junit4 学习
junit4 是什么
JUnit4是一个编写可重复测试的简单框架。它是单元测试框架的xUnit体系结构的一个实例。
Xunit是基于测试开发驱动的框架
junit3 和 junit4 的区别:
- junit3 每一个测试方法前面,都必须加上 test,并且都会继承 junit.framework.TestCase 这个类,而 junit4 只需要添加 @Test 注解即可,方法命名没有限制
断言机制:将程序预期的结果与程序运行的最终结果进行比对,确保对结果的可预知性。
编写测试类和测试方法的规范
- 测试方法必须使用 @Test 进行修饰
- 测试方法必须使用 public void 进行修饰,不能带任何的参数
- 新建一个源代码目录来存放我们的测试代码
- 测试类的包名应该和被测试类保持一致
- 测试单元的每个方法必须可以独立测试,测试方法间不能有任何的依赖
- 测试类使用 Test 作为类名的后缀(不是必须)
- 测试方法使用 test 作为方法名的前缀(不是必须)
junit4 测试失败的两种情况
- Failure 一般由单元测试使用的断言方法判断失败所引起的,表示测试点发现了问题,就是说程序输出的结果和预期值不一样
- Error 是由代码异常引起的,它可以产生于测试代码本身的错误,也可以是被测试代码中的一个隐藏的 bug
- 测试用例不是用来证明你是对的,而是用来证明你没有错
junit4 的运行流程
- @BeforeClass 修饰的方法会在所有方法被调用前被执行,
而且该方法是静态的,所以当测试类被加载后接着就会运行它,
而且内存中它只会存在一份实例,它比较适合加载配置文件. - @AfterClass 所修饰的方法通常用来对资源的清理,如关闭数据库的连接.
- @Before 和 @After 会在每个测试方法的前后各执行一次.
junit4 的常用注解
- @BeforeClass 它会在所有的方法运行前被执行,static 修饰
- @AfterClass 它会在所有的方法运行结束后被执行,static 修饰
- Before 会在每一个测试方法运行前执行一次
- After 会在每一个测试方法运行后执行一次
- Ignore 所修饰的方法会被测试运行器忽略,也就是该方法不会被执行,可以后面填写忽略信息
- RunWith 可以更改测试运行器,也可以定制自己的运行器,只要继承 org.junit.runner.Runner 类
- Test 将一个普通的方法修饰为一个测试方法
- Test 可以有两个属性,expected timeout
- expected 异常捕获,例
@Test(expected = ArithmeticException.class) public void test() { Assert.assertEquals(2, new Calculate().divide(4, 0)); }
- timeout 限制该方法运行的时间,避免程序出现死循环,如果程序运行时长超过 timeout 限定的时长,会报 TestTimedOutException 错误
@Test(timeout = 2000) public void whileTest() { while (true) { System.out.println("run always"); } }
junit4 中的测试套件
测试套件就是组织测试类一起运行的
- 写一个测试套件的入口类,这个类里面不包含其他的方法
- 更改测试运行器为 Suit.class
- 将要测试的类作为数组传入到 Suite.SuiteClasses({TaskTest1.class, TaskTest2.class, TaskTest3.class})
代码示例
-
创建三个测试类
TaskTest1.class
import org.junit.Test;
public class TaskTest1 {
@Test
public void test() {
System.out.println("TaskTest1.test");
}
}
-
第二个测试类
TaskTest2.class
import org.junit.Test;
public class TaskTest2 {
@Test
public void test() {
System.out.println("TaskTest2.test");
}
}
-
第三个测试类
TaskTest3.class
import org.junit.Test;
public class TaskTest2 {
@Test
public void test() {
System.out.println("TaskTest2.test");
}
}
-
测试套件的入口类
SuiteTest.class
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({TaskTest1.class, TaskTest2.class, TaskTest3.class})
public class SuiteTest {
}
junit4 的参数化设置
- 更改默认的测试运行器为 RunWith(Parameterized.class)
- 声明变量来存放预期值和结果值
- 声明一个返回值为 Collection 的公共静态方法,并使用 @Parameters 进行修饰
- 为测试类声明一个带有参数的公共构造函数,并在其中为声明的变量赋值
代码示例
-
参数化测试类
ParameterTest.classimport org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; import java.util.Collection; @RunWith(Parameterized.class) public class ParametersTest { int expected = 0; int input1 = 0; int input2 = 0; @Parameterized.Parameters public static Collection<Object[]> parametersTest() { return Arrays.asList(new Object[][]{ {3, 1, 2}, {2, 1, 1} }); } public ParametersTest(int expected, int input1, int input2) { this.expected = expected; this.input1 = input1; this.input2 = input2; } @Test public void test() { Assert.assertEquals(expected, new Calculate().add(input1, input2)); } }
-
被测试类
Calculate.classpublic class Calculate { public int add(int a, int b) { return a + b; } }