J'apprends TDD en utilisant c #, pour autant que je sache le test devrait conduire le développement, c'est-à-dire commencez par écrire un test qui échoue après avoir écrit le strict minimum = code pour passer le test puis refactoring.
Mais il est également dit que "Programmer vers l'interface, pas la mise en œuvre", alors écrivez un interface d'abord. C'est là que ma confusion commence, si j'écris d'abord Interface, cela viole deux choses
Le code écrit pour l'interface est non piloté par test.
Ce n'est pas le strict minimum évidemment je peux l'écrire avec une classe simple.
Dois-je également commencer par écrire des tests d'interface? sans implémentation, que vais-je tester?
Si cette question semble stupide, désolé pour cela, mais je suis complètement confus. Peut-être que je prends les choses trop à la lettre.
Votre première violation ("Le code qui est écrit pour l'interface n'est pas pilotée par le test.") N'est pas valide. Prenons un exemple trivial. Supposons que vous écrivez une classe de calculatrice et que vous écrivez une opération d'addition. Quel test pourriez-vous passer?
public class CalculatorTest {
@Test
public void testAddTwoIntegers() {
Calculator calc = new Calculator();
int result = calc.add(2, 2)
Assert.assertEquals(4, result);
}
}
Votre test vient de définir l'interface. C'est la méthode add
, voyez? add
prend deux arguments et retourne leur somme. Vous pourrez déterminer ultérieurement que vous avez besoin de plusieurs calculatrices et extraire une (dans ce cas) Java à ce moment-là. Vos tests ne devraient pas changer alors, puisque vous avez testé le public interface de cette classe.
À un niveau plus théorique, les tests sont la spécification exécutable d'un système. Les interfaces avec un système doivent être pilotées par les utilisateurs de ce système et les tests sont la première méthode dont vous disposez pour définir les interactions.
Je ne pense pas que vous puissiez séparer la conception d'interface de la conception de test. Définir les interactions et concevoir des tests pour elles sont la même opération mentale - lorsque j'envoie ces informations dans une interface, je attendez un certain résultat. Lorsque quelque chose ne va pas avec mon entrée, je m'attends à cette erreur. Vous pouvez faire ce travail de conception sur papier, puis écrire vos tests à partir de cela, ou vous pouvez les faire en même temps - cela n'a pas vraiment d'importance.
Que faisons-nous lorsque nous écrivons un interface
? Écrivons-nous du code, ou concevons-nous?
Je ne suis pas fan de la notion de conception pilotée par les tests, mais J'adore Test Driven Développement . Personnellement, j'ai obtenu mes meilleurs résultats lorsque je conçois la classe à l'avance en concevant l'interface avant d'écrire un test. Je ne compte pas l'interface comme du code. L'interface est une conception que je vais implémenter en utilisant TDD. Il est probable que cela change une évolution au fur et à mesure que je travaille, mais c'est ma feuille de route (avec ma liste de tests).
Je m'arrêterai avant de commencer à déclamer, mais j'espère que c'est une façon utile pour vous d'y penser.
Dans TDD, devrais-je avoir à écrire Test d'abord ou Interface d'abord?
Tout dépend de la façon dont vous voulez faire orthodoxe/religieux TDD .
J'apprends le TDD
Puisque vous apprenez, vous devez expérimenter pour obtenir un flux de travail personnel, qui fonctionne pour vous.
Si vous voulez le faire selon les livres, vous écrivez d'abord un test, qui échouera évidemment, car vous commencez sans aucun code. Ensuite, vous écrivez du code pour réussir le test. Si cela est fait, vous êtes libre de refactoriser le code existant, car vous disposez d'un test qui fournit une sorte de filet de sécurité pour les refactorings. Décider d'utiliser un Interface est une sorte de refactoring.
Outre TDD ou non: La question de savoir si utiliser une interface ou non n'est pas intéressante en premier lieu. Bien sûr, si vous êtes sûr, vous avez un comportement différent que vous souhaitez répartir sur plusieurs objets, il est logique de penser à utiliser une interface: par exemple, si vous avez une sorte de sortie vers différentes destinations, il est logique de l'implémenter via une interface Writer et ont différentes classes pour la sortie (FileWriter, Printer etc.). Bien que ce soit un dicton courant pour écrire sur une interface, mais cela ne signifie pas: tiliser une interface pour tout. Parfois, c'est un niveau d'indirection trop important. Btw. il en va de même pour les services. Mais c'est un sujet différent.
D'autre part, vous pouvez développer piloté par les tests d'une autre manière: concevez votre code pour la testabilité. Ce qui signifie que vous écrivez du code, ce qui est facile à tester - bien que vous écriviez les tests après. Peu importe si vous écrivez des tests avant ou après, tant que vous testez de toute façon.
TDD ou BDD signifierait Faire d'abord vos interfaces de domaine puis écrire des tests par rapport à elles par mon interprétation. L'implémentation d'une interface a un comportement attendu.
c'est toujours un test avant le code car une interface ne contient aucune logique testable, c'est la structure contre laquelle vous écrivez un test.
Je le ferais comme suit
Écrivez le comportement semi-formel (étant donné: quand: alors :)
Écrire l'interface (dans la méthode d'encapsulation du comportement de l'hôte)
Écrivez le test qu'il identifie (entrez le donné, appelez le quand, testez le alors)
Écrire/modifier le béton (classe qui implémente l'interface) pour réussir le test
N'écrivez jamais de tests avant d'avoir conçu les interfaces. Lorsque vous pensez aux types de tests à écrire (conception de test), vous ne devez pas également concevoir (architecturer) simultanément votre application. Ne pensez pas à deux choses en même temps. Avez-vous entendu parler de la séparation des préoccupations? Cela s'applique non seulement à la structure physique de votre code mais également à votre processus de réflexion.
Décidez d'abord comment votre application doit être conçue. Cela signifie que vous concevez vos interfaces et les relations entre ces interfaces. Jusqu'à ce que vous ayez fait cela, vous ne devriez pas commencer à penser aux tests. Une fois que vous savez quelles sont vos interfaces, vous pouvez soit les créer d'abord, puis écrire des tests contre elles, soit écrire des tests d'abord, puis les créer. Dans ce dernier cas, vous ne pourrez évidemment pas compiler les tests. Je ne vois aucun mal ni aucune violation de la philosophie TDD dans la création des interfaces avant les tests.