本篇博文介绍JUnit基础知识和使用。通过本篇博文的学习,结合例子,大家会对异常、超时、参数化等场景中使用JUnit有一个更好的理解。接下来就让我们进入JUnit的知识世界中去。
JUnit介绍
JUnit是什么
JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。Junit测试是程序员测试,即白盒测试。
该项目主页:http://www.junit.org/
JUnit能干什么
JUnit是一种测试代码的框架,测试的目的是:保证代码按照正确的行为,而不是保证代码无Bug。咱们可以使用JUnit完成单元测试,可以验证程序是否按照期望的行为在执行。
JUnit可以测试较多的场景,比如,本文会对超时、异常、参数化、规则等方面进行举例。
JUnit执行步骤和结果查看
Junit的测试采用三个步骤实现:
1. Arrange (准备) --> 2. Act(执行) --> 3. Assert (断言)
- 如果执行结果是绿色的,那么表明测试通过。
- 如果执行结果是红色的,表明测试不通过。
详细如下图所示:
Eclipse中搭建JUnit环境
在Eclipse中搭建JUnit环境可以采用如下两种方式:
- 1. 非Maven工程
- 2. Maven工程
详细如下图所示:
断言的几个核心方法
Assert.assertXXX方法
在Eclipse IDE中,输入Assert类名,然后输入点号和assert方法,将会给出很多assert方法的提示,主要有assertEquals, assertTrue, assertFalse, assertNul等方法。
assertXXX方法和作用如下图所示:
下面,就让我们一起来尝试一下Assert.assertXXX相关方法的使用。
Assert.assertTrue、assertFalse
Assert.assertEquals、assertNotEquals
Assert.assertSame、assertNotSame
Assert.assertNull、assertNotNull
Assert.assertThat()与Hamcrest
上面给出的关于assertEquals, assertTrue, assertFalse, assertNul等方法, 相对比较简单。JUnit的assertThat可以提供更加丰富的验证。下面列举出Assert的assertThat方法和Hamcrest结合使用的例子。
Hamcrest是一个书写匹配器对象时允许直接定义匹配规则的框架.有大量的匹配器是侵入式的,例如UI验证或者数据过滤。
使用Hamcrest可以让验证变得更加清晰、帮助人们更加容易地理解验证的含义。
下面给出assertThat结合Hamcrest的例子:
一般匹配
数值匹配
字符串匹配
集合类匹配
JUnit注解
JUnit常用注解
JUnit的生命周期
@Before @After与 @BeforeClass @AfterClass的区别
适合场景
@BeforeClass和@AfterClass对于那些比较“昂贵”的资源的分配或者释放来说是很有效的,因为它们只会在类中执行一次。
相比之下,对于那些需要在每次运行之前都要初始化或者在运行之后都需要被清理的资源来说,使用@Before和@After同样是一个比较明智的选择。
执行顺序
有时候,我们需要保证执行顺序。在这种情况下,JUnit提供了3种方式用于方法执行顺序。
- 1. 使用NAME_ASCENDING;
- 2. 使用JVM
- 3. 使用DEFAULT的执行顺序。
详细如下图所示:
异常测试
单元测试,对异常的测试不容忽视。
JUnit 4支持3种异常测试的方式,分别是:
- 使用@Test的expected属性
- 使用try/catch和fail
- 使用ExpectedException规则
详细如下图所示:
超时测试
有时候,一个方法的执行需要在一定的时间内完成,比如读取一个文件,希望在3秒钟内完成。
针对这样的场景,JUnit 4提供了2种方式来测试超时的场景:
- 一个是使用@Test属性timeout
- 一个是使用Timeout规则
如果方法执行的时间超过了指定的值,测试方法将抛出异常,测试结果为失败。其中执行的超时参数是以毫秒记的。
详细如下图所示:
参数化
有时候,某个方法的测试用例相对较多,如果一个一个验证,那么assertXXX方法需要执行多次,每次对一个用例进行验证。
那么,问题来了,有没有可能采用某种方式,一次性地对对所有的用例集合进行验证呢?
答案是肯定,JUnit参数化便可以完成该需求。
参数化的例子,使用参数化完成测试验证的详细内容如下图所示:
规则
上面的内容,我们已经使用过JUnit的规则,比如:超时规则、异常规则等。
我们可以实现MthodRule接口,并重写apply方法来编写自定义的规则。