Eu queria me ensinar a usar a abordagem TDD e tinha um projeto em que vinha trabalhando há um tempo. Não era um projeto grande, então pensei que seria um bom candidato para TDD. No entanto, sinto que algo deu errado. Deixe-me dar um exemplo:
Em um nível alto, meu projeto é um suplemento para o Microsoft OneNote que me permitirá rastrear e gerenciar projetos com mais facilidade. Agora, eu também queria manter a lógica comercial para isso o mais dissociada possível do OneNote, caso decidisse criar meu próprio armazenamento personalizado e back-end algum dia.
Primeiro, comecei com um teste básico de aceitação de palavras simples para descrever o que queria que meu primeiro recurso fizesse. Parece algo assim (emburrecendo-o por questões de concisão):
- Cliques do usuário criar projeto
- Tipos de usuário no título do projeto
- Verifique se o projeto foi criado corretamente
Ignorando o material da interface do usuário e algum planejamento intermediário, chego ao meu primeiro teste de unidade:
[TestMethod]
public void CreateProject_BasicParameters_ProjectIsValid()
{
var testController = new Controller();
Project newProject = testController(A.Dummy<String>());
Assert.IsNotNull(newProject);
}
Por enquanto, tudo bem. Vermelho, verde, refatorador, etc. Tudo bem, agora ele precisa realmente salvar coisas. Cortando alguns passos aqui, acabo com isso.
[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);
}
Eu ainda estou me sentindo bem neste momento. Ainda não tenho um armazenamento de dados concreto, mas criei a interface como previa que fosse.
Vou pular algumas etapas aqui porque esta postagem está ficando longa o suficiente, mas segui processos semelhantes e, eventualmente, chego a esse teste para meu armazenamento de dados:
[TestMethod]
public void SaveNewProject_BasicParameters_RequestsNewPage()
{
/* snip init code */
testDataStore.SaveNewProject(A.Dummy<IProject>());
A.CallTo(() => oneNoteInterop.SavePage()).MustHaveHappened();
}
Isso foi bom até que eu tentei implementá-lo:
public String SaveNewProject(IProject project)
{
Page projectPage = oneNoteInterop.CreatePage(...);
}
E há o problema exatamente onde está o "...". Percebo agora, neste ponto, que o CreatePage requer um ID de seção. Eu não percebi isso de volta quando estava pensando no nível do controlador, porque estava preocupado apenas em testar os bits relevantes para o controlador. No entanto, todo o caminho até aqui agora percebo que tenho que pedir ao usuário um local para armazenar o projeto. Agora eu tenho que adicionar um ID de local ao armazenamento de dados, depois adicionar um ao projeto, adicionar um ao controlador e adicioná-lo a TODOS os testes que já foram escritos para todas essas coisas. Tornou-se entediante muito rapidamente e não posso deixar de sentir que seria mais rápido se eu desenhasse o design com antecedência, em vez de deixá-lo ser projetado durante o processo TDD.
Alguém pode me explicar se fiz algo errado nesse processo? Existe alguma maneira de evitar esse tipo de refatoração? Ou isso é comum? Se é comum, existem maneiras de torná-lo mais indolor?
Obrigado a todos!