Je voulais apprendre à utiliser l'approche TDD et j'avais un projet sur lequel je voulais travailler depuis un moment. Ce n'était pas un grand projet, donc j'ai pensé que ce serait un bon candidat pour TDD. Cependant, j'ai l'impression que quelque chose a mal tourné. Laissez-moi vous donner un exemple:
À un niveau élevé, mon projet est un complément pour Microsoft OneNote qui me permettra de suivre et de gérer des projets plus facilement. Maintenant, je voulais aussi garder la logique métier pour cela aussi découplée que possible de OneNote au cas où je déciderais de créer mon propre stockage personnalisé et back-end un jour.
J'ai d'abord commencé avec un test d'acceptation de mots simples pour décrire ce que je voulais que ma première fonctionnalité fasse. Cela ressemble à ceci (en le simplifiant par souci de concision):
- L'utilisateur clique sur créer un projet
- Types d'utilisateurs dans le titre du projet
- Vérifiez que le projet est créé correctement
En sautant les choses sur l'interface utilisateur et une planification intermédiaire, j'arrive à mon premier test unitaire:
[TestMethod]
public void CreateProject_BasicParameters_ProjectIsValid()
{
var testController = new Controller();
Project newProject = testController(A.Dummy<String>());
Assert.IsNotNull(newProject);
}
Jusqu'ici tout va bien. Rouge, vert, refactor, etc. Bon maintenant, il faut réellement enregistrer des trucs. Découpant quelques étapes ici, je termine avec cela.
[TestMethod]
public void CreateProject_BasicParameters_ProjectMatchesExpected()
{
var fakeDataStore = A.Fake<IDataStore>();
var testController = new Controller(fakeDataStore);
String expectedTitle = fixture.Create<String>("Title");
Project newProject = testController(expectedTitle);
Assert.AreEqual(expectedTitle, newProject.Title);
}
Je me sens toujours bien à ce stade. Je n'ai pas encore de magasin de données concret, mais j'ai créé l'interface à quoi je m'attendais.
Je vais sauter quelques étapes ici parce que ce message est assez long, mais j'ai suivi des processus similaires et finalement j'arrive à ce test pour mon magasin de données:
[TestMethod]
public void SaveNewProject_BasicParameters_RequestsNewPage()
{
/* snip init code */
testDataStore.SaveNewProject(A.Dummy<IProject>());
A.CallTo(() => oneNoteInterop.SavePage()).MustHaveHappened();
}
C'était bon jusqu'à ce que j'essaie de l'implémenter:
public String SaveNewProject(IProject project)
{
Page projectPage = oneNoteInterop.CreatePage(...);
}
Et il y a le problème là où se trouve le "...". Je me rends compte à ce stade que CreatePage nécessite un ID de section. Je ne m'en étais pas rendu compte lorsque je pensais au niveau du contrôleur parce que je ne voulais que tester les bits pertinents pour le contrôleur. Cependant, tout en bas ici, je me rends compte maintenant que je dois demander à l'utilisateur un emplacement pour stocker le projet. Maintenant, je dois ajouter un ID d'emplacement à la banque de données, puis en ajouter un au projet, puis en ajouter un au contrôleur et l'ajouter à TOUS les tests qui sont déjà écrits pour toutes ces choses. Il est devenu fastidieux très rapidement et je ne peux pas m'empêcher de penser que j'aurais compris cela plus rapidement si j'avais esquissé le design à l'avance plutôt que de le laisser être conçu pendant le processus TDD.
Quelqu'un peut-il m'expliquer si j'ai fait quelque chose de mal dans ce processus? Existe-t-il de toute façon ce type de refactoring qui peut être évité? Ou est-ce courant? S'il est courant, existe-t-il des moyens de le rendre plus indolore?
Merci a tous!