167 votes

JUnit confusion: utilisez 'extend testcase' ou '@Test'?

J'ai trouvé le bon usage (ou au moins de la documentation) de JUnit très déroutant. Cette question sert à la fois comme une future référence et une véritable question.

Si j'ai bien compris, il y a deux approches principales pour créer et exécuter un test JUnit:

À l'approche d'Un (JUnit 3-style): créer une classe qui étend la classe TestCase, et de commencer des méthodes d'essai avec le mot - test. Lors de l'exécution de la classe de Test JUnit (dans Eclipse), toutes les méthodes commençant par le mot - test sont automatiquement exécutées.

import junit.framework.TestCase;
public class DummyTestA extends TestCase {

    public void testSum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

Approche B (JUnit 4-style): créer un niveau "normal" de la classe et ajouter un @Test d'annotation à la méthode. Notez que vous n'avez PAS à démarrer la méthode avec le mot - test.

import org.junit.*;
import static org.junit.Assert.*;

public class DummyTestB {

    @Test
    public void Sum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

Le mélange des deux ne semble pas être une bonne idée, voir, par exemple, ce stackoverflow question:

Maintenant, mes questions(s):

  1. Qu'est-ce que l'approche privilégiée, ou quand voulez-vous utiliser l'un plutôt que l'autre?
  2. Approche B permet de tester des exceptions par l'extension de l'annotation @Test comme en @Test(expected = ArithmeticException.class). Mais comment faites-vous tester pour les exceptions lors de l'utilisation de l'approche d'Un?
  3. Lors de l'utilisation de l'approche d'Un, vous pouvez regrouper un certain nombre de classes de test dans une suite de test comme ceci:

    TestSuite suite = new TestSuite("All tests");
    suite.addTestSuite(DummyTestA.class);
    suite.addTestSuite(DummyTestAbis.class);

    Mais cela ne peut pas être utilisé avec l'approche B (puisque chaque testclass devrait sous-classe TestCase). Quelle est la bonne façon pour un groupe de tests pour l'approche B?

Edit: j'ai ajouté la JUnit versions pour les deux approches

128voto

Joachim Sauer Points 133411

La distinction est assez facile:

  • s'étendant TestCase est la façon dont les tests unitaires ont été écrits dans JUnit 3 (bien sûr, il est toujours pris en charge dans JUnit 4)
  • à l'aide de l' @Test d'annotation est le moyen présenté par JUnit 4

En général, vous devez choisir l'annotation chemin, à moins que la compatibilité avec JUnit 3 (et/ou Java version antérieure à la version de Java 5) est nécessaire pour plusieurs raisons:

  • L' @Test annotaton est plus explicite, et est plus facile à supporter dans les outils (par exemple, il est facile de rechercher tous les tests de cette façon)
  • Plusieurs méthodes peuvent être annotées avec @Before/@BeforeClass et @After/@AfterClass offrant plus de flexibilité
  • Prise en charge intégrée pour les tests d'exceptions à l'aide de expected=
  • Soutien pour l' @Ignored d'annotation

Pour tester prévu des exceptions dans un JUnit 3 TestCase , vous auriez à rendre le texte plus explicite.

public void testMyException() {
  try {
    objectUnderTest.myMethod(EVIL_ARGUMENT);
    fail("myMethod did not throw an Exception!");
  } catch (MyException e) {
    // ok!
    // check for properties of exception here, if desired
  }
}

25voto

Grimmy Points 581

J'ai une préférence pour JUnit 4 (approche d'annotation) car je le trouve plus flexible.

Si vous voulez construire une suite de tests dans JUnit 4, vous devez créer une classe regroupant tous les tests comme celui-ci:

 import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;


@RunWith(Suite.class)
@SuiteClasses({
    Test1.class,
    Test2.class,
    Test3.class,
    Test4.class
})public class TestSuite
{
 /* empty class */
}
 

15voto

Yishai Points 42417

Il n'y est une réponse à votre question, et c'est "Quelle est la bonne façon pour un groupe de tests pour l'approche B?"

La réponse officielle est que vous annoter une classe avec une annotation @RunWith(Suite.class), puis utilisez le @Suite.SuiteClasses annotation de la liste des classes. C'est de cette façon JUnit développeurs de le faire (la liste de tous les classe dans une suite manuellement). Dans de nombreux égards, cette approche est une amélioration, en ce que c'est facile et intuitive pour ajouter avant la suite et après une suite de comportements (il suffit d'ajouter @BeforeClass et @AfterClass méthode de la classe annotée avec l'annotation @RunWith - beaucoup mieux que l'ancienne TestFixture).

Toutefois, il possède un pas en arrière, que les annotations ne vous permettra pas de créer dynamiquement la liste des classes, et de travailler autour de ce problème est un peu moche. Vous avez à la sous-classe la Suite de la classe et de créer dynamiquement le tableau de classes dans la sous-classe et de passer à la Suite du constructeur, mais c'est une solution incomplète dans d'autres sous-classes de la Suite (telles que les Catégories ne fonctionnent pas avec elle et ne sont pas essentiellement le soutien à l'Essai dynamique de la classe collection.

4voto

Espen Points 5898

Vous devriez utiliser JUnit 4. C'est mieux.

De nombreux frameworks ont commencé à déprécier le support de JUnit 3.8.

Ceci est tiré de la documentation de référence Spring 3.0:

[Avertissement] L'ancienne hiérarchie de classes JUnit 3.8 est obsolète

En général, vous devriez toujours essayer d'utiliser la dernière version stable d'un framework lorsque vous démarrez quelque chose de nouveau.

1voto

black666 Points 882
  1. L’approche "préférée" consisterait à utiliser les annotations introduites depuis Junit 4. Elles facilitent beaucoup de choses (voir votre deuxième question)

  2. Vous pouvez utiliser un simple bloc try / catch pour cela:

 
public void testForException() {
    try {
        Integer.parseInt("just a string");
        fail("Exception should have been thrown");
    } catch (final Exception e) {
        // expected
    }
}
 

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