Séparation des classes JUnit en package de test spécial?

118

J'apprends les concepts du développement piloté par les tests en lisant les articles Craftsman (cliquez sur Craftsman sous By Topic ) recommandés dans une réponse à ma question précédente, "Exemple de projet pour apprendre JUnit et le génie logiciel approprié" . Jusqu'à maintenant j'aime ça!

Mais maintenant, je veux m'asseoir et essayer moi-même. J'ai une question qui, je l'espère, n'aura besoin que d'une réponse simple.

Comment organisez-vous vos classes de test JUnit et votre code actuel? Je parle principalement de la structure du package, mais tout autre concept important serait également utile.

Mettez-vous des classes de test dans org.myname.project.test. * Et du code normal dans org.myname.project. *? Mettez-vous les classes de test juste à côté des classes normales? Préférez-vous préfixer les noms de classe avec Test plutôt que de les suffixer?

Je sais que cela semble être le genre de chose dont je ne devrais pas m'inquiéter si tôt, mais je suis une personne très centrée sur l'organisation. Je suis presque le genre de personne qui passe plus de temps à trouver des méthodes pour suivre ce qu'il faut faire, plutôt que de faire avancer les choses.

Et j'ai un projet qui est actuellement soigneusement divisé en packages, mais le projet est devenu un gâchis. Au lieu d'essayer de tout refactoriser et d'écrire des tests, je veux repartir à zéro, les tests avant tout. Mais j'ai d'abord besoin de savoir où vont mes tests.


edit: J'ai totalement oublié Maven, mais il semble que la majorité d'entre vous l'utilise! Dans le passé, j'ai eu un cas d'utilisation spécifique où Maven est complètement tombé en panne sur moi mais Ant m'a donné la flexibilité dont j'avais besoin, alors je me suis retrouvé attaché à Ant, mais je pense que peut-être que je prenais la mauvaise approche. Je pense que je vais donner un autre essai à Maven car il semble que cela ira bien avec un développement piloté par les tests.

Rachitisme
la source
1
duplicata possible de Où dois-je placer mes tests JUnit?
mmmmmm

Réponses:

154

Je préfère mettre les classes de test dans le même package que les classes de projet qu'elles testent, mais dans un répertoire physique différent, comme:

myproject/src/com/foo/Bar.java
myproject/test/com/foo/BarTest.java

Dans un projet Maven, cela ressemblerait à ceci:

myproject/src/main/java/com/foo/Bar.java
myproject/src/test/java/com/foo/BarTest.java

Le point principal est que mes classes de test peuvent accéder (et tester!) Aux classes et aux membres de la portée du package.

Comme le montre l'exemple ci-dessus, mes classes de test ont le nom de la classe testée plus Testcomme suffixe. Cela aide à les trouver rapidement - ce n'est pas très drôle d'essayer de rechercher parmi quelques centaines de classes de test, dont chacune commence par Test...

Mise à jour inspirée du commentaire de @ Ricket: de cette façon, les classes de test apparaissent (généralement) juste après leur copain testé dans une liste alphabétique des noms de classes par projet. (Drôle que je profite de ce jour après jour, sans avoir consciemment réalisé comment ...)

Update2: Beaucoup de développeurs (y compris moi-même) aiment Maven, mais il semble y en avoir au moins autant qui ne le font pas. À mon humble avis, il est très utile pour les projets Java «grand public» (je mettrais environ 90% des projets dans cette catégorie ... mais les 10% restants sont encore une minorité importante). Il est facile à utiliser si l'on peut accepter les conventions Maven; mais sinon, cela fait de la vie une lutte misérable. Maven semble être difficile à comprendre pour de nombreuses personnes socialisées sur Ant, car cela nécessite apparemment une façon de penser très différente. (Moi-même, n'ayant jamais utilisé Ant, je ne peux pas comparer les deux.) Une chose est sûre: cela fait des tests unitaires (et d'intégration) une étape naturelle et de première classe dans le processus, ce qui aide les développeurs à adopter cette pratique essentielle.

Péter Török
la source
6
Je suis également d'accord avec la note de suffixe. De plus, étant donné que les classes de test sont séparées dans un dossier physique différent, il n'est pas nécessaire d'essayer de préfixer Test pour tenter de tromper un tri par ordre alphabétique en regroupant, et je pense que SomeClassTest lit mieux.
Ricket
Excellentes conventions +1
whiskeysierra
1
Une chose à propos de mettre des classes de test dans le même package: bien que cela permette d'utiliser des membres privés de package (c'est pourquoi j'utilise aussi ce schéma), cela ne permet pas non plus de tester la visibilité automatiquement, esp. si vous utilisez TDD et laissez votre IDE générer les stubs de méthode nécessaires. Il peut les générer avec une visibilité privée du package (NetBeans, je vous regarde), ce qui rend votre test parfaitement réussi (après que vous ayez mis l'implémentation dans ces stubs), mais peut échouer en utilisation réelle (si vous avez oublié d'ajouter public) .
Sergei Tachenov
Bien que cette convention soit intéressante, que faites-vous lorsque la suite de tests se développe? Par exemple, disons que vous avez 6 méthodes dans la classe, chaque méthode a 10 tests. Avez-vous 60 tests dans votre classe? Je subdivise généralement la classe de test (une classe de test par méthode). Le problème avec ceci est que vous pourriez trouver beaucoup de classes dans votre package de test.
mmalmeida
1
@Thick_propheT dans Eclipse: faites un clic droit sur le nom du projet, cliquez sur Nouveau - Autre ..., puis dans le dossier Java, sélectionnez Dossier Source. nommez-le "test". Ensuite, si vous souhaitez suivre la convention ci-dessus, ajoutez un nouveau package à ce dossier de test ayant le même nom que le package de la classe pour laquelle vous souhaitez écrire un cas de test, puis dans le package ajoutez un nouveau cas de test JUnit (situé dans le dossier Java / Junit lorsque vous faites Nouveau-Autre ...). dans ce nouvel assistant, vous pouvez spécifier la classe en cours de test et nommer votre
scénario de
15

Je place mes classes de test dans le même package que ce qu'elles testent mais dans un dossier ou un projet source différent . Organiser mon code de test de cette manière me permet de le compiler et de le conditionner facilement séparément afin que les fichiers jar de production ne contiennent pas de code de test. Il permet également au code de test d'accéder aux champs et méthodes privés du package.

ChrisH
la source
12

J'utilise Maven . La structure que Maven promeut est: -

src/main/java/org/myname/project/MyClass.java

src/test/java/org/myname/project/TestMyClass.java

c'est-à-dire qu'une classe de test avec Test ajouté au nom de la classe à tester est dans une structure de répertoires parallèle au test principal.

L'un des avantages d'avoir les classes de test dans le même package (pas nécessairement dans un répertoire) est que vous pouvez tirer parti des méthodes de la portée du package pour inspecter ou injecter des objets de test fictifs.

Martin
la source
18
Je pensais que ce n'était <class>Test.javapas le casTest<class>.java
Mike Rylander
2
Maven acceptera les deux modèles, conformément à la documentation du plugin Maven Surefire .
Elijah Woodward
3
Je dirais que le <class>Test.javaschéma de dénomination permet à la classe principale et à la classe de test de s'afficher de près lors de l'utilisation des fonctionnalités de recherche IDE, ce qui le rend un peu meilleur que Test<class>.java.
christopheml
1
@christopheml Je suis d'accord, c'est ce que je fais maintenant.
Martin
Cela a fonctionné pour Intellij. MyClassTest.java n'a pas fonctionné.
user2761431