【单元测试】junit入门
参考:https://blog.csdn.net/qq_29837161/article/details/80813074
一、什么是单元测试
教程:https://www.w3cschool.cn/junit/uhyr1hvd.html
junt5文档:https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests
junt5的基础入门:https://www.cnblogs.com/natasha-yarovenko/p/5879678.html
junit5:https://blog.csdn.net/CSDN___LYY/article/details/86581212
写了个类,要给别人用,会不会有bug?测试一下。
单元测试是保障业务代码质量的非常有效工具,也是提高代码可靠性的必要手段。单元测试是编写测试代码,应该准确、快速地保证程序基本模块的正确性。
用main方法测试的问题:不能一起运行,大多数情况下需要人为的观察输出确定是否正确。
二、单元测试的部件
1、静态引入:比如import static org.junit.Assert.*; 静态引入一个类,类里面有很多静态方法,可以直接调用这个类里面的静态方法,而不用在其前面加 '类名.'
2、Assert断言
3、测试注解:@Test表示是测试方法,测试方法必须使用注解 org.junit.Test 修饰。测试方法必须使用 public void 修饰,而且不能带有任何参数。
4、异常以及时间测试
- 注解 org.junit.Test 中有两个非常有用的参数:expected 和 timeout。参数 expected 代表测试方法期望抛出指定的异常,如果运行测试并没有抛出这个异常,则JUnit 会认为这个测试没有通过。这为验证被测试方法在错误的情况下是否会抛出预定的异常提供了便利。
- 另一个参数 timeout,指定被测试方法被允许运行的最长时间应该是多少,如果测试方法运行时间超过了指定的毫秒数,则 JUnit 认为测试失败。这个参数对于性能测试有一定的帮助。
5、忽略测试方法
- 注解 org.junit.Ignore 用于暂时忽略某个测试方法,因为有时候由于测试环境受限,并不能保证每一个测试方法都能正确运行。
6、Fixture
Fixture是指在执行一个或者多个测试方法时需要的一系列公共资源或者数据,例如测试环境,测试数据等等。JUnit 专门提供了设置公共 Fixture 的方法,同一测试类中的所有测试方法都可以共用它来初始化 Fixture 和注销 Fixture。
①方法级别的Fixture:
使用注解 org,junit.Before 修饰用于初始化 Fixture 的方法。每一个测试方法之前运行
使用注解 org.junit.After 修饰用于注销 Fixture 的方法。每一个测试方法之后运行
保证这两种方法都使用 public void 修饰,而且不能带有任何参数。
②类级别的 Fixture
使用注解 org,junit.BeforeClass修饰用于初始Fixture 的方法。所有测试方法开始之前运行,它比较适合加载配置文件,进行初始化等等
使用注解 org.junit.AfterClass 修饰用于注销 Fixture 的方法。所有测试方法开始之后运行,通常用来对资源的清理,如关闭数据库的连接
保证这两种方法都使用 public static void 修饰,而且不能带有任何参数。
1.@Test: 测试方法
a)(expected=XXException.class)如果程序的异常和XXException.class一样,则测试通过
b)(timeout=100)如果程序的执行能在100毫秒之内完成,则测试通过
2.@Ignore: 被忽略的测试方法:加上之后,暂时不运行此段代码
3.@Before: 每一个测试方法之前运行
4.@After: 每一个测试方法之后运行
5.@BeforeClass: 方法必须必须要是静态方法(static 声明),所有测试开始之前运行,注意区分before,是所有测试方法
6.@AfterClass: 方法必须要是静态方法(static 声明),所有测试结束之后运行,注意区分 @After
@RunWith(JUnit4.class) public class JuntTest { public JuntTest(){ System.out.println("==构造函数=="); } @BeforeClass public static void beforeClass(){ System.out.println("===@BeforeClass=="); } @Before public void before(){ System.out.println("===@Before=="); } @After public void after(){ System.out.println("===@After=="); } @AfterClass public static void afterClass(){ System.out.println("===@AfterClass=="); } @Test public void test01(){ System.out.println("======test01======"); } @Test public void test02(){ System.out.println("======test02======"); } } //运行结果 ===@BeforeClass== ==构造函数== ===@Before== ======test01====== ===@After== ==构造函数== ===@Before== ======test02====== ===@After== ===@AfterClass==
7、测试运行器
可以定制自己的运行器(所有的运行器都继承自org.junit.runner.Runner)
使用注解 org.junit.runner.RunWith 在测试类上显式的声明要使用的运行器
8、测试套件
Unit 提供的一种批量运行测试类的方法,测试套件的写法遵循以下规则:
①创建一个空类作为测试套件的入口。
②使用注解 org.junit.runner.RunWith 和org.junit.runners.Suite.SuiteClasses 修饰这个空类。
③将 org.junit.runners.Suite 作为参数传入注解 RunWith,以提示 JUnit 为此类使用套件运行器执行。
④将需要放入此测试套件的测试类组成数组作为注解 SuiteClasses 的参数。
⑤保证这个空类使用 public 修饰,而且存在公开的不带有任何参数的构造函数。
@RunWith(Suite.class) @Suite.SuiteClasses({TaskTest1.class,TaskTest2.class,...}) public class SuiteTest { }
9、参数化测试
Junit 4 引入了一个新的功能参数化测试。参数化测试允许开发人员使用不同的值反复运行同一个测试。你将遵循 5 个步骤来创建参数化测试。
- 用 @RunWith(Parameterized.class) 来注释 test 类。
- 创建一个由 @Parameters 注释的公共的静态方法,它返回一个对象的集合(数组)来作为测试数据集合。
- 创建一个公共的构造函数,它接受和一行测试数据相等同的东西。
- 为每一列测试数据创建一个实例变量。
- 用实例变量作为测试数据的来源来创建你的测试用例。
package com.spring.sxf.study.springtradeweb; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; import java.util.Collection; import static org.junit.Assert.*; /** */ //第一步声明该类型的注解 @RunWith(Parameterized.class) public class ParamsJuntTest { private Integer inputNumber; private Boolean expectedResult; private PrimeNumberChecker primeNumberChecker; //第三步,创建构造函数,接收@Parameterized.Parameters注解返回集合中的数据 public ParamsJuntTest(Integer inputNumber, Boolean expectedResult) { this.inputNumber = inputNumber; this.expectedResult = expectedResult; } //第四步,在每次单侧前对测试目标类进行初始化(为每一列测试数据创建一个实例变量。) @Before public void initialize() { primeNumberChecker = new PrimeNumberChecker(); } @Test public void testPrimeNumberChecker() { System.out.println("Parameterized Number is : " + inputNumber); assertEquals(expectedResult, primeNumberChecker.validate(inputNumber)); } //第二步声明该注解注释的静态方法,返回一个测试数据的集合 //该集合中的数据会被当做构造函数的入参,传入到单测类的构建函数中。 @Parameterized.Parameters public static Collection primeNumbers() { return Arrays.asList(new Object[][] { { 2, true }, { 6, false }, { 19, true }, { 22, false }, { 23, true } }); } }