JUnit 4 Vs TestNG - Comparaison
JUnit 4 et TestNG sont tous deux des frameworks de tests unitaires très populaires en Java. Les deux frameworks ont une fonctionnalité très similaire. Quel est le meilleur? Quel framework de test unitaire dois-je utiliser dans un projet Java?
Ici, j'ai fait une comparaison des fonctionnalités entre JUnit 4 et TestNG.
1. Prise en charge des annotations
Les supports d'annotation sont implémentés dans JUnit 4 et TestNG se ressemblent.
Fonctionnalité | JUnit 4 | TestNG |
---|---|---|
annotation de test |
@Tester |
@Tester |
exécuter avant que tous les tests de cette suite ne soient exécutés |
— |
@BeforeSuite |
exécuter après que tous les tests de cette suite ont été exécutés |
— |
@AfterSuite |
exécuter avant le test |
— |
@BeforeTest |
courir après le test |
— |
@AfterTest |
s'exécuter avant que la première méthode de test appartenant à l'un de ces groupes ne soit appelée |
— |
@BeforeGroups |
s'exécuter après que la dernière méthode de test appartenant à l'un de ces groupes soit appelée |
— |
@AfterGroups |
s'exécuter avant que la première méthode de test de la classe actuelle ne soit appelée |
@Avant les cours |
@Avant les cours |
exécuter après que toutes les méthodes de test de la classe actuelle ont été exécutées |
@Après les cours |
@Après les cours |
exécuter avant chaque méthode de test |
@Avant |
@BeforeMethod |
exécuter après chaque méthode de test |
@Après |
@AfterMethod |
ignorer le test |
@ignorer |
@Test (enbale = false) |
exception attendue |
@Test (attendu = ArithmeticException.class) |
@Test (expectedExceptions = ArithmeticException.class) |
temps libre |
@Test (délai d'expiration = 1000) |
@Test (délai d'expiration = 1000) |
Les principales différences d'annotation entre JUnit4 et TestNG sont
1. Dans JUnit 4, nous devons déclarer les méthodes «@BeforeClass» et «@AfterClass» comme méthode statique. TestNG est plus flexible dans la déclaration de méthode, il n'a pas ces contraintes.
2. 3 niveaux supplémentaires setUp / tearDown: suite et groupe (@ Before / AfterSuite, @ Before / AfterTest, @ Before / AfterGroup). Voir plus dedetail here.
JUnit 4
@BeforeClass public static void oneTimeSetUp() { // one-time initialization code System.out.println("@BeforeClass - oneTimeSetUp"); }
TestNG
@BeforeClass public void oneTimeSetUp() { // one-time initialization code System.out.println("@BeforeClass - oneTimeSetUp"); }
Dans JUnit 4, la convention de dénomination des annotations est un peu déroutante, par exemple «Avant», «Après» et «Attendu», nous ne comprenons pas vraiment ce que font «Avant» et «Après», et ce que nous «attendons» du test méthode? TestiNG est plus facile à comprendre, il utilise à la place «BeforeMethod», «AfterMethod» et «ExpectedException».
2. Test d'exception
Le «test d'exception» signifie quelle exception lève du test unitaire, cette fonctionnalité est implémentée à la fois dans JUnit 4 et TestNG.
JUnit 4
@Test(expected = ArithmeticException.class) public void divisionWithException() { int i = 1/0; }
TestNG
@Test(expectedExceptions = ArithmeticException.class) public void divisionWithException() { int i = 1/0; }
3. Ignorer le test
«Ignoré» signifie s'il doit ignorer le test unitaire, cette fonctionnalité est implémentée à la fois dans JUnit 4 et TestNG.
JUnit 4
@Ignore("Not Ready to Run") @Test public void divisionWithException() { System.out.println("Method is not ready yet"); }
TestNG
@Test(enabled=false) public void divisionWithException() { System.out.println("Method is not ready yet"); }
4. Test de temps
Le «Test de temps» signifie que si un test unitaire prend plus de temps que le nombre spécifié de millisecondes pour s'exécuter, le test se terminera et marquera comme échec, cette fonctionnalité est implémentée à la fois dans JUnit 4 et TestNG.
JUnit 4
@Test(timeout = 1000) public void infinity() { while (true); }
TestNG
@Test(timeOut = 1000) public void infinity() { while (true); }
5. Test de la suite
Le «test de la suite» signifie regrouper quelques tests unitaires et les exécuter ensemble. Cette fonctionnalité est implémentée à la fois dans JUnit 4 et TestNG. Cependant, les deux utilisent une méthode très différente pour le mettre en œuvre.
JUnit 4
«@RunWith» et «@Suite» sont utilisés pour exécuter le test de la suite. La classe ci-dessous signifie que les tests unitaires «JunitTest1» et «JunitTest2» sont exécutés ensemble après l'exécution de JunitTest5. Toute la déclaration est définie à l'intérieur de la classe.
@RunWith(Suite.class) @Suite.SuiteClasses({ JunitTest1.class, JunitTest2.class }) public class JunitTest5 { }
TestNG
Le fichier XML est utilisé pour exécuter le test de la suite. Le fichier XML ci-dessous signifie que les tests unitaires «TestNGTest1» et «TestNGTest2» l'exécuteront ensemble.
TestNG peut faire plus que des tests de classes groupées, il peut également grouper des tests de méthodes. Avec le concept unique de «regroupement» de TestNG, chaque méthode est liée à un groupe, elle peut catégoriser les tests en fonction des fonctionnalités. Par exemple,
Voici une classe avec quatre méthodes, trois groupes (méthode1, méthode2 et méthode3)
@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()"); }
Avec le fichier XML suivant, nous pouvons exécuter le test unitaire avec le groupe «méthode1» uniquement.
Avec le concept de test «Grouping», la possibilité de test d'intégration est illimitée. Par exemple, nous ne pouvons tester le groupe «DatabaseFuntion» que de toutes les classes de test unitaire.
6. Test paramétré
Le «test paramétré» signifie faire varier la valeur du paramètre pour le test unitaire. Cette fonctionnalité est implémentée à la fois dans JUnit 4 et TestNG. Cependant, les deux utilisent une méthode très différente pour le mettre en œuvre.
JUnit 4
«@RunWith» et «@Parameter» sont utilisés pour fournir une valeur de paramètre pour le test unitaire, @Parameters doit retourner List [], et le paramètre passera dans le constructeur de classe comme argument.
@RunWith(value = Parameterized.class) public class JunitTest6 { private int number; public JunitTest6(int number) { this.number = number; } @Parameters public static Collection
Il a de nombreuses limitations ici; nous devons suivre la méthode «JUnit» pour déclarer le paramètre, et le paramètre doit passer dans le constructeur afin d'initialiser le membre de la classe comme valeur de paramètre pour le test. Le type de retour de la classe de paramètres est «List []», les données ont été limitées à String ou à une valeur primitive pour les tests.
TestNG
Le fichier XML ou «@DataProvider» est utilisé pour fournir des paramètres variables pour les tests.
XML file for parameterized test.
Seul «@Parameters» déclare dans la méthode qui nécessite un paramètre pour le test, les données paramétriques seront fournies dans les fichiers de configuration XML de TestNG. En faisant cela, nous pouvons réutiliser un seul cas de test avec différents ensembles de données et même obtenir des résultats différents. De plus, même l'utilisateur final, QA ou QE peut fournir ses propres données dans un fichier XML à des fins de test.
Test de l'unité
public class TestNGTest6_1_0 { @Test @Parameters(value="number") public void parameterIntTest(int number) { System.out.println("Parameterized Number is : " + number); } }
Fichier XML
@DataProvider pour le test paramétré.
Bien que l'extraction de valeurs de données dans un fichier XML puisse être très pratique, les tests nécessitent parfois des types complexes, qui ne peuvent pas être représentés sous forme de chaîne ou de valeur primitive. TestNG gère ce scénario avec son annotation @DataProvider, qui facilite le mappage de types de paramètres complexes à une méthode de test.
@DataProvider pour Vector, String ou Integer comme paramètre
@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 pour l'objet comme paramètre
P.S «TestNGTest6_3_0» est un objet simple avec juste la méthode get set pour la démo.
@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} }; }
Le test paramétré de TestNG est très convivial et flexible (soit dans un fichier XML soit à l'intérieur de la classe). Il peut prendre en charge de nombreux types de données complexes comme valeur de paramètre et la possibilité est illimitée. Comme exemple ci-dessus, nous pouvons même passer notre propre objet (TestNGTest6_3_0) pour un test paramétré
7. Test de dépendance
Le «test paramétré» signifie que les méthodes sont des tests basés sur la dépendance, qui s'exécuteront avant une méthode souhaitée. Si la méthode dépendante échoue, tous les tests suivants seront ignorés et non marqués comme ayant échoué.
JUnit 4
Le framework JUnit se concentre sur l'isolement des tests; il ne prend pas en charge cette fonctionnalité pour le moment.
TestNG
Il utilise «dependOnMethods» pour implémenter le test de dépendance comme suit
@Test public void method1() { System.out.println("This is method 1"); } @Test(dependsOnMethods={"method1"}) public void method2() { System.out.println("This is method 2"); }
La «méthode2 ()» ne s'exécutera que si «méthode1 ()» est exécutée avec succès, sinon «méthode2 ()» sautera le test.
Conclusion
Après avoir réfléchi à toutes les comparaisons de fonctionnalités, je suggère d'utiliser TestNG comme cadre de test unitaire de base pour le projet Java, car TestNG est plus avancé dans les tests de paramétrage, les tests de dépendance et les tests de suite (concept de regroupement). TestNG est destiné aux tests de haut niveau et aux tests d'intégration complexes. Sa flexibilité est particulièrement utile avec de grandes suites de tests. En outre, TestNG couvre également l'ensemble des fonctionnalités de base de JUnit4. Ce n’est tout simplement plus aucune raison pour moi d’utiliser JUnit.
Références
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/