JUnit 4与TestNG –比较

JUnit 4和TestNG都是Java中非常流行的单元测试框架。 这两个框架在功能上看起来非常相似。 哪一个更好? 我应该在Java项目中使用哪个单元测试框架?

在这里,我对JUnit 4和TestNG进行了功能比较。

junit-vs-testngjpg

1.注释支持

注释支持在JUnit 4和TestNG中都实现了,外观相似。

特征 JUnit 4 测试NG
测试注解 @测试 @测试
在此套件中的所有测试运行之前运行 - @BeforeSuite
该套件中的所有测试都运行后运行 - @AfterSuite
在测试前运行 - @BeforeTest
测试后运行 - @AfterTest
在调用属于任何这些组的第一个测试方法之前运行 - @BeforeGroups
在调用属于任何这些组的最后一个测试方法之后运行 - @AfterGroups
在调用当前类中的第一个测试方法之前运行 @课前 @课前
在运行当前类中的所有测试方法之后运行 @下课以后 @下课以后
在每种测试方法之前运行 @之前 @BeforeMethod
在每种测试方法之后运行 @后 @AfterMethod
忽略测试 @忽视 @Test(enbale = false)
预期异常 @Test(expected = ArithmeticException.class) @Test(expectedExceptions = ArithmeticException.class)
超时 @Test(超时= 1000) @Test(超时= 1000)

JUnit4和TestNG之间的主要注释差异是

1.在JUnit 4中,我们必须将“ @BeforeClass”和“ @AfterClass”方法声明为静态方法。 TestNG在方法声明方面更为灵活,它没有此约束。

2. 3个附加的setUp / tearDown级别:套件和组(@ Before / AfterSuite,@ Before / AfterTest,@ Before / AfterGroup)。 在这里查看更多详细信息。

JUnit 4

@BeforeClass
    public static void oneTimeSetUp() {
        // one-time initialization code   
    	System.out.println("@BeforeClass - oneTimeSetUp");
    }

测试NG

@BeforeClass
    public void oneTimeSetUp() {
        // one-time initialization code   
    	System.out.println("@BeforeClass - oneTimeSetUp");
}

在JUnit 4中,注释的命名约定有些混乱,例如“ Before”,“ After”和“ Expected”,我们实际上并不了解“ Before”和“ After”的含义,以及我们根据测试“预期”的含义方法? TestiNG易于理解,它使用“ BeforeMethod”,“ AfterMethod”和“ ExpectedException”代替。

2.异常测试

“异常测试”表示从单元测试中抛出什么异常,此功能在JUnit 4和TestNG中均已实现。

JUnit 4

@Test(expected = ArithmeticException.class)  
	public void divisionWithException() {  
	  int i = 1/0;
	}

测试NG

@Test(expectedExceptions = ArithmeticException.class)  
	public void divisionWithException() {  
	  int i = 1/0;
	}

3.忽略测试

“已忽略”表示是否应忽略单元测试,此功能已在JUnit 4和TestNG中实现。

JUnit 4

@Ignore("Not Ready to Run")  
	@Test
	public void divisionWithException() {  
	  System.out.println("Method is not ready yet");
	}

测试NG

@Test(enabled=false)
	public void divisionWithException() {  
	  System.out.println("Method is not ready yet");
	}

4.时间测试

“时间测试”表示如果单元测试花费的时间超过指定的毫秒数,则测试将终止并标记为失败,此功能已在JUnit 4和TestNG中实现。

JUnit 4

@Test(timeout = 1000)  
	public void infinity() {  
		while (true);  
	}

测试NG

@Test(timeOut = 1000)  
	public void infinity() {  
		while (true);  
	}

5.套件测试

“套件测试”是指捆绑几个单元测试并一起运行。 JUnit 4和TestNG都实现了此功能。 但是,两者都使用非常不同的方法来实现它。

JUnit 4

“ @RunWith”和“ @Suite”用于运行套件测试。 下面的类表示在执行JunitTest5之后,单元测试“ JunitTest1”和“ JunitTest2”将同时运行。 所有声明都在类内部定义。

@RunWith(Suite.class)
@Suite.SuiteClasses({
        JunitTest1.class,
        JunitTest2.class
})
public class JunitTest5 {
}

测试NG

XML文件用于运行套件测试。 下面的XML文件意味着单元测试“ TestNGTest1”和“ TestNGTest2”将一起运行。

<!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可以做的不仅是捆绑类测试,还可以捆绑方法测试。 通过TestNG独特的“分组”概念,每种方法都可以绑定到一个组,它可以根据功能对测试进行分类。 例如,

这是一个具有四个方法,三个组的类(方法1,方法2和方法3)

@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文件,我们只能使用“ method1”组执行单元测试。

<!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”组。

6.参数化测试

“参数化测试”是指更改单元测试的参数值。 JUnit 4和TestNG都实现了此功能。 但是,两者都使用非常不同的方法来实现它。

JUnit 4

“ @RunWith”和“ @Parameter”用于提供单元测试的参数值,@ Parameters必须返回List [],并且该参数将作为参数传递到类构造函数中。

@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”方法来声明参数,并且该参数必须传递到构造函数中,以便将类成员初始化为用于测试的参数值。 参数类的返回类型为“列表[]”,数据已限于String或用于测试的原始值。

测试NG

XML文件或“ @DataProvider”用于提供各种参数进行测试。

用于参数化测试的XML文件。
仅“ @Parameters”在方法中声明需要测试的参数,参数数据将在TestNG的XML配置文件中提供。 通过这样做,我们可以重用具有不同数据集的单个测试用例,甚至获得不同的结果。 另外,甚至最终用户,QA或QE都可以在XML文件中提供自己的数据以进行测试。

单元测试

public class TestNGTest6_1_0 {
  
	   @Test
	   @Parameters(value="number")
	   public void parameterIntTest(int number) {
	      System.out.println("Parameterized Number is : " + number);
	   }
	 
      }

XML文件

<!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注释来处理这种情况,这有助于将复杂的参数类型映射到测试方法。

将Vector,String或Integer作为参数的@DataProvider

@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作为参数
PS“ TestNGTest6_3_0”是一个简单的对象,仅具有用于演示的get set方法。

@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文件中还是在类内部)。 它可以支持许多复杂的数据类型作为参数值,并且可能性是无限的。 如上例所示,我们甚至可以传入我们自己的对象(TestNGTest6_3_0)进行参数化测试

7.依赖性测试

“参数化测试”表示方法是基于依赖关系的测试,将在所需方法之前执行。 如果从属方法失败,则将跳过所有后续测试,而不是将其标记为失败。

JUnit 4

JUnit框架专注于测试隔离; 它目前不支持此功能。

测试NG

它使用“ dependOnMethods”来实现依赖关系测试,如下所示

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

参考文献

测试NG
————
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/

翻译自: https://mkyong.com/unittest/junit-4-vs-testng-comparison/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值