web-dev-qa-db-fra.com

Pourquoi utiliser JUnit pour tester?

Peut-être que ma question est novice, mais je ne peux pas vraiment comprendre les circonstances dans lesquelles je voudrais utiliser junit ?

Que ce soit pour des applications simples ou des applications plus grandes, je les teste avec le System.out _ déclarations et cela me semble assez facile.

Pourquoi créer des classes de test avec JUnit, des dossiers inutiles dans le projet si nous devons toujours appeler les mêmes méthodes, vérifier ce qu’elles renvoient et avoir ensuite une surcharge d’annoter tout?

Pourquoi ne pas écrire un cours et le tester immédiatement avec System.out mais pas créer des classes de test?

PS Je n'ai jamais travaillé sur de grands projets que je viens d'apprendre.

Alors, quel est le but?

130
Artem Moskalev

Ce n'est pas un test, c'est "regarder manuellement la sortie" (connue dans le biz comme LMAO). Plus officiellement, on parle de "recherche manuelle d'une sortie anormale" (LMFAO). (Voir note ci-dessous)

Chaque fois que vous modifiez le code, vous devez exécuter l'application et LMFAO pour tout le code concerné par ces modifications. Même dans les petits projets, c'est problématique et sujet aux erreurs.

Passez maintenant à 50k, 250k, 1m de LOC ou plus, et à LMFAO chaque fois que vous modifiez un code. C'est non seulement désagréable, mais impossible: vous avez étendu les combinaisons d'entrées, de sorties, de drapeaux, de conditions et il est difficile d'exercer toutes les branches possibles.

Pire encore, LMFAO peut signifier visiter des pages d’application Web, générer des rapports, parcourir des millions de lignes de journal sur des dizaines de fichiers et de machines, lire des courriels générés et livrés, vérifier les messages texte, vérifier le chemin d’un robot soda, agréger les données d’une centaine de services Web, consulter le journal d’audit d’une transaction financière ... vous voyez l’idée. "Sortie" ne signifie pas quelques lignes de texte, "sortie" signifie le comportement du système dans son ensemble.

Enfin, les tests unitaires et de comportement define comportement du système. Les tests peuvent être exécutés par un serveur d'intégration continue et leur exactitude vérifiée. Bien sûr, il en va de même pour System.out, Mais le serveur CI ne saura pas si l’un d’eux est mauvais. Si tel est le cas, ce sont des tests unitaires et vous pourriez aussi bien utiliser un framework.

Peu importe à quel point nous pensons être bons, les humains ne sont pas de bons frameworks de tests unitaires ni de serveurs CI.


Remarque: LMAO est test, mais dans un sens très limité. Il n'est pas reproductible de manière significative dans l'ensemble d'un projet ou dans le cadre d'un processus. Cela revient à développer progressivement dans un REPL, sans jamais formaliser ces tests incrémentiels.

133
Dave Newton

Nous écrivons des tests pour vérifier l'exactitude du comportement d'un programme.

Vérification de l'exactitude du comportement d'un programme en inspectant le contenu des instructions de sortie à l'aide de vos yeux est un manuel, ou plus spécifiquement, un processus visuel.

Vous pourriez dire que

l'inspection visuelle fonctionne, je vérifie que le code fait ce qu'il est censé faire, pour ces scénarios et une fois que je vois qu'il est correct, nous sommes prêts à partir.

Maintenant tout d’abord, c’est bien que vous souhaitiez savoir si le code fonctionne correctement. C'est une bonne chose. Vous êtes en avance sur la courbe! Malheureusement, cette approche présente des problèmes.

Le premier problème avec l'inspection visuelle est que vous êtes un grave accident de soudage et que vous ne pouvez plus jamais vérifier l'exactitude de votre code.

Le deuxième problème est que la paire d'yeux utilisée est étroitement associée au cerveau du propriétaire des yeux. Si l'auteur du code possède également les yeux utilisés dans le processus d'inspection visuelle, le processus de vérification de l'exactitude dépend des connaissances relatives au programme intériorisées dans le cerveau de l'inspecteur visuel.

Il est difficile pour une nouvelle paire d'yeux d'entrer et de vérifier l'exactitude du code simplement parce qu'ils ne sont pas associés au cerveau du codeur d'origine. Le propriétaire de la deuxième paire d'yeux devra converser avec l'auteur original du code afin de bien comprendre le code en question. La conversation en tant que moyen de partage des connaissances est notoirement peu fiable. Un point sans objet si le codeur original n'est pas disponible pour les nouveaux yeux de la paire. Dans ce cas, la nouvelle paire d'yeux doit lire le code original.

Lire le code d'autres personnes non couvert par les tests unitaires est plus difficile que de lire le code associé à des tests unitaires. Au mieux, lire le code des autres peuples est un travail difficile, au pire, c’est la tâche la plus fastidieuse du génie logiciel. Il y a une raison pour laquelle les employeurs, lorsqu'ils annoncent des offres d'emploi, insistent sur le fait qu'un projet est un projet vierge (ou tout nouveau). Écrire du code à partir de zéro est plus facile que de modifier le code existant et donne ainsi au poste annoncé une plus grande attractivité pour les employés potentiels.

Avec les tests unitaires, nous divisons le code en ses composants. Pour chaque composant, nous exposons ensuite notre stand en expliquant comment le programme devrait se comporter. Chaque test unitaire raconte comment cette partie du programme devrait agir dans un scénario spécifique. Chaque test unitaire est comme une clause dans un contrat décrivant ce qui doit se passer du point de vue du code client.

Cela signifie alors qu'une nouvelle paire d'yeux a deux brins de vivants et précis documentation sur le code en question.

D'abord, ils ont le code lui-même, l'implémentation, comment le code a été fait; deuxièmement, ils ont toutes les connaissances que le codeur d'origine a décrites dans un ensemble de déclarations formelles qui racontent comment ce code est supposé se comporter.

Les tests unitaires capturent et décrivent formellement les connaissances que l’auteur original possédait lorsqu’il a implémenté le cours. Ils fournissent une description du comportement de cette classe lorsqu'elle est utilisée par un client.

Vous avez raison de douter de l'utilité de procéder ainsi car il est possible d'écrire des tests unitaires inutiles, ne couvrant pas tout le code en question, devenant obsolètes ou obsolètes, etc. Comment garantir que les tests unitaires non seulement imitent, mais améliorent le processus d'un auteur averti et consciencieux, inspectant visuellement les instructions de sortie de leur code au moment de l'exécution? Écrivez d'abord le test unitaire, puis écrivez le code pour que ce test réussisse. Lorsque vous avez terminé, laissez les ordinateurs exécuter les tests, ils sont rapides, ils sont parfaits pour effectuer des tâches répétitives et ils conviennent parfaitement au travail.

Assurez la qualité des tests en les vérifiant chaque fois que vous touchez le code qu'ils testent et exécutez les tests pour chaque build. Si un test échoue, corrigez-le immédiatement.

Nous automatisons le processus d’exécution des tests afin qu’ils soient exécutés chaque fois que nous construisons le projet. Nous automatisons également la génération de rapports de couverture de code détaillant le pourcentage de code couvert et exercé par les tests. Nous visons des pourcentages élevés. Certaines sociétés empêcheront l’archivage des modifications de code dans le contrôle de code source si elles ne disposent pas d’un nombre suffisant de tests unitaires pour décrire les modifications éventuelles du comportement du code. Généralement, une deuxième paire d'yeux examinera les modifications de code en collaboration avec l'auteur des modifications. L'examinateur examinera les modifications pour s'assurer que les modifications sont compréhensibles et suffisamment couvertes par les tests. Le processus de révision est donc manuel, mais lorsque les tests (tests unitaires et d'intégration et éventuellement de tests d'acceptation utilisateur) réussissent ce processus de révision manuelle, ils deviennent partie intégrante du processus de construction automatique. Celles-ci sont exécutées chaque fois qu'une modification est archivée. Un serveur intégration continue exécute cette tâche dans le cadre du processus de construction.

Les tests qui s'exécutent automatiquement maintiennent l'intégrité du comportement du code et aident à empêcher les modifications futures de la base de code de rompre le code .

Enfin, fournir des tests vous permet d’agresser de manière agressive re-factoriser le code car vous pouvez apporter des améliorations importantes à votre code en sachant que vos modifications ne casseront pas les tests existants.

Il y a une mise en garde à Test Driven Development et c'est que vous devez écrire du code dans le but de le rendre testable. Cela implique de coder des interfaces et d'utiliser des techniques telles que l'injection de dépendance pour instancier des objets en collaboration. Découvrez le travail de Kent Beck qui décrit très bien le TDD. Cherchez codant pour les interfaces et étudiez modèles de conception

50
Rob Kielty

Lorsque vous testez avec quelque chose comme System.out, vous ne testez qu'un petit sous-ensemble de cas d'utilisation possibles. Ce n'est pas très complet quand vous avez affaire à des systèmes pouvant accepter une quantité quasi infinie d'entrées différentes.

Les tests unitaires sont conçus pour vous permettre d'exécuter rapidement des tests sur votre application en utilisant un ensemble très volumineux et diversifié d'entrées de données différentes. En outre, les meilleurs tests unitaires prennent également en compte les cas limites, tels que les entrées de données situées à la limite de ce qui est considéré comme valide.

Pour qu'un être humain teste toutes ces entrées, cela peut prendre des semaines alors que cela peut prendre des minutes pour une machine.

Pensez-y comme ceci: vous ne "testez" pas non plus quelque chose qui sera statique. Votre application subira probablement des changements constants. Par conséquent, ces tests unitaires sont conçus pour s'exécuter à différents moments du cycle de compilation ou de déploiement. Peut-être le plus gros avantage est-il:

Si vous cassez quelque chose dans votre code, vous le saurez maintenant, pas après votre déploiement, ni lorsqu'un testeur d'AQ détecte un bogue, ni lorsque vos clients ont annulé. Vous aurez également une meilleure chance de régler le problème immédiatement, car il est clair que la chose qui a cassé la partie du code en question s'est probablement produite depuis votre dernière compilation. Ainsi, la quantité de travail d'enquête nécessaire pour résoudre le problème est considérablement réduite.

13
jmort253

Les tests unitaires garantissent que le code fonctionne comme prévu. Ils sont également très utiles pour garantir que le code fonctionne toujours comme prévu au cas où vous deviez le modifier ultérieurement pour créer de nouvelles fonctionnalités permettant de corriger un bogue. Avoir une couverture de test élevée de votre code vous permet de continuer à développer des fonctionnalités sans avoir à effectuer de nombreux tests manuels.

Votre approche manuelle par System.out Est bonne mais pas la meilleure. C'est un test unique que vous effectuez. Dans le monde réel, les exigences changent constamment et la plupart du temps, vous apportez de nombreuses modifications aux fonctions et aux classes existantes. Donc… pas à chaque fois que vous testez le morceau de code déjà écrit.

il y a aussi des fonctionnalités plus avancées sont dans JUnit comme comme

Affirmer des déclarations

JUnit fournit des méthodes pour tester certaines conditions. Ces méthodes commencent généralement par des assertions et vous permettent de spécifier le message d'erreur, le résultat attendu et le résultat réel.

Certaines de ces méthodes sont

  1. fail([message]) - Laisse le test échouer. Peut être utilisé pour vérifier qu'une certaine partie du code n'est pas atteinte. Ou si le test échoue avant que le code de test ne soit implémenté.
  2. assertTrue(true)/assertTrue(false) - sera toujours vrai/faux. Peut être utilisé pour prédéfinir un résultat de test, si le test n'est pas encore implémenté.
  3. assertTrue([message,] condition) - Vérifie que le booléen condition est vrai.
  4. assertEquals([message,] expected, actual) - Teste si deux valeurs sont égales (selon la méthode equals si elle est implémentée, sinon en utilisant la comparaison de référence ==). Remarque: Pour les tableaux, c'est la référence qui est vérifiée et et non le contenu, utilisez assertArrayEquals([message,] expected, actual) pour cela.
  5. assertEquals([message,] expected, actual, delta) - Teste si deux valeurs float ou double sont à une certaine distance l'une de l'autre, contrôlées par la valeur delta.
  6. assertNull([message,] object) - Vérifie que l'objet est null

etc. Voir la Javadoc complète pour tous les exemples ici .

Suites

Avec les suites de tests, vous pouvez en un sens combiner plusieurs classes de test en une seule unité afin que vous puissiez toutes les exécuter en même temps. Un exemple simple, combinant les classes de test MyClassTest et MySecondClassTest dans une suite appelée AllTests:

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

@RunWith(Suite.class)
@SuiteClasses({ MyClassTest.class, MySecondClassTest.class })
public class AllTests { } 
9
Arvind

J'ai ajouté un autre System.out ne peut pas faire:

  • Rendre chaque cas de test indépendant (c'est important)

    JUnit peut le faire: chaque fois qu'une nouvelle instance de cas de test sera créée et @Before est appelé.

  • Séparer le code de test de la source

    JUnit peut le faire.

  • Intégration avec CI

    JUnit peut le faire avec Ant et Maven.

  • Organisez et combinez facilement les cas de test

    JUnit peut faire @Ignore et suite de tests.

  • Facile à vérifier le résultat

    JUnit propose de nombreuses méthodes Assert (assertEquals, assertSame...)

  • Mock et stub vous font vous concentrer sur le module de test.

    JUnit peut faire: L'utilisation de mock et stub vous permet de configurer le bon appareil et de vous concentrer sur la logique du module de test.

Le principal avantage de JUnit est qu’il est automatisé plutôt que de devoir vérifier manuellement avec vos impressions. Chaque test que vous écrivez reste avec votre système. Cela signifie que si vous effectuez une modification qui a un effet secondaire inattendu, votre test la détectera et échouera plutôt que de vous rappeler de tout tester manuellement après chaque modification.

6
n00begon

JUnit est un framework de tests unitaires pour le Java). Il est important dans le développement piloté par les tests et fait partie d'une famille de frameworks de tests unitaires connus collectivement sous le nom de xUnit.

JUnit promeut l’idée du "premier test, puis du codage", qui met l’accent sur la configuration des données de test pour un morceau de code pouvant être testé en premier, puis implémenté. Cette approche revient à "tester un peu, coder un peu, tester un peu, coder un peu ...", ce qui augmente la productivité du programmeur et la stabilité du code de programme, ce qui réduit le stress du programmeur et le temps passé au débogage.

Caractéristiques JUnit est un framework open source utilisé pour l'écriture et l'exécution de tests.

Fournit une annotation pour identifier les méthodes de test.

Fournit des assertions pour tester les résultats attendus.

Fournit des coureurs de test pour l'exécution de tests.

Les tests JUnit vous permettent d’écrire du code plus rapidement, ce qui augmente la qualité

JUnit est d'une simplicité élégante. C'est moins complexe et prend moins de temps.

Les tests JUnit peuvent être exécutés automatiquement. Ils vérifient leurs propres résultats et fournissent un retour immédiat. Il n'est pas nécessaire de parcourir manuellement un rapport des résultats du test.

Les tests JUnit peuvent être organisés en suites de tests contenant des scénarios de tests, voire d'autres suites de tests.

Junit indique la progression du test dans une barre verte si le test se passe bien et devient rouge en cas d'échec du test.

4
AKKI

J'ai une perspective légèrement différente de la raison pour laquelle JUnit est nécessaire.

Vous pouvez réellement écrire tous les cas de test vous-même, mais c'est fastidieux. Voici les problèmes:

  1. Au lieu de System.out, Nous pouvons ajouter if(value1.equals(value2)) et renvoyer 0 ou -1 ou un message d'erreur. Dans ce cas, nous avons besoin d'une classe de test "principale" qui exécute toutes ces méthodes, vérifie les résultats et détermine quels tests ont échoué et lesquels ont été transmis.

  2. Si vous souhaitez ajouter quelques tests supplémentaires, vous devez également les ajouter à cette classe de tests "principale". Modifications apportées au code existant. Si vous souhaitez détecter automatiquement les cas de test à partir de classes de tests, vous devez utiliser la réflexion.

  3. Tous vos tests et votre classe principale d'exécution de tests ne sont pas détectés par Eclipse et vous devez écrire des configurations de débogage/exécution personnalisées pour exécuter ces tests. Vous ne voyez toujours pas ces jolies sorties de couleur verte/rouge cependant.

Voici ce que fait JUnit:

  1. Ses méthodes assertXXX() sont utiles pour imprimer des messages d'erreur utiles à partir des conditions et pour communiquer les résultats à la classe "principale".

  2. La classe "main" est appelée runner, fournie par JUnit, nous n’avons donc pas à en écrire. Et il détecte automatiquement les méthodes de test par réflexion. Si vous ajoutez de nouveaux tests avec l'annotation @Test, Ils sont automatiquement détectés.

  3. JUnit a également une intégration Eclipse et une intégration maven/gradle. Il est donc facile d’exécuter des tests et vous n’aurez pas à écrire de configurations d’exécution personnalisées.

Je ne suis pas un expert en JUnit, c'est donc ce que j'ai compris à présent et j'en ajouterai d'autres à l'avenir.

2
Sreekar

Vous ne pouvez pas écrire de scénario de test sans utiliser le framework de test, sinon vous devrez écrire votre framewok de test pour rendre justice à vos scénarios de test. Voici quelques informations sur JUnit Framework, mis à part le fait que vous pouvez utiliser le framework TestNG.

Qu'est-ce que Junit?

Junit est un framework de test largement utilisé avec Java Langage de programmation. Vous pouvez utiliser ce framework d'automatisation à la fois pour les tests unitaires et les tests d'interface utilisateur. Il nous aide à définir le flux d'exécution de notre code avec différentes annotations. Junit est basé sur l'idée de "premier test puis codage", ce qui nous aide à accroître la productivité des scénarios de test et la stabilité du code.

Fonctionnalités importantes des tests Junit -

  1. Il s'agit d'un framework de test open source permettant aux utilisateurs d'écrire et d'exécuter des scénarios de test de manière efficace.
  2. Fournit divers types d’annotations pour identifier les méthodes de test.
  3. Fournit différents types d'assertions pour vérifier les résultats de l'exécution d'un scénario de test.
  4. Il donne également aux coureurs de tests pour exécuter des tests efficacement.
  5. C'est très simple et fait donc gagner du temps.
  6. Il fournit des moyens d'organiser vos tests sous forme de combinaisons de test.
  7. Il donne des résultats de cas de test de manière simple et élégante.
  8. Vous pouvez intégrer jUnit avec Eclipse, Android Studio, Maven & Ant, Gradle et Jenkins
1
anuja jain

JUNIT: OBSERVER ET AJUSTER

Voici ma perspective de JUNIT.

JUNIT peut être utilisé pour,
1) Observez le comportement du système quand une nouvelle unité est ajoutée à ce système.
2) Faites les ajustements dans le système pour accueillir la "nouvelle" unité dans le système.
Quoi? Exactement.

La vraie vie par exemple.

Lorsque votre parent visite votre chambre auberge universitaire,
1) Vous prétendez être plus responsable.
2) Vous garderez toutes les choses où elles devraient être, comme des chaussures dans un casier à chaussures non sur une chaise, des vêtements dans une armoire pas sur une chaise.
3) Vous vous débarrasserez de toute la contrebande.
4) vous lancerez le nettoyage dans chaque appareil que vous possédez.

En termes de programmation

Système: Votre code
UNIT: nouvelle fonctionnalité.
Comme le framework JUNIT est utilisé pour Java donc JUNIT = Java UNIT (peut être).

Supposons que vous avez déjà un code à l'épreuve des balles, mais une nouvelle exigence est venue et vous devez ajouter la nouvelle exigence dans votre code. Cette nouvelle exigence peut casser votre code pour certaines entrées (testcase).

Un moyen facile d'adapter ce changement consiste à utiliser des tests unitaires (JUNIT).
Pour cela, vous devez écrire plusieurs cas de test pour votre code lorsque vous construisez votre base de code. Et chaque fois qu'une nouvelle exigence vient, il vous suffit d'exécuter tous les scénarios de test pour voir si l'un d'eux échoue. Si non, vous êtes un artiste BadA ** et vous êtes prêt à déployer le nouveau code.
Si l'un des cas de test échoue, vous modifiez votre code et exécutez à nouveau les cas de test jusqu'à obtenir le statut vert.

0
Rohit Singh

JUNIT est la méthode généralement acceptée par le développeur Java. Où ils peuvent fournir une entrée attendue similaire à la fonction et décider en conséquence que le code écrit est parfaitement écrit ou si le scénario de test échoue, une approche différente peut également être utilisée. JUNIT rendra le développement rapide et assurera le 0 défaut dans la fonction.

0
mohit sarsar

Les tests unitaires sont effectués à l'aide de la méthode White Box Testing. Le test en boîte blanche est une méthode de test d'un logiciel qui teste les structures internes ou le fonctionnement d'une application.

Quand est-ce effectué? Le test unitaire est le premier niveau de test logiciel et est effectué avant le test d'intégration.

https://onlyfullstack.blogspot.com/2019/02/junit-tutorial.html

https://onlyfullstack.blogspot.com/2019/02/what-is-junit-how-to-use-junit.html

0
Saurabh Oza