Junit单元测试的步骤

(1)新建一个单元测试

(2)选择位置

(3)选择需要测试的方法

(4)是否将Junit 4添加到ClassPath中

(5)自动生成的测试类

(6) 然后就可以编写单元测试了

单元测试的编写

(1)Assert断言

package cn.hanquan.junit;import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;class CalcTest {@Testvoid testAdd() {assertEquals(3, new Calc().add(1, 2));assertEquals(30, new Calc().add(10, 20));assertEquals(159, new Calc().add(150, 9));}
}

(2)Junit Fixture:Junit4 @Before@After的使用

初始化测试资源称为Fixture

@Before:创建初始化对象,在执行所有每一个@Test之前都会执行一次。如is = new FileInputStream()
@After:销毁@Before创建的测试对象,在执行所有每一个@Test之后都会执行一次。如is.close()
@BeforeClass:在其中初始化非常耗时的对象,如:数据库的连接
@AfterClass:清理@BeforeClass创建的资源,比如:断开数据库连接

注意:在JUnit5中,@Before @After 注解不执行

官方文档:https://junit.org/junit5/docs/current/user-guide/#migrating-from-junit4-tips


@Before@After@BeforeEach@AfterEach给替代了。

还有一些其他的的注解也被替代了。

在JUnit5的环境下写了@Before @After , 讲道理 IDE应该提醒 该注解已经不存在, 然而Eclipse并没有这样的提示。


代码示例

被测试的类Calc.java

package cn.hanquan.junit;public class Calc {public Calc() {}public int add(int a, int b) {System.out.println(a + "+" + b + "=" + (a + b));return a + b;}
}

测试类CalcTest

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import org.junit.After;
import org.junit.Before;
import org.junit.Test;public class CalcTest {Calc c;@Beforepublic void initialize() {System.out.println(">>>>>>> initializing >>>>>>>");c = new Calc();}@Testpublic void testAdd1() {assertEquals(3, c.add(1, 2));assertEquals(30, c.add(10, 20));assertEquals(159, c.add(150, 9));}@Testpublic void testAdd2() {assertEquals(4, c.add(2, 2));assertEquals(36, c.add(13, 23));assertEquals(1000, c.add(-3000, 4000));}@Afterpublic void destroy() {System.out.println("<<<<<<<<< cleaning <<<<<<<<<\n");}
}

测试结果

输出

>>>>>>> initializing >>>>>>>
1+2=3
10+20=30
150+9=159
<<<<<<<<< cleaning <<<<<<<<<>>>>>>> initializing >>>>>>>
2+2=4
13+23=36
-3000+4000=1000
<<<<<<<<< cleaning <<<<<<<<<

(3)测试抛出的异常是否符合预期

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import org.junit.After;
import org.junit.Before;
import org.junit.Test;public class CalcTest {Calc c;@Beforepublic void initialize() {System.out.println(">>>>>>> initializing >>>>>>>");c = new Calc();}@Test // 测试输出是否符合预期public void testAdd2() {assertEquals(20, c.divide(100, 5));}@Test(expected = ArithmeticException.class) // 针对异常进行的测试public void testAdd3() {c.divide(8, 0);}@Afterpublic void destroy() {System.out.println("<<<<<<<<< cleaning <<<<<<<<<\n");}
}

(4)参数化测试:一次运行多个测试

JUnit参数化测试的五个步骤:

(1)为准备使用参数化测试的测试类指定特殊的运行器 org.junit.runners.Parameterized

(2)为测试类声明几个变量,分别用于存放期望值和测试所用数据

(3)为测试类声明一个带有参数的公共构造函数,并在其中为第二个环节中声明的几个变量赋值

(4)为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的,返回值为 java.util.Collection 的公共静态方法,并在此方法中初始化所有需要测试的参数对

(5)编写测试方法,使用定义的变量作为参数进行测试。

示例代码

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import java.util.Arrays;
import java.util.Collection;import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;/*** 使用Junit进行参数化测试的步骤* * @author Buuug**/
//(1)测试类指定特殊的运行器org.junit.runners.Parameterized
@RunWith(Parameterized.class)
public class CalcTest {Calc c;@Beforepublic void bef() {System.out.println("Before");c = new Calc();}// (2)为测试类声明几个变量,分别用于存放期望值和测试所用数据。此处我只放了测试所有数据,没放期望值。private int n1;private int n2;private int result;// (3)为测试类声明一个带有参数的公共构造函数,并在其中为第二个环节中声明的几个变量赋值。public CalcTest(int n1, int n2, int result) {super();this.n1 = n1;this.n2 = n2;this.result = result;}// (4)为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的,返回值为// java.util.Collection 的公共静态方法,并在此方法中初始化所有需要测试的参数对。@Parameterspublic static Collection<Object[]> data() {return Arrays.asList(new Object[][] { { 4, 2, 2 }, { 9, 3, 3 }, { -100, 25, -4 }, { 88, 2, 44 }, { 25, 5, 5 },{ 72, 8, 9 }, { 42, 6, 7 }, { 1, 1, 1 }, { 1000000, 333333, 888888 }, { 56, 8, 7 }, { 55, 55, 1 },{ 12, 6, 2 }, { 21, 10, 2 }, { 70, 20, 3 }, { 45, 15, 3 }, { 46, 15, 3 }, { 47, 3, 15 }, { 2, 1, 2 } });}// (5)步骤五:编写测试方法,使用定义的变量作为参数进行测试。@Testpublic void testAdd() {assertEquals(result, c.divide(n1, n2));}@Afterpublic void aft() {System.out.println("After\n");}
}

测试结果

第8个未通过,是故意写错的。

(5)超时测试:设定运行时间限制,测试是否运行时间过长

50行加一个@Test(timeout = 1)就行了。

一开始想通过Thread.sleep(1000);这种形式拖延时间,但是抛出了ThreadInterrupted异常,(没有具体去了解原因),然后我又在@Test的方法里加了一个Lambda表达式开启的多线程,结果开启之后,不管sleep多长也没有影响了,都可以在限定时间内结束,我寻思着是不是要join一下才可以。(后来加了Join,确实如此。)

我在被测试的类上面加了一些无用的循环拖延时间,然后把时间限定设置为1ms。看看效果吧:

示例代码1:没有使用多线程,只是加了没用的循环拖延时间

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import java.util.Arrays;
import java.util.Collection;import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;/*** 使用Junit进行参数化测试的步骤* * @author Buuug**/
@RunWith(Parameterized.class)
public class CalcTest {Calc c;@Beforepublic void bef() {System.out.println("Before");c = new Calc();}private int n1;private int n2;private int result;public CalcTest(int n1, int n2, int result) {super();this.n1 = n1;this.n2 = n2;this.result = result;}@Parameterspublic static Collection<Object[]> data() {return Arrays.asList(new Object[][] { { 4, 2, 2 }, { 9, 3, 3 }, { -100, 25, -4 }, { 88, 2, 44 }, { 25, 5, 5 },{ 72, 8, 9 }, { 42, 6, 7 }, { 1, 1, 1 }, { 1000000, 333333, 888888 }, { 56, 8, 7 }, { 55, 55, 1 },{ 12, 6, 2 }, { 21, 10, 2 }, { 70, 20, 3 }, { 45, 15, 3 }, { 46, 15, 3 }, { 47, 3, 15 }, { 2, 1, 2 } });}@Test(timeout = 1) // 设置超时时间public void testAdd() {assertEquals(result, c.divide(n1, n2));}@Afterpublic void aft() {System.out.println("After\n");}
}

测试结果

示例代码2:使用多线程sleep模拟运行耗时,记得join一下主线程,否则都来不及计算就完成了

  • CalcTest.java单元测试:时间限制为501ms。
package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import java.util.Arrays;
import java.util.Collection;import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;/*** 使用Junit进行参数化测试的步骤* * @author Buuug**/
@RunWith(Parameterized.class)
public class CalcTest {Calc c;@Beforepublic void bef() {System.out.println("Before");c = new Calc();}private int n1;private int n2;private int result;public CalcTest(int n1, int n2, int result) {super();this.n1 = n1;this.n2 = n2;this.result = result;}@Parameterspublic static Collection<Object[]> data() {return Arrays.asList(new Object[][] { { 4, 2, 2 }, { 9, 3, 3 }, { -100, 25, -4 }, { 88, 2, 44 }, { 25, 5, 5 },{ 72, 8, 9 }, { 42, 6, 7 }, { 1, 1, 1 }, { 56, 8, 7 }, { 55, 55, 1 }, { 12, 6, 2 }, { 21, 10, 2 },{ 70, 20, 3 }, { 45, 15, 3 }, { 46, 15, 3 }, { 47, 3, 15 }, { 2, 1, 2 } });}@Test(timeout = 1000) // 设置超时时间public void testAdd() {Thread t = new Thread(() -> { // ()表示的是函数的参数,这里无参assertEquals(result, c.divide(n1, n2));});t.start();try {t.join();// join} catch (InterruptedException e) {e.printStackTrace();}}@Afterpublic void aft() {System.out.println("After\n");}
}
  • 被测试的类:Calc,里面Thread.sleep(500);。由于时间限制为501ms,因此仅空余出1ms给它做计算。
package cn.hanquan.junit;public class Calc {public Calc() {}public int divide(int a, int b) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(a + "/" + b + "=" + (a / b));return a / b;}
}

运行结果:部分未通过

那个抛出java.lang.InterruptedException异常的,是因为没有在限制时间内运行完毕,被打断了吧?(待解决,暂时没有深入研究)

【Java单元测试】如何进行单元测试、异常测试、参数化测试、超时测试、测试多线程相关推荐

  1. java单元测试测试异常_Java单元测试中出现意外异常

    我真的是JUnit的新手和一般的单元测试,我很难找到合适的方法.处理意外异常的更好方法是什么?为什么? 方法A: 首先捕获预期的,通过消息测试失败 在最后一个catch块中,捕获一般异常并使测试失败并 ...

  2. java 单元测试用例_Java 单元测试及JUnit的使用

    Java 单元测试: 单元测试是开发者编写的一小段代码,用于检测被测代码的一个很小的.很明确的功能是否正确. 单元测试的方法: 人工静态分析:人工阅读检测代码 自动静态分析:使用代码复查工具检查 自动 ...

  3. Spock in Java 慢慢爱上写单元测试

    前言 最近小组里面引进了Spock这个测试框架,本人在实际使用了之后,体验非常不错,本篇文章一是为了巩固输入的知识,二是为了向大家推广一下. 在了解学习Spock测试框架之前,我们应该先关注单元测试本 ...

  4. Java单元测试实践-01.单元测试概述与示例

    Java单元测试实践-00.目录(9万多字文档+700多测试示例) https://blog.csdn.net/a82514921/article/details/107969340 1. 前言 以下 ...

  5. Uber:Java中的不稳定单元测试处理

    Flaky Tests介绍 单元测试是任何持续集成(CI)系统的基石.在合并之前,它向软件工程师警告新实施的代码的错误和现有代码的回归.这在软件开发生命周期的早期就能发现bug,从而确保提高软件的可靠 ...

  6. Java开发手册之单元测试,还没搞懂JVM

    正例:为了不受外界环境影响,要求设计代码时就把SUT的依赖改成注入,在测试时用spring 这样的DI框架注入一个本地(内存)实现或者Mock实现. [强制]对于单元测试,要保证测试粒度足够小,有助于 ...

  7. java day25【Junit单元测试 、反射 、 注解】

    第一章  Junit单元测试: * 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具体的执行流程. * Junit使用:白盒测 ...

  8. Android ui 单元测试 覆盖率,Android单元测试/Ui测试+JaCoCo覆盖率统计

    Android单元测试/Ui测试+JaCoCo覆盖率统计 参考资料1 参考资料2 背景说明 单元测试 从源代码着手,对源码中的最小可测试单元进行检查和验证,在对源代码有较深的理解下,编写测试单元,工作 ...

  9. 阿里巴巴java开发编码规范——单元测试

    目录 强制 推荐 参考 强制 1.好的单元测试必须遵守AIR原则.A:Automatic(自动化),I:Independent(独立性),R:Repeatable(可重复) 2.单元测试应该是全自动执 ...

  10. Python单元测试介绍及单元测试理解,单元测试的自动生成(对函数进行测试)

    目录 一.单元测试的定义 二.实例理解 2.1可通过的测试 一个模拟的登录 测试用例 测试代码 运行结果 2.2不可通过的测试 一个模拟的登录 测试用例 测试代码 运行结果 三.单元测试的自动生成 h ...

最新文章

  1. 网速不给力,我们自己给——MinGW的手动安装与配置
  2. 设计模式 — 结构型模式 — 桥接模式
  3. C# WebService发布与调用方法(转)
  4. 【HeadFirst 设计模式学习笔记】13 MVC分析
  5. mysql eval,mysql中是否有类似于eval的写法的,答案在这里
  6. php添加上传附件,phpweb招聘模块job上传简历附件的修改办法
  7. 数据结构——排序算法
  8. 6. OD-去除收费软件次数限制,去除退出软件时弹出的广告(比如可执行5次)
  9. 使用React的static方法实现同构以及同构的常见问题
  10. 选项类 oracle ebs,Oracle EBS 打3类补丁主要步骤
  11. [LibTorch] 参数注册 模块注册
  12. 用计算机代码怎么表白,IT男专用表白程序
  13. JS跨域请求解决方案
  14. python统计套利_【独家发布】期货市场内外盘低频统计套利基于Python
  15. 收藏级干货——Auto CAD历史版本功能大盘点(下)
  16. 爬虫结合批量下载评书、有声书、戏曲等的使用教程
  17. ps 画中间透明的边框图形
  18. 【Maven】高级应用:私服(nexus)搭建及使用、自定义项目骨架(archtype)
  19. 电影《大长今》励志启示
  20. 移动端 --- 区分苹果终端和安卓终端

热门文章

  1. python居中填充_Python代码中 如何将字符串填充为指定长度并保持原字符串居中呢?...
  2. OpenCV源码安装教程(兼容CUDA)
  3. VS2019-写opengl时Bugs合集(持续更新)
  4. EOJ_1102_任务调度问题
  5. android qq 登陆 简书,使用QQ第三方登录
  6. SpringMVC学习日记 1.Spring框架
  7. 逆向工程核心原理学习笔记(五):实战“打补丁方法”修改字符串
  8. cocos2d-x游戏实例(4)-地图碰撞
  9. 你已经用上 5G 网络了吗?
  10. 面试官:你对MySQL高性能优化有什么规范建议?