Comment exécuter les méthodes d'essai dans un ordre précis en Juin4?

je veux exécuter des méthodes d'essai qui sont annotées par @Test dans un ordre spécifique.

par exemple:

public class MyTest {
    @Test public void test1(){}
    @Test public void test2(){}
}

je veux m'assurer d'exécuter test1() avant test2() chaque fois que j'exécute MyTest , mais je n'ai pas pu trouver d'annotation comme @Test(order=xx) .

je pense que C'est une caractéristique très importante pour JUnit, si l'auteur de JUnit ne veut pas la fonction de commande , pourquoi?

352
demandé sur ROMANIA_engineer 2010-09-12 07:35:26

16 réponses

je pense que C'est très important pour JUnit, si l'auteur de JUnit ne veut pas la fonctionnalité de commande, pourquoi?

Je ne suis pas sûr qu'il y ait un moyen propre de le faire avec JUnit, à ma connaissance JUnit suppose que tous les tests peuvent être effectués dans un ordre arbitraire. De la FAQ:

comment utiliser un montage d'essai?

(...) La commande de test-méthode invocations est non garanti , donc testOneItemCollection() pourrait être exécuté avant testEmptyCollection(). (...)

pourquoi? Eh bien, je crois que faire des tests dépendant de l'ordre est une pratique que les auteurs ne veulent pas promouvoir. Les Tests doivent être indépendants, ils ne doivent pas être couplés et la violation de ce will rendre les choses plus difficile à maintenir, va briser la capacité de courir essais individuels (évidemment), etc.

cela dit, si vous voulez vraiment aller dans cette direction, envisagez D'utiliser TestNG car il supporte l'exécution des méthodes de tests dans un ordre arbitraire nativement (et des choses comme spécifier que les méthodes dépendent de groupes de méthodes). Cedric Beust explique comment procéder dans ordre d'exécution des essais dans .

207
répondu Pascal Thivent 2017-05-23 11:47:29

si vous vous débarrassez de votre instance existante de Junit, et téléchargez JUnit 4.11 ou plus dans le chemin de construction, le code suivant exécutera les méthodes de test dans l'ordre de leurs noms, triés dans l'ordre ascendant:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {

    @Test
    public void testAcreate() {
        System.out.println("first");
    }
    @Test
    public void testBupdate() {
        System.out.println("second");
    }
    @Test
    public void testCdelete() {
        System.out.println("third");
    }
}
60
répondu Aniket Kulkarni 2015-02-19 01:06:04

Si l'ordre est important, vous devez faire vous-même.

@Test public void test1() { ... }
@Test public void test2() { test1(); ... }

en particulier, vous devriez énumérer quelques-unes ou toutes les permutations d'ordre possibles à tester, si nécessaire.

par exemple,

void test1(); 
void test2(); 
void test3(); 


@Test
public void testOrder1() { test1(); test3(); }

@Test(expected = Exception.class)
public void testOrder2() { test2(); test3(); test1(); }

@Test(expected = NullPointerException.class)
public void testOrder3() { test3(); test1(); test2(); }

Ou, un test complet de toutes les permutations:

@Test
public void testAllOrders() {
    for (Object[] sample: permute(1, 2, 3)) {
        for (Object index: sample) {
            switch (((Integer) index).intValue()) {
                case 1: test1(); break; 
                case 2: test2(); break; 
                case 3: test3(); break; 
            }
        }
    }
}

ici, permute() est une fonction simple qui itère toutes les permuations possibles dans une Collection de tableaux.

49
répondu Xiè Jìléi 2011-01-16 08:30:22

la Migration vers TestNG semble la meilleure solution, mais je ne vois pas de solution claire ici pour jUnit. Voici la plupart solution lisible / formatage j'ai trouvé pour jUnit:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
    @Test
    void stage1_prepareAndTest(){};

    @Test
    void stage2_checkSomething(){};

    @Test
    void stage2_checkSomethingElse(){};

    @Test
    void stage3_thisDependsOnStage2(){};

    @Test
    void callTimeDoesntMatter(){}
}

cela garantit que les méthodes stage2 sont appelées après les méthodes stage1 et avant les méthodes stage3.

32
répondu joro 2017-01-11 14:20:09

C'est l'un des principaux problèmes que j'ai rencontré lorsque J'ai travaillé sur Junit et j'ai trouvé la solution suivante qui fonctionne très bien pour moi:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;

public class OrderedRunner extends BlockJUnit4ClassRunner {

    public OrderedRunner(Class<?> clazz) throws InitializationError {
        super(clazz);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        List<FrameworkMethod> list = super.computeTestMethods();
        List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
        Collections.sort(copy, new Comparator<FrameworkMethod>() {

            @Override
            public int compare(FrameworkMethod f1, FrameworkMethod f2) {
                Order o1 = f1.getAnnotation(Order.class);
                Order o2 = f2.getAnnotation(Order.class);

                if (o1 == null || o2 == null) {
                    return -1;
                }

                return o1.order() - o2.order();
            }
        });
        return copy;
    }
}

crée aussi une interface comme ci-dessous:

 @Retention(RetentionPolicy.RUNTIME)


@Target({ ElementType.METHOD})

public @interface Order {
public int order();
}

supposons maintenant que vous avez la classe A où vous avez écrit plusieurs cas de test comme ci-dessous:

(@runWith=OrderRunner.class)
Class A{
@Test
@Order(order = 1)

void method(){

//do something

}

}

ainsi l'exécution commencera à partir de la méthode nommée"method ()". Merci!

14
répondu Aman Goel 2016-11-27 04:21:47

(encore inédit) changement https://github.com/junit-team/junit/pull/386 introduit un @SortMethodsWith . https://github.com/junit-team/junit/pull/293 au moins a rendu l'ordre prévisible sans cela (en Java 7 Il peut être tout à fait aléatoire).

8
répondu Jesse Glick 2013-11-14 20:43:04

regardez un rapport de JUnit. JUnit est déjà organisé par package. Chaque paquet A (ou peut avoir) des classes TestSuite, chacune d'entre elles exécutant à son tour plusieurs TestCases. Chaque TestCase peut avoir plusieurs méthodes de test du formulaire public void test*() , dont chacune deviendra en fait une instance de la classe TestCase à laquelle elles appartiennent. Chaque méthode d'essai (instance de TestCase) a un nom et un critère de réussite/échec.

ce que ma gestion exige est le concept de l'individu test-step items, dont chacun indique ses propres critères de réussite ou d'échec. L'échec d'une étape d'essai ne doit pas empêcher l'exécution d'autres étapes d'essai.

dans le passé, les développeurs de test dans ma position ont organisé des classes de TestCase dans des paquets qui correspondent à la(AUX) partie (s) du produit à l'essai, créé une classe de TestCase pour chaque test, et fait chaque méthode d'essai une "étape" séparée dans le test, complète avec ses propres critères de réussite / échec dans le JUnit sortie. Chaque cas D'essai est un "essai" autonome, mais les différentes méthodes, ou les "étapes" d'essai dans le cas D'essai, doivent se produire dans un ordre spécifique.

les méthodes D'essai étaient les étapes de L'essai, et les concepteurs de l'essai ont obtenu un critère de réussite/échec distinct pour chaque étape de l'essai. Maintenant, les étapes des tests sont mélangées, et les tests (bien sûr) échouent.

par exemple:

Class testStateChanges extends TestCase

public void testCreateObjectPlacesTheObjectInStateA()
public void testTransitionToStateBAndValidateStateB()
public void testTransitionToStateCAndValidateStateC()
public void testTryToDeleteObjectinStateCAndValidateObjectStillExists()
public void testTransitionToStateAAndValidateStateA()
public void testDeleteObjectInStateAAndObjectDoesNotExist()
public void cleanupIfAnythingWentWrong()

chaque méthode d'essai affirme et rapporte ses propres critères réussite / échec. Le fait de regrouper cela en "une grande méthode de test" pour le plaisir de commander perd la granularité des critères réussite/échec de chaque "étape" dans le rapport de synthèse de JUnit. ...et ça dérange mes chefs. Ils réclament actuellement une autre solution.

est-ce que quelqu'un peut expliquer comment un JUnit avec un ordre de méthode d'essai brouillé supporterait des critères distincts de réussite/échec de chaque étape d'essai séquentielle, comme illustré ci-dessus et exigé par ma direction?

indépendamment de la documentation, je vois cela comme une régression sérieuse dans le cadre de JUnit qui rend la vie difficile pour beaucoup de développeurs de test.

6
répondu Anonymous Developer 2016-08-24 19:00:29

ce que vous voulez est parfaitement raisonnable lorsque les cas de test sont exécutés comme une suite.

malheureusement pas le temps de donner une solution complète en ce moment, mais jeter un oeil à la classe:

org.junit.runners.Suite

qui vous permet d'appeler des cas de test (de n'importe quelle classe de test) dans un ordre spécifique.

ceux-ci peuvent être utilisés pour créer des tests fonctionnels, d'intégration ou de système.

cela laisse vos tests unitaires comme ils sont sans ordre précis (tel que recommandé), que vous les exécutiez comme cela ou non, et puis réutiliser les tests dans le cadre d'une vue d'ensemble.

nous réutilisons/héritons le même code pour les tests d'unité, d'intégration et de système, parfois basé sur des données, parfois basé sur des commits, et parfois exécuté comme une suite.

3
répondu CharlieS 2014-08-27 00:58:21

Je ne suis pas sûr d'être d'accord, si je veux tester 'File Upload' et ensuite tester 'les données insérées par File Upload' pourquoi ne voudrais-je pas que ceux-ci soient indépendants les uns des autres? Je pense qu'il est tout à fait raisonnable de pouvoir les exécuter séparément plutôt que d'avoir les deux dans un cas de test Goliath.

3
répondu Mattk 2015-03-19 12:11:44

voir ma solution ici: "Junit et java 7."

dans cet article, je décris comment exécuter des tests junit dans l'ordre - "comme dans votre code source". Les Tests seront exécutés, dans l'ordre où vos méthodes de test apparaissent dans le fichier de classe.

http://intellijava.blogspot.com/2012/05/junit-and-java-7.html

mais comme L'a dit Pascal Thivent, ce n'est pas une bonne pratique.

2
répondu kornero 2012-12-05 10:12:22

j'ai lu quelques réponses et je suis d'accord que ce n'est pas la meilleure pratique, mais la façon la plus facile de commander vos tests - et la façon dont JUnit exécute les tests par défaut est par nom alphabétique Ascendant.

alors nommez vos tests dans l'ordre alphabétique que vous voulez. Notez également que le nom du test doit commencer avec le mot test. Il suffit de faire attention aux numéros

l'essai12 sera effectué avant l'essai2

:

testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond

1
répondu pstorli 2014-03-10 20:01:20

s'il vous Plaît vérifier celui-ci: https://github.com/TransparentMarket/junit . Il exécute le test dans l'ordre où il est spécifié (défini dans le fichier de classe compilé). En outre, il dispose d'une suite AllTests pour exécuter des tests définis par le sous-paquet en premier. En utilisant L'implémentation AllTests, on peut étendre la solution en filtrant également les propriétés (nous utilisions auparavant @Fast annotations mais celles-ci n'étaient pas encore publiées).

0
répondu Martin Kersten 2015-04-30 14:20:01

voici une extension à JUnit qui peut produire le comportement désiré: https://github.com/aafuks/aaf-junit

je sais que c'est contre les auteurs de la philosophie JUnit, mais en utilisant JUnit dans des environnements qui ne sont pas des tests unitaires stricts (comme pratiqué en Java) cela peut être très utile.

0
répondu shlomi33 2016-04-25 15:28:02

j'ai fini ici en pensant que mes tests n'étaient pas en ordre, mais la vérité est que la pagaille était dans mes emplois asynchrones. Lorsque vous travaillez avec la simultanéité, vous devez également effectuer des contrôles de simultanéité entre vos tests. Dans mon cas, les travaux et les tests partagent un sémaphore, donc les prochains tests sont suspendus jusqu'à ce que le travail en cours libère la serrure.

je sais que ce n'est pas entièrement lié à cette question, mais peut-être pourrait aider à cibler la bonne question

0
répondu McCoy 2017-11-01 15:44:06

vous pouvez utiliser un de ces codes:

@FixMethodOrder(MethodSorters.JVM)OR `@FixMethodOrder(MethodSorters.DEFAULT)` OR `@FixMethodOrder(MethodSorters.NAME_ASCENDING)` before your test class like this:


@FixMethodOrder(MethodSorters.NAME_ASCENDING)


public class BookTest { ...}
0
répondu Arezoo Bagherzadi 2018-08-04 11:41:37

JUnit permet actuellement aux méthodes d'essai d'exécuter l'ordre en utilisant les annotations de classe:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FixMethodOrder(MethodSorters.JVM)
@FixMethodOrder(MethodSorters.DEFAULT)

pour définir l'ordre des méthodes vous pouvez les nommer comme:

a_testworkunit_withcertainstate_shoulddos something b_testWorkUnit_WithCertainState_shoulddosomething c_testworkunit_withcertainstate_devrait_dépasser

vous pouvez trouver exemples ici .

0
répondu Zon 2018-08-22 09:15:34