Comment utiliser les tests unitaires lors de l'utilisation de BDD?

17

J'essaie de comprendre BDD. J'ai lu quelques articles et, si j'ai bien compris, BDD est "la prochaine étape" de TDD. Je dis cela parce que je trouve que les deux sont très similaires, et comme j'ai pu le lire dans cet article , BDD est né comme une amélioration de TDD. Génial, j'aime vraiment l'idée.

Il y a un point pratique que je n'obtiens pas, pensa: il y a un fichier .feature dans lequel le BA écrira tout le comportement attendu dans lequel le système aurait. En tant que BA, il n'a aucune idée de la façon dont le système est construit, nous allons donc écrire quelque chose comme ceci:

+ Scénario 1: le compte est à crédit +

Étant donné que le compte est à crédit

Et la carte est valide

Et le distributeur contient de l'argent

Lorsque le client demande de l'argent

Assurez-vous ensuite que le compte est débité et assurez-vous que l'argent est distribué

Et assurez-vous que la carte est retournée

D'accord, c'est très bien, mais il y a de nombreuses parties du système qui collaboreront pour que cela se produise (pensez à Account obj, Dispenser obj, Customer obj et ainsi de suite). Pour moi, cela ressemble à un test d'intégration.

J'aimerais avoir des tests unitaires. Comment tester le code qui vérifie si le distributeur a de l'argent? Ou que l'argent est distribué? Ou que le compte est débité en cas de besoin? Comment puis-je mélanger les tests unitaires avec les tests "BA Created"?

JSBach
la source
C'est à cela que servent les simulacres et les talons: isoler les pièces sous test.
Robert Harvey
Désolé, je ne comprends pas. Tu veux dire que je devrais me moquer du distributeur? Comment pourrais-je le tester?
JSBach
Lorsque vous testez le distributeur, vous vous moquez du compte, de la carte et du client.
Robert Harvey
3
Pourquoi voulez-vous mélanger les tests unitaires et les "tests créés par BA"? Utilisez TDD comme technique pour créer des tests unitaires pour des parties individuelles de votre logiciel et ajoutez des tests supplémentaires pour tester les exigences du point de vue du BA (appelez ces derniers tests d'intégration, si vous le souhaitez). Où voyez-vous une contradiction?
Doc Brown
@DocBrown: Par «émerger naturellement», je veux dire que certains TDD'ers croient qu'une conception logicielle émergera naturellement des tests unitaires comme vous «refactorisez rouge-vert». Une conversation de chat en cours sur cette question a lieu dans le tableau blanc .
Robert Harvey

Réponses:

27

Le développement piloté par le comportement et le développement piloté par les tests sont complémentaires, mais ne se remplacent pas.

Le comportement de l'application est décrit dans les tests d'acceptation qui, selon BDD, seraient les fonctionnalités et les scénarios écrits en concombre.

Les petits détails sur le fonctionnement de chaque petit composant sont décrits dans Tests unitaires. Les résultats des tests unitaires prennent en charge les scénarios que vous écrivez dans Cucumber.

Imaginez le processus de construction d'une voiture.

Tout d'abord, l'équipe produit propose ses idées et les résume finalement à des scénarios d'utilisation:

Scenario: Starting the car
    Given I am standing in front of the drivers door
    When I open the door
    Then the door should lift up DeLorean-style (yeah, baby!)
    When I get into the car
    And turn the key
    Then the engine roars to life

Je sais que ce scénario semble un peu idiot, mais c'est une exigence très élevée, axée sur le produit et l'utilisateur final. L'ouverture de la porte, la rotation de la clé et le démarrage du moteur impliquent beaucoup de composants différents travaillant ensemble. Ce seul test n'est pas suffisant pour s'assurer que le véhicule fonctionne correctement. Vous devez tester le démarreur, la batterie, l'alternateur, la clé, le contacteur d'allumage --- et la liste continue --- juste pour monter dans la voiture et la démarrer. Chacun de ces composants a besoin de ses propres tests.

Le scénario ci-dessus est un test "Big Picture". Chaque composant du véhicule a besoin de tests "Small Picture" pour s'assurer qu'ils fonctionnent correctement dans l'ensemble.

La construction et le test de logiciels sont les mêmes à bien des égards. Vous concevez de haut en bas, puis construisez de bas en haut. Pourquoi avoir une porte qui se soulève si vous ne pouvez même pas démarrer le moteur? Pourquoi avoir un démarreur si vous n'avez pas de batterie?

Votre équipe produit élaborera les tests d'acceptation et les étoffera dans du concombre. Cela vous donne le "Big Picture". Il appartient maintenant à l'équipe d'ingénierie de concevoir les composants appropriés et la façon dont ils interagissent, puis de tester chacun séparément - ce sont vos tests unitaires.

Une fois les tests unitaires réussis, commencez à implémenter les scénarios de concombre. Une fois ceux-ci passés, vous avez livré ce que l'équipe produit a demandé.

Greg Burghardt
la source
Existe-t-il un moyen de lier ces tests "Big Picture" aux tests "Small Picture"? Je veux dire, lorsque les fonctionnalités changent officiellement (par exemple, un scénario de concombre changeant), y a-t-il un moyen de mapper ce changement aux tests bas de gamme (par exemple, les tests junit qui sont pour ce scénario de concombre particulier)?
Srikanth
Vous pouvez partager des méthodes d'assistance et des assertions personnalisées entre vos tests «grande image» et «petite image», mais ils impliqueront très probablement une configuration différente pour tester des unités de code spécifiques.
Nick McCurdy
[...] qui selon BDD seraient les Caractéristiques et Scénarios écrits en Concombre. Vous confondez principes et outils.
jub0bs
Eh bien, ok, le libellé est un peu décalé, mais le fait est que le comportement d'une application est capturé dans les fonctionnalités et les scénarios.
Greg Burghardt
9

J'essaie de comprendre BDD. J'ai lu quelques articles et, si j'ai bien compris, BDD est "la prochaine étape" de TDD. Je dis cela parce que je trouve que les deux sont très similaires, et comme j'ai pu le lire dans cet article, BDD est né comme une amélioration de TDD.

En fait, non, BDD n'est pas "la prochaine étape" de TDD. Il est TDD. Ou plus précisément, il s'agit d'une reformulation de TDD.

Les créateurs de BDD ont remarqué que le principal obstacle à la compréhension du fait que le TDD n'est pas une question de test mais de spécification comportementale est que toute la terminologie TDD concerne le test et non la spécification comportementale. C'est comme essayer de ne pas penser à un éléphant rose quand quelqu'un vous dit "essayez de ne pas penser à un éléphant rose", sauf avec la complication supplémentaire d'être dans une pièce remplie d'éléphants roses et un gars hurlant constamment "éléphant rose, rose éléphant, éléphant rose "dans votre oreille.

Ainsi, ils ont reformulé TDD en termes de spécification comportementale. Les «tests» et les «cas de test» sont désormais des «exemples», les «unités» sont des «comportements», les «assertions» sont des «attentes», etc.

Cependant, la méthodologie est toujours la même. Vous commencez avec un test d'acceptation (je veux dire "fonctionnalité"), effectuez un zoom avant sur un test unitaire (je veux dire "exemple"), effectuez un zoom arrière, etc.

J'aimerais avoir des tests unitaires. Comment tester le code qui vérifie si le distributeur a de l'argent? Ou que l'argent est distribué? Ou que le compte est débité en cas de besoin? Comment puis-je mélanger les tests unitaires avec les tests "BA Created"?

De la même manière que vous le faites dans TDD. Vous pouvez écrire vos fonctionnalités et vos exemples dans différents cadres (par exemple, Cucumber et RSpec) ou même dans différents langages (par exemple, écrire des exemples pour un projet C en C et des fonctionnalités dans FIT / Fitnesse), vous pouvez utiliser un seul cadre de fonctionnalités pour les deux ( par exemple, écrire des exemples et des fonctionnalités dans Cucumber) ou vous pouvez utiliser un cadre d'exemples unique pour les deux (par exemple, écrire les deux dans RSpec). Vous n'avez même pas du tout besoin d'utiliser un framework.

Un exemple de TDD-done-right (qui est identique à BDD) utilisant un seul framework est JUnit lui-même, qui contient un mélange de tests unitaires (exemples) et de tests fonctionnels / d'intégration (fonctionnalités), tous écrits dans JUnit lui-même.

Je crois que Kent Beck appelle cela le "zoom". Démarrez de haut niveau, puis "zoomez" sur les détails, puis reculez.

Jörg W Mittag
la source
1

Avertissement: je ne suis pas un expert en BDD, mais j'essaie de vous donner mon point de vue sur l'article auquel vous avez lié.

TDD est une technique d'implémentation - vous écrivez d'abord un test, puis vous implémentez la méthode, exécutez votre test, refactorisez et ajoutez d'autres tests pour la même méthode ou pour une nouvelle méthode. TDD ne définit en fait aucune règle sur la façon de choisir les noms de classe ou de méthode, cela dépend de vous. TDD ne vous dit pas non plus "quand vous avez terminé".

Ainsi, chaque fois que vous écrivez un test pour une nouvelle méthode, vous devez choisir un nom de méthode - et c'est là que BDD entre en jeu. En choisissant des noms de méthode en utilisant les termes métier du scénario ci-dessus, et en les choisissant d'une manière décrivant le comportement de votre classe, vous faites BDD. Chaque fois que vous vous demandez "dois-je ajouter des tests supplémentaires", vous pouvez regarder les scénarios donnés par votre BA et vérifier si vous avez complètement implémenté toutes les pièces nécessaires. Sinon, vous devrez ajouter d'autres tests.

L'auteur de l'article suggère également d'utiliser un schéma de dénomination plus lié au comportement lors du choix des noms de vos tests, c'est pourquoi il suggère de remplacer JUnit par un outil qui ne s'appuie pas sur un schéma de dénomination où chaque scénario de test doit commencer le nom "test". Bien que je ne connaisse pas JBehave, je pense que c'est la principale différence entre cet outil et Junit.

De plus, les scénarios BDD seront également un modèle pour les tests d'intégration - que vous ajouterez généralement après avoir étoffé les noms de méthode par TDD et après avoir ajouté une quantité raisonnable de tests unitaires.

Donc, à ma connaissance, TDD est un instrument que vous pouvez utiliser dans le cadre de BDD, et BDD vous aide à écrire les bons tests et à leur donner de meilleurs noms.

Doc Brown
la source
En bref, Junit prend en charge la dénomination de vos tests; il vous suffit d'utiliser une annotation @Test. Cela n'a peut-être pas été fait en 2003 cependant.
soru
@soru En 2003, il a effectivement imposé le mot "test".
Lunivore
L'auteur de l'article est Dan North, qui a proposé le concept en premier lieu. Il a notamment remarqué que le mot "test" nous amène à tester notre implémentation (domaine de la solution) alors qu'en réalité, l'exploration et la définition des tests devraient vraiment nous maintenir dans le domaine du problème. Dan a décrit BDD comme "ce que TDD était censé être". Lisez ceci pour plus d'informations: dannorth.net/2012/05/31/bdd-is-like-tdd-if
Lunivore