Volevo insegnarmi a usare l'approccio TDD e avevo un progetto su cui volevo lavorare da un po '. Non era un progetto di grandi dimensioni, quindi ho pensato che sarebbe un buon candidato per TDD. Tuttavia, sento che qualcosa è andato storto. Lasciatemi fare un esempio:
Ad un livello elevato il mio progetto è un componente aggiuntivo per Microsoft OneNote che mi consentirà di monitorare e gestire i progetti più facilmente. Ora, volevo anche mantenere la logica di business per questo come disaccoppiata da OneNote il più possibile possibile nel caso in cui ho deciso di creare il mio storage personalizzato e il back end un giorno.
Per prima cosa ho iniziato con un semplice test di accettazione di parole semplici per delineare ciò che volevo fare per la mia prima caratteristica. Assomiglia a qualcosa del genere (abbreviato per brevità):
- L'utente fa clic su crea progetto
- Tipi di utente nel titolo del progetto
- Verifica che il progetto sia stato creato correttamente
Ignorando le informazioni sull'interfaccia utente e alcuni piani di intermediazione vengo al mio primo test di unità:
[TestMethod]
public void CreateProject_BasicParameters_ProjectIsValid()
{
var testController = new Controller();
Project newProject = testController(A.Dummy<String>());
Assert.IsNotNull(newProject);
}
Fin qui tutto bene. Rosso, verde, refactoring, ecc. Va bene, adesso serve davvero risparmiare. Tagliando alcuni passaggi, finisco con questo.
[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);
}
Mi sento ancora bene a questo punto. Non ho ancora un data store concreto, ma ho creato l'interfaccia come avrei previsto.
Ho intenzione di saltare alcuni passaggi qui perché questo post sta diventando abbastanza lungo, ma ho seguito processi simili e alla fine ottengo questo test per il mio archivio dati:
[TestMethod]
public void SaveNewProject_BasicParameters_RequestsNewPage()
{
/* snip init code */
testDataStore.SaveNewProject(A.Dummy<IProject>());
A.CallTo(() => oneNoteInterop.SavePage()).MustHaveHappened();
}
Questo è andato bene fino a quando ho provato a implementarlo:
public String SaveNewProject(IProject project)
{
Page projectPage = oneNoteInterop.CreatePage(...);
}
E il problema è proprio dove si trova "...". Ora mi rendo conto che in questo punto CreatePage richiede un ID di sezione. Non me ne ero reso conto quando pensavo al livello del controller perché mi interessava solo testare i bit rilevanti per il controller. Tuttavia, fino a qui mi rendo conto che devo chiedere all'utente un luogo in cui archiviare il progetto. Ora devo aggiungere un ID di posizione all'archivio dati, quindi aggiungerne uno al progetto, quindi aggiungerne uno al controller e aggiungerlo a TUTTI i test già scritti per tutte queste cose. È diventato molto noioso molto rapidamente e non posso fare a meno di pensare che mi sarei accorto più rapidamente se avessi delineato il progetto in anticipo piuttosto che averlo progettato durante il processo TDD.
Qualcuno può spiegarmi se ho fatto qualcosa di sbagliato in questo processo? C'è comunque questo tipo di refactoring può essere evitato? O è comune? Se è comune ci sono modi per renderlo più indolore?
Grazie a tutti!