J'ai trouvé l'utilisation correcte (ou du moins la documentation) de JUnit très déroutante. Cette question sert à la fois de référence future et de vraie question.
Si j'ai bien compris, il existe deux approches principales pour créer et exécuter un test JUnit:
Approche A (style JUnit 3): créez une classe qui étend TestCase et démarrez les méthodes de test avec le mot test
. Lors de l'exécution de la classe en tant que 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 (style JUnit 4): créez une classe «normale» et ajoutez une @Test
annotation à la méthode. Notez que vous ne devez 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);
}
}
Mélanger les deux ne semble pas être une bonne idée, voir par exemple cette question de stackoverflow :
Maintenant, mes questions:
- Quelle est l'approche préférée ou quand utiliseriez-vous l'une au lieu de l'autre?
- L'approche B permet de tester les exceptions en étendant l'annotation @Test comme dans
@Test(expected = ArithmeticException.class)
. Mais comment tester les exceptions lors de l'utilisation de l'approche A? Lorsque vous utilisez l'approche A, vous pouvez regrouper un certain nombre de classes de test dans une suite de tests 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 classe de test doit sous-classe TestCase). Quelle est la bonne façon de regrouper les tests pour l'approche B?
Edit: j'ai ajouté les versions JUnit aux deux approches
la source
extends TestCase
et ensuite chaque test annoté avec@Test
juste pour confondre les choses. :)Réponses:
La distinction est assez simple:
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)@Test
annotation est la manière introduite par JUnit 4En général, vous devez choisir le chemin de l'annotation, sauf si la compatibilité avec JUnit 3 (et / ou une version Java antérieure à Java 5) est nécessaire. La nouvelle méthode présente plusieurs avantages:
@Test
annotation est plus explicite et est plus facile à prendre en charge dans les outils (par exemple, il est facile de rechercher tous les tests de cette façon)@Before
/@BeforeClass
et@After
/@AfterClass
offrant plus de flexibilité@Rule
annotations sur des éléments tels queExpectedException
@Ignored
annotation@RunWith
Pour tester les exceptions attendues dans un JUnit 3,
TestCase
vous devez rendre le texte explicite.JUnit 5 a introduit un autre changement d'API, mais utilise toujours des annotations. La nouvelle
@Test
annotation estorg.junit.jupiter.api.Test
(l'ancienne "JUnit 4 l'étaitorg.junit.Test
), mais elle fonctionne à peu près de la même manière que celle de JUnit 4.la source
assertTrue(e.getMessage().contains("foo"))
pourrait être utile.expected
méthode vérifie uniquement le type.J'ai une préférence pour JUnit 4 (approche d'annotation) car je la trouve plus flexible.
Si vous souhaitez créer une suite de tests dans JUnit 4, vous devez créer une classe regroupant tous les tests comme ceci:
la source
Il y a une partie sans réponse à votre question, à savoir "Quelle est la bonne façon de regrouper les tests pour l'approche B?"
La réponse officielle est que vous annotez une classe avec un @RunWith (Suite.class), puis utilisez l'annotation @ Suite.SuiteClasses pour répertorier les classes. C'est ainsi que les développeurs JUnit le font (listant chaque classe dans une suite manuellement). À bien des égards, cette approche est une amélioration, en ce sens qu'il est trivial et intuitif d'ajouter des comportements avant et après suite (ajoutez simplement une méthode @BeforeClass et @AfterClass à la classe annotée avec @RunWith - bien mieux que l'ancien TestFixture ).
Cependant, il y a un pas en arrière, dans la mesure où les annotations ne vous permettent pas de créer dynamiquement la liste des classes, et contourner ce problème devient un peu laid. Vous devez sous-classer la classe Suite et créer dynamiquement le tableau de classes dans la sous-classe et le transmettre au constructeur Suite, mais c'est une solution incomplète dans la mesure où les autres sous-classes de Suite (telles que Catégories) ne fonctionnent pas avec elle et essentiellement ne prennent pas en charge la collection de classes de test dynamique.
la source
Vous devriez utiliser JUnit 4. C'est mieux.
De nombreux frameworks ont commencé à rendre obsolète la prise en charge de JUnit 3.8.
Ceci provient de la documentation de référence de Spring 3.0:
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.
la source
L'approche "préférée" serait d'utiliser des annotations qui ont été introduites depuis juin 4. Elles facilitent beaucoup de choses (voir votre deuxième question)
Vous pouvez utiliser un simple bloc try / catch pour cela:
la source