JUnit 4使用手册
笔者此前使用过JUnit 3,工作关系很长时间没再碰Java了。最近重新接触了一下,发现JUnit 4和3有较大区别,特总结一下JUnit 4的基本用法,供自己查阅也供朋友们参考。
一、JUnit简介
JUnit由Kent Beck和ErichGamma开发,几乎毫无疑问是迄今所开发的最重要的第三方Java库,它也成为了Java语言事实上的标准单元测试库。正如Martin Fowler所说,“在软件开发领域,从来就没有如此少的代码起到了如此重要的作用”。JUnit引导并促进了测试先行的编程和测试驱动的开发。
JUnit 4是该库三年以来最具里程碑意义的一次发布。它的新特性主要是通过采用Java 5中的标记annotation)而不是利用子类、反射或命名机制来识别测试,从而简化测试代码。用Kent的话来说,“JUnit 4 的主题是通过进一步简化 JUnit,鼓励更多的开发人员编写更多的测试。”
二、JUnit4实践
选择一款IDE(Eclipse, NetBean, Idea等),基本上它们都全面支持JUnit了。创建工程后,为了避免代码混乱,建议为单元测试代码与被测试代码分别创建单独的目录。首先,写一个很简单的方法,判断输入的邮箱地址是否符合规范:
1 |
public static boolean checkEmail(String email) {
|
2 |
if (!email.matches( "[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+" )) {
|
OK,一切准备就绪,我们开始编写这个方法的单元测试用例。
1、测试由@Test注释开始
2 |
public void checkEmail(){
|
3 |
assertEquals( true , RegexUtil.checkEmail( "add.dd@sina.com" ));
|
以前版本的JUnit通过命名约定和反射来定位测试用例,要求测试方法以”test”开头+方法名,并且测试类需要继承TestCase。JUnit 4中简化了这个操作,只需要在测试类中引入org.junit.Test,在测试方法前使用注解@Test,JUnit就可以侦测该测试方法了,保持了代码的简洁。
注:在JUnit4中仍然可以以原来的方式进行测试(继承TestCase并在方法前加test)。但是如果这样就最好不要使用注解。因为一旦继承了TestCase,注解会失效,如果没有test前缀,会报:AssertionFailedError: No tests found…异常。
2、Fixture
它是指在执行一个或者多个测试方法时需要的一系列公共资源或者数据,例如测试环境,测试数据等。JUnit专门提供了设置公共Fixture的方法,同一测试类中的所有测试方法都可以共用它来初始化Fixture和注销Fixture。在以前的版本,JUnit使用SetUp和TearDown方法。在JUnit4中,使用注解org,junit.Before和org.junit.After。例如:
2 |
public void initialize (){……}
|
4 |
public void dispose (){……}
|
这样,在每一个测试方法执行之前,JUnit会保证注解了Before的方法提前执行。当测试方法执行完毕后,JUnit调用注解了After的方法注销测试环境。
注:@Before和@After修饰的是方法级别的。它们都可以修饰多个方法,但是方法执行的顺序不能保证。
在JUnit 4中还引入了类级别的Fixture设置方法,即使用注解 BeforeClass和AfterClass。这两种方法都使用 public static void 修饰,且不能带有任何参数。类级别的Fixture仅会在测试类中所有测试方法执行之前和之后执行。
3、异常和测试时间
JUnit 4中引入了异常的测试,以前版本中异常测试是在抛出异常的代码中放入try块,然后在try块的末尾加入fail语句。在JUnit 4中,可以使用@Test中的expected参数,它表示测试方法期望抛出的异常,如果运行测试并没有抛出这个异常,则JUnit会认为这个测试没有通过。例如:
1 |
@Test (expected= IndexOutOfBoundsException. class )
|
3 |
new ArrayList<Object>().get( 1 );
|
@Test的另一个参数timeout,用来指定被测试方法被允许运行的最长时间。如果测试方法运行时间超过了指定的毫秒数,则JUnit认为测试失败。例如:
2 |
public void checkEmail(){
|
3 |
assertEquals( true , RegexUtil.checkEmail( "add.dd@sina.com" ));
|
4、忽略测试方法
JUnit 4提供注解org.junit.Ignore用于暂时忽略某个测试方法。例如:
2 |
@Test (expected=UnsupportedDBVersionException. class )
|
3 |
public void unsupportedDBCheck(){ …… }
|
5、测试用例的执行
JUnit中所有的测试用例都是由测试运行器执行的。JUnit提供了默认的测试运行器,但并没有限制我们必须使用默认的运行器(所有的运行器都继承自Runner)。相反,我们不仅可以定制自己的运行器,而且还可以为每个测试类指定使用某个运行器(使用@RunWith)。例如JUnit的自测代码:
01 |
public class RunWithTest {
|
02 |
private static String log;
|
03 |
public static class ExampleRunner extends Runner {
|
04 |
public ExampleRunner(Class<?> klass) {
|
08 |
public void run(RunNotifier notifier) {
|
12 |
public Description getDescription() {
|
14 |
return Description.createSuiteDescription( "example" );
|
17 |
@RunWith (ExampleRunner. class )
|
18 |
public static class ExampleTest {
|
20 |
@Test public void run() {
|
22 |
JUnitCore.runClasses(ExampleTest. class );
|
23 |
assertTrue(log.contains( "plan" ));
|
24 |
assertTrue(log.contains( "initialize" ));
|
25 |
assertTrue(log.contains( "run" ));
|
显而易见,如果测试类没有显式的声明使用哪一个测试运行器,JUnit 会启动默认的测试运行器执行测试类。一般情况下,默认测试运行器可以应对绝大多数的测试要求;当使用 JUnit 提供的一些高级特性或者针对特殊需求定制 JUnit 测试方式时,显式的声明测试运行器就必不可少了。
6、测试套件Suite
正如JUnit以前版本中提供的Suite一样,JUnit4提供了一种批量运行测试类的方法,以方便我们在每次进行系统测试时,只需执行若干测试套件而不是执行无数测试用例。我们只需创建一个空类,并填写两个注解。例如:
2 |
@Suite .SuiteClasses({TestCheckEmail. class , TestTimeUtil. class })
|
3 |
public class CustomizeRunner{
|
测试套件中不仅可以包含基本的测试类,而且可以包含其它的测试套件。但是,一定要保证测试套件之间没有循环包含关系,否则将出现死循环。
7、参数化测试
当我们编写了大量的单元测试方法后,我们发现这些方法其实大同小异,只是参数不同(测试边界值或者测试异常值)。在以前的 JUnit版本上,并没有好的解决方法,而现在我们可以使用JUnit提供的参数化测试方式解决这个问题。
首先在测试类中指定参数运行期@RunWith(Parameterized.class)。例如:
01 |
@RunWith (Parameterized. class )
|
02 |
public class TestWithParam {
|
03 |
@Parameterized .Parameters
|
04 |
public static List<Object[]> data() {
|
05 |
return Arrays.asList( new Object[][]{
|
06 |
{ 0 , 0 }, { 1 , 1 }, { 2 , 1 }, { 3 , 2 }, { 4 , 3 }, { 5 , 5 }, { 6 , 8 },{ 10 , 55 }
|
10 |
private int fExpected;
|
11 |
public testWithParam( int input, int expected) {
|
17 |
assertEquals(fExpected, Fibonacci.compute(fInput));
|
19 |
private static class Fibonacci{
|
20 |
public static int compute( int input){
|
27 |
else return compute(input- 1 )+compute(input- 2 );
|
在静态方法data中,我们使用二维数组来构建测试所需要的参数列表,其中每个数组中的元素的放置顺序只要和构造函数中的顺序保持一致就可以了。
参考文献:
1.单元测试利器 JUnit 4:http://www.ibm.com/developerworks/cn/java/j-lo-junit4/
2.JUnit 4 JavaDoc
相关推荐
《ANT&JUNIT中文手册》是一份集合了Apache Ant和JUnit两种重要Java开发工具的中文教程,旨在帮助Java开发者更高效地理解和运用这两个工具。Ant是Apache软件基金会的一个项目,是一个基于Java的构建工具,而JUnit则是...
尽管JUnit5与JUnit4不完全兼容,但仍然可以使用JUnit4来运行JUnit5的测试。 **4.5 配置参数** 介绍了如何配置JUnit5的运行参数,以适应不同的测试需求。 #### 五、扩展模型 **5.1 概览** 扩展模型是JUnit5的一...
《JUnit使用简明手册》是针对Java开发人员的一份实用指南,主要涵盖了如何有效地使用JUnit进行单元测试。JUnit是一款广泛使用的开源测试框架,它简化了Java应用的单元测试过程,帮助开发者确保代码的质量和可靠性。...
本资源是JUnit 5用户手册的中文版,旨在帮助开发者快速上手使用JUnit 5来进行单元测试。以下是从该手册中提取的相关知识点: 1. 什么是JUnit 5? JUnit 5是Java中的一个单元测试框架,旨在帮助开发者编写更加可靠...
### JUnit5 用户手册知识点详解 #### 一、概述 JUnit5是一款强大的单元测试框架,相较于之前的版本进行了大幅度的重构和改进。它由三个主要部分组成:JUnit Platform、JUnit Jupiter和JUnit Vintage。这三个部分...
### JUnit与Selenium集成使用手册 #### 一、引言 随着软件开发技术的不断发展,自动化测试成为了提高软件质量的重要手段之一。JUnit 和 Selenium 是两款广泛使用的自动化测试工具,JUnit 主要用于 Java 应用程序的...
《开发者手册Junit4》是一份专为Java开发者设计的详细指南,主要涵盖了Junit4这一流行的单元测试框架的使用方法和技术。Junit是Java语言中最常用的单元测试工具,尤其在敏捷开发和持续集成环境中扮演着重要角色。这...
12. 测试分类:JUnit 4 通过 `@Category` 注解支持测试分类,这有助于根据功能或模块组织测试,然后选择性地运行某一类别的测试。 13. 快速失败:JUnit 设计的原则之一是快速反馈,当测试失败时,它会立即停止执行...
这个“Junit学习.rar”压缩包显然包含了关于JUnit从3.8到4.9版本的学习资料,包括可能的操作手册、教程文档以及个人的学习笔记。以下是基于这些资源可能涵盖的一些关键知识点: 1. **JUnit基础知识**:了解JUnit的...
本资源包含“JUnit API和入门手册”以及“JUnit In Action”电子书,将帮助你深入理解和掌握JUnit的核心概念和使用方法。 首先,`JUnit4.1.chm`文件是JUnit 4.1版本的API参考文档,通常包含了类、接口、方法等详细...
JUnit 是 Java 开发者常用的单元测试框架,尤其对于 J2EE 开发者而言,掌握 JUnit 的使用至关重要。本文将详细介绍 JUnit 的基本知识、安装、单元测试的编写与执行,以及 JUnit 的断言方法。 首先,JUnit 是一个...
随着XP软件工程技术的广泛推广,单元测试的作用在软件工程中变得越来越重要,而一个简明...在java编程语句环境里,Junit Framework是一个已经被多数java程序员采用和实证的优秀的测试框架。下面我们就来聊聊这个工具。
JUnit4.5API参考手册 JUnit4.5API参考手册