JUnit 是Java语言标准单元测试库。JUnit4 放弃了过去严格的命名规范、继承层次,转而采用了Java 5 的Annotation机制,从而简化测试。本文详细介绍了JUnit4 的基本用法,后续还会针对Matcher、Rule、Theories等主题进行一系列学习总结。
什么是JUnit?
JUnit 由XP(极限编程)和TDD(测试驱动开发)的创始人、软件大师Kent Back以及Eclipse架构师之一、设计模式之父Erich Gamma共同打造。正如『教父』- Martin Fowler 所说,“在软件开发领域,从来没有如此少的代码起到了如此重要的作用”。由于 JUnit,Java 代码变得更健壮,更可靠,bug 也比以前更少。JUnit(它本身的灵感来自 Smalltalk 的 SUnit)衍生了许多 xUnit 工具,将单元测试的优势应用于各种语言。nUnit (.NET)、pyUnit (Python)、CppUnit (C++)、dUnit (Delphi) 以及其他工具,影响了各种平台和语言上的程序员的测试工作。
什么是Annotation
Annotation是Java 5 引入的新特性,它为程序元素(类、变量、方法)添加一个说明,这些说明可看做『元数据』,与业务逻辑无关,仅提供给框架分析使用。利用这些『元数据』,框架决定如何使用这些程序元素或改变他们的行为。
JUnit4 新框架的特点是什么
JUnit4相比之前版本更轻量,更优雅。它放弃了严格的继承层次、命名规范,选择了灵活的Java5 Annotation。用 Beck 的话来说,"JUnit 4 的主题是通过进一步简化 JUnit,鼓励更多的开发人员编写更多的测试。"
JUnit4 基本用法
1、测试方法
测试方法必须使用public void修饰
测试方法不能有参数列表
测试方法使用@Test修饰
例如:
import org.junit.Assert;
public class AddTest {
private int x = 1;
private int y = 1;
@Test
public void add() {
int result = x + y;
Assert.assertEquals(2, result);
}
}
2、测试固件
固件通过一个契约来倡导重用,该契约确保特殊逻辑(初始化数据库、网络连接、消除资源等)在测试之前或之后运行。
针对每个测试运行一次固件: @Before @After
为整个类运行一次固件: @BeforeClass @AfterClass 。它有可能会违反测试的独立性,并引入非预期的混乱。如果一个测试在某种程度上改变了@BeforeClass所初始化的一个对象,那么会引入顺序依赖,有可能会影响其他测试结果,隐藏 bug。
3、测试套件
套件用于将测试用例从逻辑上进行分组。在JUnit4中使用两个新注释表达套件的语义。
@RunWith:使用它是为了让不同的运行器执行特别的测试类。为了运行测试套件,JUnit4绑定了叫做Suite的套件运行器,必须在@RunWith中指定该运行器-@RunWith(Suite.class)
@SuiteClasses:该注释需传入表示测试套件类的列表参数
4、异常测试
旧的JUnit异常测试是首先将待测函数放在try块,然后在try的末尾加入fail语句,后在catch模块中捕捉该异常。JUnit4是通过编写抛出异常的代码,并使用注释(@Test声明expected参数)来声明该异常是预期的,如果该异常没有抛出,则该测试将失败。
@Test(expected=exceptionName.class)
@Test(expected=ArithmeticException.class)
public void divideByZero(){
int result=5/0
}
5、性能-时间测试
性能测试一直都是单元测试的痛点之一,JUnit4没有完全解决该问题,但是它对性能测试-时间这个问题有所帮助。测试可以用一个超时参数来注释,如果测试时间超过该超时参数,则测试失败。
@Test(time=number),其中number是以ms为单位
@Test(time=100)
public void getContentsFromNet(){
net.query("abc");
}
6、忽略测试
某些测试用例因为所做的工作比较复杂或者缓慢,例如访问远程网络,因此这些用例运行时间会比较长;又或者某些测试用例因其他原因导致失败,暂时无法运行。那么这类测试都可以先暂时忽略,等后续再做这类测试。
@Ignore注释测试方法,则测试运行器不会运行该测试方法,在测试结果中会显示本次运行测试pass数、fail数、ignore数。
7、测试运行器
JUnit中所有测试方法都是由它均是由测试运行器负责执行,JUnit为单元测试提供了默认的运行器,但是并未限制只能使用默认运行器,也可以通过继承org.junit.runner.Runner来定制自己的运行器。因此可以为每个测试类指定使用某个特定的测试运行器,指定方法是通过@Runner中显示指名特定测试运行器。例如测试套件使用@RunWith(Suite.class)。