JUnit 4 与 TestNG 对比

article/2025/10/2 12:01:23

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中,注解的命名是比较令人困惑的,例如 BeforeAfter and Expected,我们不是很确切的能理解在方法前面有BeforeAfter这样的注解是做什么的,同样Expected也如此。TestNG在这方面做的就好很多,注解使用了BeforeMethodAfterMethodExpectedException,这样的名字就非常好理解了。

异常测试

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

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 的文件可以使得TestNGTest1TestNGTest2一起执行。

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了。


http://chatgpt.dhexx.cn/article/77wV1qPG.shtml

相关文章

Junit 4 Tutorials(Junit 4 教程) 一、Junit简介及Junit Eclipse 教程

Junit 测试框架简介 测试框架是最流行的Java单元测试框架。Junit被用来开发对Java类的单元测试。它就是一个类包&#xff0c;提供了各种方法来测试Java类中的方法(method)。 Junit 4 特性 简单的注解&#xff0c;提供书写Junit测试的基本特性断言方法(Assert Methods)比较测试…

JUnit4 与 JUnit 5 常用注解对比

JUnit4 与 JUnit 5 常用注解对比 JUnit4JUnit5说明TestTest表示该方法是一个测试方法。JUnit5与JUnit 4的Test注解不同的是&#xff0c;它没有声明任何属性&#xff0c;因为JUnit Jupiter中的测试扩展是基于它们自己的专用注解来完成的。这样的方法会被继承&#xff0c;除非它…

JUnit4教程(一):基本应用

一、简介 这个估计大家都比我清楚了&#xff0c;JUnit是一个单元测试框架&#xff0c;我们可以基于它编写用来测试代码的代码&#xff0c;从而更方便地进行回归测试。 二、编写测试与断言&#xff08;Assertion&#xff09; 在Junit4中&#xff0c;编写一个测试方法只需要使用…

JUnit4使用教程-快速入门

序言 大学刚学java的时候就听说过JUnit了&#xff0c;单元测试框架&#xff0c;很好用的测试框架&#xff0c;JUnit测试框架将测试更加便捷和容易&#xff0c;编写测试代码也是简单、明了&#xff0c;功能强大。今天我给大家简单分享一下最新JUnit4的使用&#xff0c;几分钟入…

单元测试——junit4入门例子

简单的Junit4 单元测试入门例子 新建第一个测试test case 这次我使用一个简单的例子来介绍如何写一个简单的单元测试&#xff0c;这里所用的测试工具是eclipse。 点击下载->涉及的项目源代码下载 被测文件 Calculate.java package com.junit4.main;public class Calcul…

JUnit4教程

因jdk5中的新特性&#xff0c;JUnit4也因此有了很大的改变。确切的说&#xff0c;Junit4简直就不是3的扩展版本&#xff0c;而是一个全新的测试框架。下面详细介绍JUnit4的使用方法 1.测试方法&#xff1a; 在junit4之前&#xff0c;测试类通过继承TestCase类&#xff0c;并使用…

JUnit4 jar包下载

JUnit4 jar包 链接&#xff1a;https://pan.baidu.com/s/112B-PaQvlTAzEXxHcpC9Sw 密码&#xff1a;ktrn

JUnit4单元测试入门教程

JUnit4单元测试入门教程 - 简书 本文按以下顺序讲解JUnit4的使用 下载jar包单元测试初体验自动生成测试类执行顺序Test的属性 下载jar包## 下载地址 在github上&#xff0c;把以下两个jar包都下载下来。 下载junit-4.12.jar&#xff0c;junit-4.12-javadoc.jar&#xff08;文…

JUnit4的使用和配置

JUnit4是JUnit框架有史以来的最大改进&#xff0c;其主要目标便是利用Java5的Annotation特性简化测试用例的编写。 先简单解释一下什么是Annotation&#xff0c;这个单词一般是翻译成元数据。元数据是什么&#xff1f;元数据就是描述数据的数据。也就是说&#xff0c;这个东西在…

浅谈java单元测试框架junit4/5

0 前言 junit是一个开源的Java语言的单元测试框架。目前junit主要有版本junit3&#xff0c;junit4和junit5。因在junit3中&#xff0c;是通过对测试类和测试方法的命名来确定是否是测试&#xff0c;且所有的测试类必须继承junit的测试基类TestCase&#xff0c;所以本文不再讨论…

IDEA中使用JUnit4(单元测试框架)超详细!

IDEA中使用JUnit4教程 超详细&#xff01;(单元测试框架) 导语&#xff1a;自动化测试的必经之路–Selenium 作者&#xff1a;变优秀的小白 Github&#xff1a;YX-XiaoBai QQ交流群(new): 811792998 爱好&#xff1a;Americano More Ice ! 话不多说&#xff0c;实战为主&…

Junit 4 的使用

一、什么是 Junit 我们来百度一波&#xff0c;什么是 Junit 可以看到哈&#xff0c;Junit 是一个 Java 语言的单元测试框架&#xff0c;这个东西是程序员自测所需要的一个东西&#xff0c;这个测试也被称为白盒测试。&#xff08;下面会去说什么是白盒测试&#xff09; 我们之…

JUnit4

1.JUnit4全面引入Annotation来执行我们编写的测试 2.JUnit4并不要求测试类继承TestCase父类 3.在一个测试类中&#xff0c;所有被Test注解所修饰的public,void方法都是test case,可以被JUnit所执行。 4.虽然JUnit4并不要求测试方法名以test开头&#xff0c;但我们最好还是按照 …

Junit 4详解

Java单元机测试框架 --- Junit4 1、什么是Junit4 JUnit4是一个易学易用的Java单元测试框架,一般我们在写完一段代码或一个方法的时候,都要测试一下这段代码和这个方法的逻辑是不是正确,输入一定的数据,返回的数据是不是我们想要的结果,即我们在写单个业务代码针对结果进行…

IOS UIBUtton

Type 第二个是Customer 常用 按钮的阴影效果只能左右 这是区别于标签的地方 阴影设置没有负值 按钮的代码使用 按钮点击方法 代码设置 传参

UIButton设置图片位置

设置小图片image的位置 image默认图片保持原大小可以通过设置contentVerticalAlignment和contentHorizontalAlignment&#xff0c;修改位置&#xff0c;甚至填充满按钮 // 修改图片位置 图2的效果[button setImage:image forState:UIControlStateNormal];button.contentVerti…

UIButton基础总结

1、UIButton简介 UIButton继承自UIControl。 2、UIButton的四种状态 UIButton的四种状态分别为Normal、Highlighted、Disabled和Selected。 **&#xff08;1&#xff09;Normal&#xff1a;**按钮的普通状态&#xff0c;即为按钮的初始状态 **&#xff08;2&#xff09;Highlig…

[Swift]代码触发UIButton的点击事件

使用极光的手机号码一键登录功能&#xff0c;要求点击按钮后先弹出协议同意&#xff0c;同意协议后自动改变底部协议状态再自动代码触发登录按钮的点击事件。 OC: [but sendActionsForControlEvents:UIControlEventTouchUpInside];Swift: but.sendActions(for: .touchUpInsid…

iOS UIButton控件

UIButton是UIControl的子类&#xff0c;实现了按钮功能&#xff0c;交互事件和控件状态可查看iOS UIControl控件。 1. 初始化 通过指定按钮类型来创建UIButton对象 (instancetype)buttonWithType:(UIButtonType)buttonType;UIButtonType是一个枚举类型 值说明UIButtonTypeCu…

UIButton基础

一、UIButton基础 与UILabel相同&#xff0c;UIButton对象也需要在ViewController中写一个创建函数来建立 UIButton对象的建立如下&#xff1a; //创建普通按钮函数 - (void) createUIRectButton {//创建一个btn对象&#xff0c;更具类型来创建btn//圆角类型btn:UIButtonType…