39 votes

La spécification d'une commande à junit 4 tests au niveau de la Méthode (pas le niveau de la classe)

Je sais que c'est une mauvaise pratique, mais il doit être fait, ou je vais avoir besoin de passer à testng. Est-il un moyen, similaire à JUnit 3 testSuite, pour spécifier l'ordre des tests à exécuter dans une classe?

Merci pour l'aide!

62voto

Michael D Points 1572

Si vous êtes sûr de vraiment vouloir faire cela: Il peut y avoir une meilleure façon, mais c'est tout ce que je pouvais trouver...

JUnit4 a une annotation: @RunWith qui vous permet de remplacer la valeur par défaut Runner pour vos tests.

Dans votre cas, vous voulez créer une sous-classe spéciale de BlockJunit4ClassRunner, et remplacer computeTestMethods() pour renvoyer les tests dans l'ordre que vous désirez exécuter. Par exemple, disons que je veux l'exécution de mes tests dans l'ordre alphabétique inverse:

public class OrderedRunner extends BlockJUnit4ClassRunner {

    public OrderedRunner(Class klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected List computeTestMethods() {
        List list = super.computeTestMethods();
        List copy = new ArrayList(list);
        Collections.sort(copy, new Comparator() {
            public int compare(FrameworkMethod o1, FrameworkMethod o2) {
                return o2.getName().compareTo(o1.getName());
            }
        });
        return copy;
    }
}
@RunWith(OrderedRunner.class)
public class OrderOfTest {
    @Test public void testA() { System.out.println("A"); }
    @Test public void testC() { System.out.println("C"); }
    @Test public void testB() { System.out.println("B"); }
}

L'exécution de ce test produit:

C
B
Un

Pour votre cas particulier, vous souhaitez un comparateur qui permettrait de trier les tests par nom dans l'ordre que vous désirez exécuter. (Je suggère de définir le comparateur en utilisant quelque chose comme Google Goyave classe de la Commande.explicite("methodName1","methodName2").onResultOf(...); où onResultOf est pourvu d'une fonction qui convertit les FrameworkMethod à son nom... même si évidemment, vous êtes libre de mettre en oeuvre que de la manière que vous voulez.

62voto

joscarsson Points 1567

Je vois plusieurs raisons pour le faire, surtout lors de l'utilisation de JUnit pour exécuter des tests fonctionnels ou de tester des objets persistants. Par exemple, considérons un objet Article qui est conservé à un certain type de stockage persistant. Si je voudrais tester l'insérer, mettre à jour et supprimer des fonctionnalités Article objet de la suite de l'unité de principe de l'essai "tous les tests doivent être réorganisables et test d'une partie de la fonctionnalité", j'aurais trois tests:

  • testInsertArticle()
  • testUpdateArticle()
  • testDeleteArticle()

Cependant, pour être en mesure de tester la fonctionnalité de mise à jour, j'ai d'abord besoin d'insérer l'article. Pour tester les fonctionnalités de suppression, j'aurais aussi besoin d'insérer un article. Donc, dans la pratique, l'insertion de la fonctionnalité est déjà testé les deux en testUpdateArticle() et testDeleteArticle(). Il est alors tentant de simplement créer une méthode de test testArticleFunctionality() qui fait tout, mais des méthodes comme ça finira par être énorme (et ils ne seront pas simplement partie de test de la fonctionnalité de l' Article objet).

Il en va de même pour l'exécution de tests fonctionnels de contre par exemple une API restful. JUnit est idéal aussi pour ces cas, si ce n'était pas pour le undeterministic la commande de tests.

Cela dit, j'ai étendu Michael D - OrderedRunner d'utiliser des annotations afin de déterminer l'ordre des tests, juste pensé que je devais partager. Il peut être étendu, par exemple en spécifiant exactement qui teste chaque test dépend, mais c'est ce que j'utilise pour l'instant.

C'est la façon dont il est utilisé. Il évite la nécessité pour le nommage des tests comme AA_testInsert(), AB_testUpdate(), AC_testDelete(), ..., ZC_testFilter(), etc.

@RunWith(OrderedRunner.class)
public class SomethingTest {
    @Test
    @Order(order=2)
    public void testUpdateArticle() {
        // test update
    }

    @Test
    @Order(order=1)
    public void testInsertArticle() {
        // test insert
    }

    @Test
    @Order(order=3)
    public void testDeleteArticle() {
        // test delete
    }
}

Peu importe comment ces tests sont placés dans le fichier, ils seront toujours exécuter en tant qu' order=1 tout d'abord, order=2 deuxième et dernier order=3, peu importe si vous les exécutez à partir de l'intérieur de l'Éclipse, à l'aide de la Fourmi, ou de toute autre manière.

La mise en œuvre de la façon suivante. Tout d'abord, l'annotation Order.

@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
    public int order();
}

Ensuite, la modification de OrderedRunner.

public class OrderedRunner extends BlockJUnit4ClassRunner {
    public OrderedRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        List<FrameworkMethod> list = super.computeTestMethods();
        Collections.sort(list, 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 list;
    }
}

26voto

Shiva Kumar Points 1410

JUnit version 4.11-delà, il est possible de modifier l'ordre d'exécution des tests en annotant votre classe avec des @FixMethodOrder et la spécification de l' MethodSorters. Voir ce lien pour plus de détails.

4voto

Philippe Blayo Points 1582

Dans junit 4.11 la nouvelle annotation @FixMethodOrder permet de définir un ordre spécifique:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)

1voto

kornero Points 721

Si vous souhaitez exécuter des tests junit dans l'ordre", comme ils présents dans votre code source", et ne souhaitez pas modifier vos tests de code, voir ma note à ce sujet ici:

Comment faire pour exécuter junit tests afin présents dans votre code source

Mais c'est vraiment pas une bonne idée, les essais doivent être indépendants.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X