原文出处: 付学良的网志

原文出处2: http://www.importnew.com/16270.html

————————————————————————————————————————————

Junit 4 和 TestNG 都是 Java 方面非常流行的单元测试框架。在功能上两个框架都非常类似。到底哪个比较好?在Java项目中我们应该选择哪个框架?

下图将会对Junit 4 和 TestNG 做个功能特征的对比。

注解支持

Junit 4 和 TestNG 在注解方面的实现非常相似。

特性

JUnit 4

TestNG

测试注解

@Test

@Test

测试套件在执行之前需要执行的

@BeforeSuite

测试套件在执行之后需要执行的

@AfterSuite

在测试之前需要执行的

@BeforeTest

在测试之后需要执行的

@AfterTest

在一个测试方法所属于的任意一个组的第一个方法被调用之前执行

@BeforeGroups

在一个测试方法所属于的任意一个组的最后一个方法被调用之后执行

@AfterGroups

在当前类的第一个测试方法调用之前执行

@BeforeClass

@BeforeClass

在当前类的最后一个测试方法调用之后执行

@AfterClass

@AfterClass

每个测试方法之前需要执行

@Before

@BeforeMethod

每个测试方法之后需要执行

@After

@AfterMethod

忽略

@ignore

@Test(enbale=false)

预期异常

@Test(expected = ArithmeticException.class)

@Test(expectedExceptions = ArithmeticException.class)

超时

@Test(timeout = 1000)

@Test(timeout = 1000)

JUnit 4 和 TestNG 之间注解方面的区别主要有以下几点:

1. 在Junit 4 中,如果我们需要在方法前面使用@BeforeClass和@AfterClass,那么该测试方法则必须是静态方法。TestNG 在方法定义部分则更加的灵活,它不需要类似的约束。

2. 3个附加的setUp/tearDown级别:套件和分组(@Before/AfterSuite, @Before/AfterTest, @Before/AfterGroup)。想了解详细的请看这里

JUnit 4

1

2

3

4

5

@BeforeClass

public static void oneTimeSetUp() {

// one-time initialization code

System.out.println("@BeforeClass - oneTimeSetUp");

}

TestNG

1

2

3

4

5

@BeforeClass

public void oneTimeSetUp() {

// one-time initialization code

System.out.println("@BeforeClass - oneTimeSetUp");

}

在Junit 4中,注解的命名是比较令人困惑的,例如 Before, After and Expected,我们不是很确切的能理解在方法前面有Before和After这样的注解是做什么的,同样Expected也如此。TestNG在这方面做的就好很多,注解使用了BeforeMethod,AfterMethod和ExpectedException,这样的名字就非常好理解了。

异常测试

异常测试的意思是在单元测试中应该抛出什么异常是合理的,这个特性在两个框架都已经实现。

JUnit 4

1

2

3

4

@Test(expected = ArithmeticException.class)

public void divisionWithException() {

int i = 1/0;

}

TestNG

1

2

3

4

@Test(expectedExceptions = ArithmeticException.class)

public void divisionWithException() {

int i = 1/0;

}

忽略测试

忽略测试意思是在单元测试哪些是可以被忽略的,这个特性在两个框架都已经实现。

JUnit 4

1

2

3

4

5

@Ignore("Not Ready to Run")

@Test

public void divisionWithException() {

System.out.println("Method is not ready yet");

}

TestNG

1

2

3

4

@Test(enabled=false)

public void divisionWithException() {

System.out.println("Method is not ready yet");

}

时间测试

时间测试意思是如果一个单元测试运行的时间超过了一个指定的毫秒数,那么测试将终止并且标记为失败的测试,这个特性在两个框架都已经实现。

JUnit 4

1

2

3

4

@Test(timeout = 1000)

public void infinity() {

while (true);

}

TestNG

1

2

3

4

@Test(timeOut = 1000)

public void infinity() {

while (true);

}

套件测试

套件测试就是把几个单元测试组合成一个模块,然后运行,这个特性两个框架均已实现。然而却是用了两个不同的方式来实现的。

JUnit 4

@RunWith 和 @Suite注解被用于执行套件测试。下面的代码是所展示的是在JunitTest5被执行之后需要JunitTest1 和 JunitTest2也一起执行。所有的声明需要在类内部完成。

1

2

3

4

5

6

7

@RunWith(Suite.class)

@Suite.SuiteClasses({

JunitTest1.class,

JunitTest2.class

})

public class JunitTest5 {

}

TestNG

执行套件测试是使用XML文件配置的方式来做。下面的 XML 的文件可以使得TestNGTest1和TestNGTest2一起执行。

1

2

3

4

5

6

7

8

9

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >

<suite name="My test suite">

<test name="testing">

<classes>

<class name="com.fsecure.demo.testng.TestNGTest1" />

<class name="com.fsecure.demo.testng.TestNGTest2" />

</classes>

</test>

</suite>

TestNG可以在这块做的更好,使用了组的概念,每个方法都可以被分配到一个组里面,可以根据功能特性来分组。例如:

这是一个有4个方法,3个组(method1, method2 和 method4)的类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@Test(groups="method1")

public void testingMethod1() {

System.out.println("Method - testingMethod1()");

}

@Test(groups="method2")

public void testingMethod2() {

System.out.println("Method - testingMethod2()");

}

@Test(groups="method1")

public void testingMethod1_1() {

System.out.println("Method - testingMethod1_1()");

}

@Test(groups="method4")

public void testingMethod4() {

System.out.println("Method - testingMethod4()");

}

下面XML文件定义了一个只是执行methed1的组的单元测试

1

2

3

4

5

6

7

8

9

10

11

12

13

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >

<suite name="My test suite">

<test name="testing">

<groups>

<run>

<include name="method1"/>

</run>

</groups>

<classes>

<class name="com.fsecure.demo.testng.TestNGTest5_2_0" />

</classes>

</test>

</suite>

使用分组的概念,集成测试就会更加强大。例如,我们可以只是执行所有测试中的组名为DatabaseFuntion的测试。

参数化测试

参数化测试意思是给单元测试传多个参数值。这个特性在JUnit 4 和TestNG。然后两个框架实现的方式却完全不同。

JUnit 4

@RunWith 和 @Parameter 注解用于为单元测试提供参数值,@Parameters必须返回 List,参数将会被作为参数传给类的构造函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@RunWith(value = Parameterized.class)

public class JunitTest6 {

private int number;

public JunitTest6(int number) {

this.number = number;

}

@Parameters

public static Collection<Object[]> data() {

Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };

return Arrays.asList(data);

}

@Test

public void pushTest() {

System.out.println("Parameterized Number is : " + number);

}

}

它在使用上有许多的限制;我们必须遵循 JUnit 的方式去声明参数,参数必须通过构造函数的参数去初始化类的成员来用于测试。返回的参数类型必须是List [],数据已经被限定为String或者是一个原始值。

TestNG

使用XML文件或者@DataProvider注解来给测试提供参数。

XML文件配置参数化测试

只是在方法上声明@Parameters注解,参数的数据将由 TestNG 的 XML 配置文件提供。这样做之后,我们可以使用不同的数据集甚至是不同的结果集来重用一个测试用例。另外,甚至是最终用户,QA 或者 QE 可以提供使用 XML 文件来提供他们自己的数据来做测试。

Unit Test

1

2

3

4

5

6

7

8

9

public class TestNGTest6_1_0 {

@Test

@Parameters(value="number")

public void parameterIntTest(int number) {

System.out.println("Parameterized Number is : " + number);

}

}

XML 文件

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >

<suite name="My test suite">

<test name="testing">

<parameter name="number" value="2"/>

<classes>

<class name="com.fsecure.demo.testng.TestNGTest6_0" />

</classes>

</test>

</suite>

@DataProvider 注解做参数化测试

使用XML文件初始化数据可以很方便,但是测试偶尔需要复杂的类型,一个String或原始值并不能完全满足。 TestNG 的@ DataProvider的注解,可以更好的把复杂的参数类型映射到一个测试方法来处理这种情况。

@DataProvider 可以使用 Vector, String 或者 Integer 类型的值作为参数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Test(dataProvider = "Data-Provider-Function")

public void parameterIntTest(Class clzz, String[] number) {

System.out.println("Parameterized Number is : " + number[0]);

System.out.println("Parameterized Number is : " + number[1]);

}

//This function will provide the patameter data

@DataProvider(name = "Data-Provider-Function")

public Object[][] parameterIntTestProvider() {

return new Object[][]{

{Vector.class, new String[] {"java.util.AbstractList", "java.util.AbstractCollection"}},

{String.class, new String[] {"1", "2"}},

{Integer.class, new String[] {"1", "2"}}

};

}

@DataProvider 作为对象的参数

P.S “TestNGTest6_3_0” 是一个简单的对象,使用了get和set方法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Test(dataProvider = "Data-Provider-Function")

public void parameterIntTest(TestNGTest6_3_0 clzz) {

System.out.println("Parameterized Number is : " + clzz.getMsg());

System.out.println("Parameterized Number is : " + clzz.getNumber());

}

//This function will provide the patameter data

@DataProvider(name = "Data-Provider-Function")

public Object[][] parameterIntTestProvider() {

TestNGTest6_3_0 obj = new TestNGTest6_3_0();

obj.setMsg("Hello");

obj.setNumber(123);

return new Object[][]{

{obj}

};

}

TestNG的参数化测试使用起来非常的友好和灵活 (不管是XML配置还是在类里面注解的方式). 它可以使用许多复杂的数据类型作为参数的值,并且没有什么限制。如上面的例子所示, we even can pass in our own object (TestNGTest6_3_0) for parameterized test

依赖测试

参数化测试意味着测试的方法是有依赖的,也就是要执行的的方法在执行之前需要执行的部分。如果依赖的方法出现错误,所有的子测试都会被忽略,不会被标记为失败。

JUnit 4

JUnit 框架主要聚焦于测试的隔离,暂时还不支持这个特性。

TestNG

它使用dependOnMethods来实现了依赖测试的功能,如下:

1

2

3

4

5

6

7

8

9

@Test

public void method1() {

System.out.println("This is method 1");

}

@Test(dependsOnMethods={"method1"})

public void method2() {

System.out.println("This is method 2");

}

如果method1()成功执行,那么method2()也将被执行,否则method2()将会被忽略。

讨论总结

当我们做完所有特性的对比以后,我建议使用 TestNG 作为 Java 项目的主要单元测试框架,因为 TestNG 在参数化测试、依赖测试以及套件测试(组)方面功能更加强大。TestNG 意味着高级的测试和复杂的集成测试。它更加的灵活,特别是对大的套件测试。另外,TestNG 也涵盖了 JUnit4 的全部功能。那就没有任何理由使用 Junit了。

参考资料

TestNG

————

http://en.wikipedia.org/wiki/TestNG

http://www.ibm.com/developerworks/java/library/j-testng/

http://testng.org/doc/index.html

http://beust.com/weblog/

JUnit

———–

http://en.wikipedia.org/wiki/JUnit

http://www.ibm.com/developerworks/java/library/j-junit4.html

http://junit.sourceforge.net/doc/faq/faq.htm

http://www.devx.com/Java/Article/31983/0/page/3

http://ourcraft.wordpress.com/2008/08/27/writing-a-parameterized-junit-test/

TestNG VS JUnit

——————

http://docs.codehaus.org/display/XPR/Migration+to+JUnit4+or+TestNG

http://www.ibm.com/developerworks/java/library/j-cq08296/index.html

http://www.cavdar.net/2008/07/21/junit-4-in-60-seconds/

JUnit 4 与 TestNG 对比的更多相关文章

  1. JUnit 4 Vs TestNG比较

    JUnit 4和TestNG都是Java中非常受欢迎的单元测试框架.两种框架在功能上看起来非常相似. 哪一个更好? 在Java项目中应该使用哪个单元测试框架? 下面表中概括了JUnit 4和TestN ...

  2. JUnit 4 和 TestNG

    JUnit 4和TestNG都是Java中非常受欢迎的单元测试框架.两种框架在功能上看起来非常相似.哪一个更好?在Java项目中应该使用哪个单元测试框架? 下面表中概括了JUnit 4和TestNG之 ...

  3. 关于testNG和JUnit的对比

    关于选择JUnit还是选testNG,这几篇文章,建议读一读: API参考文档: Junit API文档:http://junit.org/junit4/javadoc/latest/index.ht ...

  4. 单元测试——测试神器,testng

    为什么用它 建议使用 TestNG 作为 Java 项目的主要单元测试框架,因为 TestNG 在参数化测试.依赖测试以及套件测试(组)方面功能更加强大.TestNG 意味着高级的测试和复杂的集成测试 ...

  5. testNg vs junit 4.X @Test

    http://www.ibm.com/developerworks/cn/java/j-cq08296/ 一个简单的测试用例 初看起来,JUnit 4 和 TestNG 中实现的测试非常相似.为了更好 ...

  6. testng入门教程11 TestNG运行JUnit测试

    现在,您已经了解了TestNG和它的各种测试,如果现在担心如何重构现有的JUnit代码,那就没有必要,使用TestNG提供了一种方法,从JUnit和TestNG按照自己的节奏.也可以使用TestNG执 ...

  7. 在Eclipse中开发使用Spring IOC的JUnit/TestNG测试用例之详解

    转载自:http://blog.csdn.net/radic_feng/article/details/6740438 我们期望能像在产品代码中一样,在测试用例中使用的bean也由Spring Con ...

  8. Java Unit Testing - JUnit & TestNG

    转自https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaUnitTesting.html yet another insignifican ...

  9. 单元测试利器 JUnit 4

    引言 毋庸置疑,程序员要对自己编写的代码负责,您不仅要保证它能通过编译,正常地运行,而且要满足需求和设计预期的效果.单元测试正是验证代码行为是否满足预期的有效手段之一.但不可否认,做测试是件很枯燥无趣 ...

随机推荐

  1. c 进程和系统调用

    这一篇博客讲解进程和系统调用相关的知识 有这样一个场景,我需要输入一串文字,然后把我输入的文字加上一个本地的时间戳 保存在一个文件中,可以初步理解为一个备忘录也行 #include <stdio ...

  2. jvm系列(六):jvm调优-从eclipse开始

    jvm调优-从eclipse开始 概述 什么是jvm调优呢?jvm调优就是根据gc日志分析jvm内存分配.回收的情况来调整各区域内存比例或者gc回收的策略:更深一层就是根据dump出来的内存结构和线程 ...

  3. Vertica 分区表设计(续)

    在上篇Vertica 分区表设计中,已经提过了Vertica的分区表创建和分区删除,但举例上并不系统, 本篇文章将系统的对分区表设计及后续的删除分区进行讲解. 概述:Vertica分区表(天和月)创建 ...

  4. 微信小程序定时器组件(输入时间字符串即可倒计时)

    昨天写了代码,今天发现要重用,干脆就抽出来做个组件得了,顺便还改善了一下代码通用性. 昨天的代码在这里 github下载地址 用法: 引入: var timer = require('../../pl ...

  5. 03 通过Button打开另一个的frm

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) { DialogResult re = MessageBox ...

  6. [Android下载]北京新版小学英语三年级上册点读手机软件

    小学英语三年级上册点读软件.根据2014年北京教改版教材编写,发音标准.实现点读功能.点到哪里读到哪里.哪里不会点哪里!北京教育科学研究院编写,北京出版社出版.ISBN:9787200108781   ...

  7. TypeScript之面向对象初体验

    1.安装nodejs和vscode: nodejs : https://nodejs.org/en/ Visual Studio Code :  https://www.visualstudio.co ...

  8. Java中文字符处理的四大迷题

    虽然计算机对英文字符的支持非常不错,我们也恨不得写的程序只会处理英文的数据,但是昨为中国人,无可避免地要处理一些中文字符.当很简单的一件事情,遇到了中文,一切就不同了!本文就会讲述实际生产环境中遇到的 ...

  9. logstash+elasticsearch+kibana管理日志(安装)

    logstash1.先安装jdk2.wget https://download.elastic.co/logstash/logstash/logstash-2.4.0.tar.gz tar -xzvf ...

  10. 高效 Java Web 开发框架 JessMA v3.4.1

    JessMA 是功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hibernate.MyBatis 与 J ...