繼續進行同樣的戰斗,昨天我開始研究Spring的測試支持 。 它也建立在JUnit之上。 但是,在使用相同功能的幾分鐘后,我一直在尋找JUnit中一直找不到的功能。 TestNG使用DataProviders提供參數化測試 。 考慮到我再次問自己一個熟悉的問題– TestNG或JUnit,我決定對此進行記錄,以便下次可以確定是哪個以及為什么。
基本上一樣
如果您只是要進行一些基本的單元測試,那么這兩個框架基本上是相同的。 這兩個框架都允許您快速有效地測試代碼。 他們在Eclipse和其他IDE中具有工具支持。 他們還獲得了諸如Ant和Maven之類的構建框架的支持。 對于初學者來說,JUnit一直是首選,因為它是第一個用于單元測試的框架,并且一直可用。 我談論的許多人直到我們談論它之前都沒有聽說過TestNG。
靈活性
讓我們來看兩個簡單的測試用例。
package com.kapil.itrader;
import java.util.Arrays;
import java.util.List;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;public class FibonacciTest
{private Integer input;private Integer expected;@BeforeClasspublic static void beforeClass(){// do some initialization}@Testpublic void FibonacciTest(){System.out.println("Input: " + input + ". Expected: " + expected);Assert.assertEquals(expected, Fibonacci.compute(input));assertEquals(expected, Fibonacci.compute(input));}
}
好吧,這是示例展示,我正在使用4.x +版本并正在使用注釋。 優先于4.0版本; JUnit不支持注釋,這是TestNG相對于競爭對手的主要優勢; 但是JUnit很快就適應了。 您會注意到,JUnit還支持靜態導入,并且我們可以像以前的版本中那樣省去更多繁瑣的代碼。
package com.kapil.framework.core;
import junit.framework.Assert;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;public class BaseTestCase
{protected static final ClassPathXmlApplicationContext context;static{context = new ClassPathXmlApplicationContext("rootTestContext.xml");context.registerShutdownHook();}@BeforeSuiteprivate void beforeSetup(){// Do initialization}@Testpublic void testTrue(){Assert.assertTrue(false);}
}
首先看一下這兩個代碼,可以推斷兩者幾乎相同。 但是,對于那些已經完成足夠的單元測試的人,我會同意TestNG可以提供更大的靈活性。 JUnit要求我將初始化方法聲明為static; 因此,我將在該方法中編寫的任何內容也必須是靜態的。 JUnit還要求我將初始化方法公開。 但是TestNG不會。 我也可以在測試課程中使用OOP的最佳實踐。 除了@ BeforeClass,TestNG還允許我聲明測試套件,組,方法,并使用@ BeforeSuite,@ BeforeMethod,@ BeforeGroups等注釋。 當編寫需要訪問公共數據集的任何級別的集成測試或單元測試用例時,這非常有用。
測試隔離和依賴性測試
在進行隔離測試時,Junit非常有效。 從本質上講,這意味著您無法控制測試的執行順序。 而且,因此,如果由于某種依賴關系而有兩個要按特定順序運行的測試,則無法使用JUnit進行。 但是,TestNG允許您非常有效地執行此操作。 在Junit中,您可以解決此問題,但它并不整齊,也不那么容易。
基于參數的測試
TestNG提供的一個非常強大的功能是“參數化測試”。 JUnit在4.5+版本中對此添加了一些支持,但是它不如TestNG有效。 您可能與FIT合作過,您會知道我在說什么。 但是,JUnit中添加的支持是非常基本的,并且效果不佳。 我已經修改了我以前的測試用例,以包括參數化測試。
package com.kapil.itrader;import static org.junit.Assert.assertEquals;import java.util.Arrays;
import java.util.List;import junit.framework.Assert;import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;@RunWith(Parameterized.class)
public class FibonacciTest
{private Integer input;private Integer expected;@Parameterspublic static List data(){return Arrays.asList(new Integer[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });}@BeforeClasspublic static void beforeClass(){System.out.println("Before");}public FibonacciTest(Integer input, Integer expected){this.input = input;this.expected = expected;}@Testpublic void FibonacciTest(){System.out.println("Input: " + input + ". Expected: " + expected);Assert.assertEquals(expected, Fibonacci.compute(input));assertEquals(expected, Fibonacci.compute(input));}}
您會注意到,我已經使用@RunWith批注來對測試用例進行參數化。 在這種情況下,將使用已用@Parameters注釋的內聯方法– data()將數據提供給該類。 但是,最大的問題是將數據傳遞給類構造函數。 這使我只能在此類中編寫邏輯綁定的測試用例。 而且,我最終將對一個服務擁有多個測試用例,因為該服務中的所有各種方法都需要不同的數據集。 好消息是,有各種開放源代碼框架擴展了此方法,并添加了自己的“ RunWith”實現,以允許與CSV,HTML或Excel文件等外部實體集成。
TestNG提供了開箱即用的支持。 不支持讀取CSV或外部文件,但支持數據提供程序。
package com.kapil.itrader.core.managers.admin;import org.testng.Assert;
import org.testng.annotations.Test;import com.uhc.simple.common.BaseTestCase;
import com.uhc.simple.core.admin.manager.ILookupManager;
import com.uhc.simple.core.admin.service.ILookupService;
import com.uhc.simple.dataprovider.admin.LookupValueDataProvider;
import com.uhc.simple.dto.admin.LookupValueRequest;
import com.uhc.simple.dto.admin.LookupValueResponse;/*** Test cases to test {@link ILookupService}.*/
public class LookupServiceTests extends BaseTestCase
{@Test(dataProvider = "LookupValueProvider", dataProviderClass = LookupValueDataProvider.class)public void testGetAllLookupValues(String row, LookupValueRequest request, LookupValueResponse expectedResponse){ILookupManager manager = super.getLookupManager();LookupValueResponse actualResponse = manager.getLookupValues(request);Assert.assertEquals(actualResponse.getStatus(), expectedResponse.getStatus());}
}
上面的代碼片段展示了我已經將dataProvider用作批注的值,然后提供了一個類,該類負責創建在調用時提供給方法的數據。 使用這種機制,我可以輕松地以分離的方式編寫測試用例及其數據提供者,并非常有效地使用它。
為什么我選擇TestNG
對我而言,參數化測試是我選擇TestNG而非Junit的最大原因。 但是,上面列出的所有內容都是為什么我總是要花幾分鐘的時間在新的Eclipse安裝程序或maven項目中設置TestNG的原因。 當運行大型測試套件時,TestNG非常有用。 對于小型項目或培訓活動,JUnit很好; 因為任何人都可以很快開始使用它; 但不適用于需要數千個測試用例的項目,并且在大多數測試用例中,您會遇到各種情況。
參考: Scratch Pad博客上來自我們JCG合作伙伴 Kapil Viren Ahuja的TestNG或JUnit 。
翻譯自: https://www.javacodegeeks.com/2012/01/testng-or-junit.html