2010-04-19 16 views
58

Comment personnaliser l'ordre d'exécution des tests dans TestNG?Ordre d'exécution des tests dans TestNG

Par exemple:

public class Test1 { 
    @Test 
    public void test1() { 
     System.out.println("test1"); 
    } 

    @Test 
    public void test2() { 
     System.out.println("test2"); 
    } 

    @Test 
    public void test3() { 
     System.out.println("test3"); 
    } 
} 

Dans la suite ci-dessus, l'ordre d'exécution de tests est arbitraire. Pour une exécution, la sortie peut être:

test1 
test3 
test2 

Comment exécuter les tests dans l'ordre dans lequel ils ont été écrits?

Répondre

-5

Tests comme tests unitaires? Pourquoi? Les tests DOIVENT être indépendants, sinon ... vous ne pouvez pas exécuter un test individuellement. S'ils sont indépendants, pourquoi interférer? Plus - qu'est-ce qu'un "ordre" si vous les exécutez dans plusieurs threads sur plusieurs cœurs?

+2

Il est en fait tout à fait possible de mélanger les dépendances et le parallélisme, jetez un oeil à cet article pour savoir comment TestNG le fait: http: // beust.com/weblog/2009/11/28/noyau dur-multicore-avec-testng/ –

+0

Les gens utilisent JUnit pour beaucoup de choses en plus des tests unitaires. Presque toutes ces utilisations supplémentaires ont des moments où vous devez faire des choses dans un ordre particulier. C'est l'une des principales raisons de développer TestNG, BTW. – Jeffiekins

0

Il existe des moyens d'exécuter des tests dans un ordre donné. Normalement, les tests doivent être répétables et indépendants pour garantir qu'ils ne testent que la fonctionnalité désirée et qu'ils ne dépendent pas des effets secondaires du code en dehors de ce qui est testé. Donc, pour répondre à votre question, vous devrez fournir plus d'informations telles que POURQUOI il est important d'exécuter des tests dans un ordre spécifique.

+16

Il existe de nombreuses situations où les dépendances sont utiles, en particulier pour l'intégration et les tests fonctionnels. Par exemple, tester un site Web: vous voulez d'abord tester la page de connexion, puis la page suivante, etc ... Effacer et recréer l'état à partir de rien n'est pas pratique et entraîne des tests très lents. De plus, les dépendances vous offrent un meilleur diagnostic, comme "1 test échoué, 99 tests ignorés" au lieu des 100 tests échoués, ce qui ne permet pas de réaliser que toutes ces erreurs sont dues à l'échec d'un test. –

52

En TestNG, vous utilisez dependsOnMethods et/ou dependsOnGroups:

@Test(groups = "a") 
public void f1() {} 

@Test(groups = "a") 
public void f2() {} 

@Test(dependsOnGroups = "a") 
public void g() {} 

Dans ce cas, g() ne fonctionnera après f1() et f2() ont complété et réussi.

Vous trouverez beaucoup d'exemples dans la documentation: http://testng.org/doc/documentation-main.html#test-groups

+1

'dependsOnGroups' est extrêmement utile mais il me semble que TestNG ignore' priority' quand les deux sont combinés. –

+0

Cependant, la solution de Cedric a quelques inconvénients quand on travaille avec le plugin TestNG Eclipse, ver. 5.9.0.4 au moment où chaque exécution de TestCase montre que les groupes ne sont pas supportés par ce plugin. – honzajde

4

Si je comprends bien votre question que vous voulez exécuter des tests dans un ordre précis, TestNG IMethodInterceptor peut être utilisé. Jetez un oeil à http://beust.com/weblog2/archives/000479.html sur la façon de les exploiter.

Si vous voulez exécuter certains preinitialization, jetez un oeil à IHookable http://testng.org/javadoc/org/testng/IHookable.html et fil http://groups.google.com/group/testng-users/browse_thread/thread/42596505990e8484/3923db2f127a9a9c?lnk=gst&q=IHookable#3923db2f127a9a9c

1

associés En utilisant paramenter prioritaire pour @Test nous pouvons contrôler l'ordre d'exécution de test.

+2

Malheureusement, pas dans TestNG. –

+0

@MariuszJamro Je ne comprends pas pourquoi? Le paramètre 'Priority' n'a pas encore existé en 2012? –

4
@Test(dependsOnMethods="someBloodyMethod") 
+3

Je pourrais signaler que ce n'est pas une réponse particulièrement utile - je suggère de développer vos réponses dans un peu plus de détails! – Zyerah

19

Pour répondre scénario en question:

@Test 
public void Test1() { 

} 

@Test (dependsOnMethods={"Test1"}) 
public void Test2() { 

} 

@Test (dependsOnMethods={"Test2"}) 
public void Test3() { 

} 
60

Cela fonctionne.

@Test(priority=1) 
public void Test1() { 

} 

@Test(priority=2) 
public void Test2() { 

} 

@Test(priority=3) 
public void Test3() { 

} 

priority encourage l'ordre d'exécution, mais ne garantit pas le niveau de priorité précédente est terminée. test3 peut démarrer avant que test2 se termine. Si une garantie est nécessaire, déclarez une dépendance. Contrairement aux solutions qui déclarent des dépendances, les tests utilisant priority s'exécuteront même si un test échoue. Ce problème avec les dépendances peut être travaillé avec @Test(...alwaysRun = true...) selon documentation.

1

Piggy reculant de la réponse de user1927494, Si vous voulez exécuter un seul test avant tous les autres, vous pouvez le faire:

@Test() 
public void testOrderDoesntMatter_1() { 
} 

@Test(priority=-1) 
public void testToRunFirst() { 
} 

@Test() 
public void testOrderDoesntMatter_2() { 
} 
3

Si vous ne souhaitez pas utiliser l'option @Test(priority =) dans TestNG , vous pouvez utiliser la bibliothèque javaassist et IMethodInterceptor de TestNG pour prioriser les tests selon l'ordre dans lequel les méthodes de test sont définies dans la classe de test. Ceci est basé sur la solution fournie here.

Ajouter cet écouteur à votre classe de test:

package cs.jacob.listeners; 

import java.util.Arrays; 
import java.util.Comparator; 
import java.util.List; 

import javassist.ClassPool; 
import javassist.CtClass; 
import javassist.CtMethod; 
import javassist.NotFoundException; 

import org.testng.IMethodInstance; 
import org.testng.IMethodInterceptor; 
import org.testng.ITestContext; 

public class PriorityInterceptor implements IMethodInterceptor { 
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) { 

    Comparator<IMethodInstance> comparator = new Comparator<IMethodInstance>() { 
     private int getLineNo(IMethodInstance mi) { 
     int result = 0; 

     String methodName = mi.getMethod().getConstructorOrMethod().getMethod().getName(); 
     String className = mi.getMethod().getConstructorOrMethod().getDeclaringClass().getCanonicalName(); 
     ClassPool pool = ClassPool.getDefault(); 

     try { 
      CtClass cc  = pool.get(className); 
      CtMethod ctMethod = cc.getDeclaredMethod(methodName); 
      result   = ctMethod.getMethodInfo().getLineNumber(0); 
     } catch (NotFoundException e) { 
      e.printStackTrace(); 
     } 

     return result; 
     } 

     public int compare(IMethodInstance m1, IMethodInstance m2) { 
     return getLineNo(m1) - getLineNo(m2); 
     } 
    }; 

    IMethodInstance[] array = methods.toArray(new IMethodInstance[methods.size()]); 
    Arrays.sort(array, comparator); 
    return Arrays.asList(array); 
    } 
} 

Ceci trouve essentiellement les numéros de ligne des méthodes et les trie par ordre croissant de leur numéro de ligne, à savoir l'ordre par lequel ils sont définis dans le classe.

+1

Celui-ci est la vraie solution si vous devez migrer quelques centaines de tests de junit – realcnbs

1

En spécifiant les méthodes d'essai à exécuter en testNg.xml nous pouvons exécuter les cas de test dans souhaitée pour

<suite> 
 
<test name="selenium1"> 
 
    \t \t <classes> 
 
\t \t \t <class name="com.test.SeleniumTest" > 
 
\t \t \t  <methods><include name="methodB"></include> 
 
\t \t \t   <include name="methodA"></include> 
 
\t \t \t  </methods>  
 
\t \t \t </class> 
 
\t \t </classes> 
 
    
 
\t </test> 
 
</suite>

1

L'ordre des méthodes dans le fichier de classe est imprévisible, vous besoin d'utiliser des dépendances ou d'inclure vos méthodes explicitement en XML. Par défaut, TestNG exécutera vos tests dans l'ordre dans lequel ils se trouvent dans le fichier XML. Par défaut, TestNG exécutera vos tests. Si vous voulez que les classes et méthodes répertoriées dans ce fichier à exécuter dans un ordre imprédictible, définissez l'attribut ordre préserver false

4

Utilisez ceci:

public class TestNG 
{ 
     @BeforeTest 
     public void setUp() 
     { 
        /*--Initialize broowsers--*/ 

     } 

     @Test(priority=0) 
     public void Login() 
     { 

     } 

     @Test(priority=2) 
     public void Logout() 
     { 

     } 

     @AfterTest 
     public void tearDown() 
     { 
       //--Close driver--// 

     } 

} 

Habituellement TestNG fournit nombre de annotations, nous pouvons utiliser @BeforeSuite, @BeforeTest, @BeforeClass pour initialiser les navigateurs/configuration.

Nous pouvons donner la priorité si vous avez écrit nombre de cas de test dans votre script et que vous voulez exécuter comme par priorité assignée puis utilisez: @Test(priority=0) à partir de 0,1,2,3 ....

Pendant ce temps nous pouvons grouper le nombre de cas de test et l'exécuter en groupant. A la fin comme la fermeture des navigateurs, nous pouvons utiliser @AfterTest, @AfterSuite, @AfterClass annotations.

1

J'ai rencontré le même problème, la raison possible est due à l'exécution parallèle de testng et la solution est d'ajouter l'option de priorité ou simplement mettre à jour preserve-order = "true" dans votre testng.xml.

<test name="Firefox Test" preserve-order="true"> 
+1

preserve-order = "true", est par défaut dans testng.xml et ne fonctionne que pour l'ordre que vous avez défini dans testng.xml seulement, donc la résolution de votre problème ne fait qu'ajouter la priorité à @Tests – Kiran

0

Si vous arrive d'utiliser des choses supplémentaires comme dependsOnMethods, vous pouvez définir l'ensemble du flux de @Test dans votre fichier testng.xml. AFAIK, l'ordre défini dans votre fichier XML de la suite (testng.xml) remplacera toutes les autres stratégies de commande.