1、Junit 是什么?
JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。
注意:Junit 测试也是程序员测试,即所谓的白盒测试,它需要程序员知道被测试的代码如何完成功能,以及完成什么样的功能
2、Junit 能做什么?
我们知道 Junit 是一个单元测试框架,那么使用 Junit 能让我们快速的完成单元测试。
通常我们写完代码想要测试这段代码的正确性,那么必须新建一个类,然后创建一个 main() 方法,然后编写测试代码。如果需要测试的代码很多呢?那么要么就会建很多main() 方法来测试,要么将其全部写在一个 main() 方法里面。这也会大大的增加测试的复杂度,降低程序员的测试积极性。而 Junit 能很好的解决这个问题,简化单元测试,写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。
3、Junit 的用法
首先介绍 Junit 的几种类似于 @Test 的注解:
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
junit before,beforeClass,after, afterClass的执行顺序
JUnit4使用Java5中的注解(annotation),以下是JUnit4常用的几个annotation:
- @Before:初始化方法 对于每一个测试方法都要执行一次(注意与BeforeClass区别,后者是对于所有方法执行一次)
- @After:释放资源 对于每一个测试方法都要执行一次(注意与AfterClass区别,后者是对于所有方法执行一次)
- @Test:测试方法,在这里可以测试期望异常和超时时间
- @Test(expected=ArithmeticException.class)检查被测方法是否抛出ArithmeticException异常
- @Ignore:忽略的测试方法
- @BeforeClass:针对所有测试,只执行一次,且必须为static void
- @AfterClass:针对所有测试,只执行一次,且必须为static void
- 一个JUnit4的单元测试用例执行顺序为:
- @BeforeClass -> @Before -> @Test -> @After -> @AfterClass;
- 每一个测试方法的调用顺序为:
- @Before -> @Test -> @After;
那么上面的例子,我们可以看到,每个 @Test 方法中都有 Calculator c = new Calculator();即类的实例化,那么我们可以将其放入到 @Before 中
|
同理:别的注解用法我们用一个类来看:
|
结果为:
|
注意:编写测试类的原则:
①测试方法上必须使用@Test进行修饰
②测试方法必须使用public void 进行修饰,不能带任何的参数
③新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开
④测试类所在的包名应该和被测试类所在的包名保持一致
⑤测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖
⑥测试类使用Test作为类名的后缀(不是必须)
⑦测试方法使用test作为方法名的前缀(不是必须)
Junit单元测试执行的顺序
- 在写JUnit测试用例时,有时候需要按照定义顺序执行我们的单元测试方法.
- 比如如在测试数据库相关的用例时候要按照测试插入、查询、删除的顺序测试。
- 如果不按照这个顺序测试可能会出现问题,比如删除方法在前面执行,后面的方法就都不能通过测试.
- 因为数据已经被清空了。而JUnit测试默认的顺序是随机的。所以这时就需要有办法要求JUnit在执行测试方法时按照我们指定的顺序来执行。
- 按照设计原则,JUnit是不指定测试方法调用执行顺序的。
- 目前为止,这些方法只是简单地按照反射(reflection) API返回的顺序执行。
- 但是,使用JVM默认提供的排序是很不明智的,因为Java平台没有指定任何有规律的顺序,
- 而事实上JDK 7可能会返回一个随机的顺序。
- 当然,精心编写的测试代码之间并不需要假定任何执行顺序,但有时候,但在某些平台上一个可预测的失败总比随机的失败要好。
- 本例通过Junit的@FixMethodOrder注解来设定单元测试中方法的执行顺序
- 可以看到,DefaultOrderTest 和 NotSettingOrderTest 执行结果是一样的
- JVMOrderTest每次返回不同的结果
- NameAscOrderTest返回的是按照方法名称的字典序执行的结果
不指定顺序 : 从4.11版本开始,JUnit将默认使用一个确定的,但不可预测的顺序。执行顺序同DefaultOrderTest
public class NotSettingOrderTest {
@Test
public void one() {
System.out.println("1");
}
@Test
public void two() {
System.out.println("2");
}
@Test
public void three() {
System.out.println("3");
}
@Test
public void four() {
System.out.println("4");
}
/**
* 无论执行多少次,结果始终为:
1
2
4
3
*/
}
MethodSorters.DEFAULT : 默认的顺序执行 执行顺序同NotSettingOrderTest@FixMethodOrder(MethodSorters.DEFAULT)
public class DefaultOrderTest {
@Test
public void one() {
System.out.println("1");
}
@Test
public void two() {
System.out.println("2");
}
@Test
public void three() {
System.out.println("3");
}
@Test
public void four() {
System.out.println("4");
}
/**
* 每次执行结果都是:
1
2
4
3
*/
}
MethodSorters.JVM : 保留测试方法的执行顺序为JVM返回的顺序。每次测试的执行顺序有可能会所不同。
@FixMethodOrder(MethodSorters.JVM)
public class JVMOrderTest {
@Test
public void one() {
System.out.println("1");
}
@Test
public void two() {
System.out.println("2");
}
@Test
public void three() {
System.out.println("3");
}
@Test
public void four() {
System.out.println("4");
}
/**
* 每次执行结果都有可能不一样
*/
}
MethodSorters.NAME_ASCENDING : 按照方法名的字典顺序升序执行
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class NameAscOrderTest {
@Test
public void one() {
System.out.println("1");
}
@Test
public void two() {
System.out.println("2");
}
@Test
public void three() {
System.out.println("3");
}
@Test
public void four() {
System.out.println("4");
}
/**
* 无论执行多少次,都是按照方法名字的字典序执行:
4
1
3
2
*/
}