Comment rédiger un test unitaire?

135

J'ai une classe Java. Comment puis-je le tester unitaire ?


Dans mon cas, j'ai classe fait une somme binaire. Il prend deux byte[]tableaux, les additionne et retourne un nouveau tableau binaire.

Tsundoku
la source
7
Vous pouvez utiliser un outil comme jUnit et écrire des cas de test (méthodes de test) pour votre classe java. Appelez ensuite les tests jUnit dans le cadre du processus de construction (ant / maven). Utiliser jUnit n'est pas du tout difficile, le plus difficile est de proposer autant de scénarios de test auxquels vous pouvez penser afin de détecter les bogues tôt et souvent.
CoolBeans

Réponses:

133
  1. Définissez la sortie attendue et souhaitée pour un cas normal, avec une entrée correcte.

  2. Maintenant, implémentez le test en déclarant une classe, donnez-lui un nom (généralement quelque chose comme TestAddingModule), et ajoutez-y la méthode testAdd (c'est-à-dire comme celle ci-dessous):

    • Écrivez une méthode et au-dessus, ajoutez l'annotation @Test.
    • Dans la méthode, exécutez votre somme binaire et assertEquals(expectedVal,calculatedVal).
    • Testez votre méthode en l'exécutant (dans Eclipse, clic droit, sélectionnez Exécuter en tant que → Test JUnit).

      //for normal addition 
      @Test
      public void testAdd1Plus1() 
      {
          int x  = 1 ; int y = 1;
          assertEquals(2, myClass.add(x,y));
      }
  3. Ajoutez d'autres cas comme vous le souhaitez.

    • Vérifiez que votre somme binaire ne lève pas d'exception inattendue en cas de dépassement d'entier.
    • Vérifiez que votre méthode gère correctement les entrées Null (exemple ci-dessous).

      //if you are using 0 as default for null, make sure your class works in that case.
      @Test
      public void testAdd1Plus1() 
      {
          int y = 1;
          assertEquals(0, myClass.add(null,y));
      }
jayunit100
la source
1. La notation @Test est-elle requise? 2. pourquoi ne pas tester l'entrée nulle avec with assertNotNull? 3. où sont capturés les résultats des tests unitaires? comment les résultats sont-ils indiqués à l'utilisateur?
user137717
10
Oui, la @Testnotation est requise. Ceci est fait pour signaler au lanceur de test unitaire que cette méthode représente un test unitaire et doit être exécutée. Les méthodes qui ne sont pas annotées avec @Testne sont pas exécutées par le testeur.
Ali Shah Ahmed
pour le deuxième test - ne devrait-il pas ajouter un nullpour ysimplement vous donner y?
Ajuster le
Merci! Je veux savoir pourquoi il n'est pas nécessaire d'ajouter staticau modificateur de la méthode de test.
Liang Zhang
104

Je propose cet article pour IntelliJ et Eclipse .

Éclipse:

Pour faire un test unitaire pour votre projet, veuillez suivre ces étapes (j'utilise Eclipse pour écrire ce test):

1- Cliquez sur Nouveau -> Projet Java.

Créer un projet

2- Notez le nom de votre projet et cliquez sur Terminer.

Créer un projet

3- Faites un clic droit sur votre projet. Ensuite, cliquez sur Nouveau -> Classe.

Créer une classe

4- Notez le nom de votre classe et cliquez sur Terminer.

Créer une classe

Ensuite, terminez le cours comme ceci:

public class Math {
    int a, b;
    Math(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int add() {
        return a + b;
    }
}

5- Cliquez sur Fichier -> Nouveau -> Cas de test JUnit.

Créer un test JUnite

6- Cochez setUp () et cliquez sur Terminer. SetUp () sera l'endroit où vous initialiserez votre test.

Vérifier la configuration ()

7- Cliquez sur OK.

Ajouter JUnit

8- Ici, j'ajoute simplement 7 et 10. Donc, je m'attends à ce que la réponse soit 17. Complétez votre classe de test comme ceci:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MathTest {
    Math math;
    @Before
    public void setUp() throws Exception {
        math = new Math(7, 10);
    }
    @Test
    public void testAdd() {
        Assert.assertEquals(17, math.add());
    }
}

9- Écrivez, cliquez sur votre classe de test dans l'explorateur de packages et cliquez sur Exécuter en tant que -> JUnit Test.

Exécuter le test JUnit

10- C'est le résultat du test.

Résultat du test

IntelliJ: Notez que j'ai utilisé la communauté IntelliJ IDEA 2020.1 pour les captures d'écran. En outre, vous devez configurer votre jre avant ces étapes. J'utilise JDK 11.0.4.

1- Faites un clic droit sur le dossier principal de votre projet-> nouveau -> répertoire. Vous devriez appeler cela «test». entrez la description de l'image ici 2- Faites un clic droit sur le dossier de test et créez le package approprié. Je suggère de créer les mêmes noms d'emballage que la classe d'origine. Ensuite, vous cliquez avec le bouton droit sur le répertoire de test -> marquer le répertoire comme -> racine des sources de test. entrez la description de l'image ici 3- Dans le bon package dans le répertoire de test, vous devez créer une classe Java (je suggère d'utiliser Test.java). entrez la description de l'image ici 4- Dans la classe créée, saisissez '@Test'. Ensuite, parmi les options offertes par IntelliJ, sélectionnez Ajouter 'JUnitx' au chemin de classe. 5- Écrivez votre méthode de test dans votre classe de test. La signature de la méthode est comme:entrez la description de l'image ici entrez la description de l'image ici

@Test
public void test<name of original method>(){
...
}

Vous pouvez faire vos affirmations comme ci-dessous:

Assertions.assertTrue(f.flipEquiv(node1_1, node2_1));

Voici les importations que j'ai ajoutées:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

entrez la description de l'image ici

C'est le test que j'ai écrit: entrez la description de l'image ici

Vous pouvez vérifier vos méthodes comme ci-dessous:

Assertions.assertEquals(<Expected>,<actual>);
Assertions.assertTrue(<actual>);
...

Pour exécuter vos tests unitaires, faites un clic droit sur le test et cliquez sur Exécuter. entrez la description de l'image ici

Si votre test réussit, le résultat sera comme ci-dessous: entrez la description de l'image ici

J'espère que cela aide. Vous pouvez voir la structure du projet dans GitHub https://github.com/m-vahidalizadeh/problem_solving_project .

Mohammad
la source
12
Aimez votre réponse, c'est le meilleur "comment faire"!
alisa le
4
Je suis heureux que ma réponse ait été utile. Merci pour votre commentaire.
Mohammad le
1
Voici à quoi devraient ressembler les tutoriels; exemple propre, concis et complet. Très bien.
Jack Of Blades
1
Merci beaucoup Jack. Je suis heureux que vous l'ayez trouvé utile.
Mohammad le
18

C'est une question très générique et il y a de nombreuses façons d'y répondre.

Si vous souhaitez utiliser JUnit pour créer les tests, vous devez créer votre classe de cas de test, puis créer des méthodes de test individuelles qui testent des fonctionnalités spécifiques de votre classe / module sous tests (les classes de cas de test uniques sont généralement associées à une seule classe de "production" qui est en cours de test) et à l'intérieur de ces méthodes, exécutez diverses opérations et comparez les résultats avec ce qui serait correct. Il est particulièrement important d'essayer de couvrir autant de caisses d'angle que possible.

Dans votre exemple spécifique, vous pouvez par exemple tester les éléments suivants:

  1. Une simple addition entre deux nombres positifs. Ajoutez-les, puis vérifiez que le résultat correspond à ce que vous attendez.
  2. Une addition entre un nombre positif et négatif (qui renvoie un résultat avec le signe du premier argument).
  3. Une addition entre un nombre positif et négatif (qui renvoie un résultat avec le signe du deuxième argument).
  4. Une addition entre deux nombres négatifs.
  5. Un ajout qui entraîne un débordement.

Pour vérifier les résultats, vous pouvez utiliser diverses méthodes assertXXX de la classe org.junit.Assert (pour plus de commodité, vous pouvez faire 'import static org.junit.Assert. *'). Ces méthodes testent une condition particulière et échouent au test si elle ne valide pas (avec un message spécifique, éventuellement).

Exemple de classe de cas de test dans votre cas (sans le contenu des méthodes défini):

import static org.junit.Assert.*;

public class AdditionTests {
    @Test
    public void testSimpleAddition() { ... }


    @Test
    public void testPositiveNegativeAddition() { ... }


    @Test
    public void testNegativePositiveAddition() { ... }


    @Test
    public void testNegativeAddition() { ... }


    @Test
    public void testOverflow() { ... }
}

Si vous n'êtes pas habitué à écrire des tests unitaires mais que vous testez votre code en écrivant des tests ad-hoc que vous validez ensuite «visuellement» (par exemple, vous écrivez une méthode principale simple qui accepte les arguments saisis à l'aide du clavier puis imprime les résultats - puis vous continuez à saisir des valeurs et à vous valider vous-même si les résultats sont corrects), alors vous pouvez commencer par écrire ces tests dans le format ci-dessus et valider les résultats avec la méthode assertXXX correcte au lieu de le faire manuellement. De cette façon, vous pouvez réexécuter le test beaucoup plus facilement que si vous deviez faire des tests manuels.

Seramme
la source
8

Comme @CoolBeans mentionné, jetez un œil à jUnit . Voici un petit tutoriel pour vous aider à démarrer également avec jUnit 4.x

Enfin, si vous voulez vraiment en savoir plus sur les tests et le développement piloté par les tests (TDD), je vous recommande de consulter le livre suivant de Kent Beck: Test-Driven Development By Example .

Vladmore
la source
6

D'autres réponses vous ont montré comment utiliser JUnit pour configurer des classes de test. JUnit n'est pas le seul framework de test Java. Cependant, se concentrer sur les détails techniques de l'utilisation d'un cadre nuit aux concepts les plus importants qui devraient guider vos actions, je vais donc en parler.

  • Le test (de toutes sortes de toutes sortes de choses) compare le comportement réel de quelque chose (le système sous test, SUT) avec son comportement attendu .

  • Les tests automatisés peuvent être effectués à l'aide d'un programme informatique. Parce que cette comparaison est effectuée par un programme informatique inflexible et peu intelligent, le comportement attendu doit être connu avec précision et sans ambiguïté.

  • Ce qu'un programme ou une partie de programme (une classe ou une méthode) est censé faire est sa spécification . Le logiciel de test nécessite donc que vous ayez une spécification pour le SUT. Cela peut être une description explicite ou une spécification implicite dans votre tête de ce qui est attendu.

  • Les tests unitaires automatisés nécessitent donc une spécification précise et sans ambiguïté de la classe ou de la méthode que vous testez.

  • Mais vous aviez besoin de cette spécification lorsque vous avez décidé d'écrire ce code. Ainsi, une partie de ce que sont les tests commence réellement avant que vous n'écriviez ne serait-ce qu'une seule ligne du SUT. La technique de test de Test Driven Development (TDD) pousse cette idée à l'extrême et vous demande de créer le code de test unitaire avant d'écrire le code à tester.

  • Les frameworks de tests unitaires testent votre SUT à l'aide d' assertions . Une assertion est une expression logique (une expression avec un booleantype de résultat; un prédicat ) qui doit être truesi le SUT se comporte correctement. La spécification doit donc être exprimée (ou ré-exprimée) sous forme d'assertions.

  • Une technique utile pour exprimer une spécification sous forme d'assertions est la programmation par contrat . Ces spécifications sont en termes de postconditions . Une postcondition est une assertion sur l'état publiquement visible du SUT après le retour d'une méthode ou d'un constructeur. Certaines méthodes ont des postconditions qui sont des invariants , qui sont des prédicats qui sont vrais avant et après l'exécution de la méthode. On peut également dire qu'une classe a des invariants, qui sont des postconditions de chaque constructeur et méthode de la classe, et devraient donc toujours être vraies. Les postconditions (et invariants) ne sont exprimées qu'en termes d'état visible de publicité:public et protectedchamps, les valeurs renvoyées parpublicet lesprotected méthodes (telles que les getters) et l'état publiquement visible des objets passés (par référence) aux méthodes.


De nombreux débutants postent ici des questions demandant comment ils peuvent tester du code, en présentant le code mais sans indiquer les spécifications de ce code. Comme le montre cette discussion, il est impossible pour quiconque de donner une bonne réponse à une telle question, car au mieux les répondants potentiels doivent deviner la spécification, et pourraient le faire de manière incorrecte. Le demandeur de la question ne comprend évidemment pas l'importance d'une spécification, et est donc un novice qui a besoin de comprendre les principes fondamentaux que j'ai décrits ici avant d' essayer d'écrire du code de test.

Raedwald
la source