Atualmente, estou aprendendo sobre TDD e tentando colocá-lo em prática em meus projetos pessoais. Eu também usei extensivamente o controle de versão em muitos desses projetos. Estou interessado na interação dessas duas ferramentas em um fluxo de trabalho típico, especialmente quando se trata da máxima de manter pequenos compromissos. Aqui estão alguns exemplos que vêm à mente:
Inicio um novo projeto e escrevo um teste simples para criar uma classe ainda não existente. Devo confirmar o teste antes de escrever a classe, mesmo que o teste não seja compilado? Ou devo esboçar a quantidade mínima de código necessária para compilar o teste antes de confirmar?
Encontro um bug e escrevo um teste para recriá-lo. Devo confirmar o teste com falha ou implementar a correção de bug e depois confirmar?
Estes são os dois exemplos que vêm imediatamente à mente. Sinta-se à vontade para fornecer exemplos adicionais em sua resposta.
Editar:
Eu assumi nos dois exemplos que imediatamente após escrever o teste, escreverei o código para fazer o teste passar. Outra situação também pode surgir: eu trabalho em um projeto usando TDD por várias horas sem confirmar. Quando finalmente faço confirmações, quero dividir meu trabalho em pequenos pedaços. (O Git torna isso relativamente fácil, mesmo se você deseja confirmar apenas algumas das alterações em um único arquivo.)
Isso significa que minha pergunta é tanto sobre o que cometer quanto sobre quando cometer.
fonte
Não.
Não.
Você está falando de dois paradigmas aqui:
Minha recomendação é: siga o círculo do TDD até que seu código seja compilado, seus testes sejam ecológicos e você tenha algo para contribuir com o sistema. Portanto, você deve cortar seus recursos verticalmente, por exemplo, para uma nova máscara de interface do usuário, não crie todo o formulário e confirme sem a lógica de negócios, mas implemente um aspecto minúsculo, mas no front-end e na lógica de negócios, bem como na camada de persistência .
Para uma correção de bug grande, confirme após cada melhoria (por exemplo, refatoração), mesmo que o bug ainda não tenha sido corrigido. Os testes devem ser verdes e o código deve ser compilado.
fonte
Certamente você começa usando um controle de fonte saudável como o git.
Depois, você pode trabalhar da maneira que quiser e se comprometer em cada canto - qualquer passo ou subetapa é um jogo justo.
Antes de enviar as coisas, você compila todo o trabalho em um único commit. Ou um casal, em pontos onde tudo é verde e a composição faz sentido. E empurre esses commits sensatos. Para o caso múltiplo, crie um ramo com o qual você mescla --no-ff.
O controle de origem não é um sistema de rastreamento de trabalho ou um historiador. Os commits devem apresentar um delta coerente e sensível, enquanto o estado do checkout deve compilar pelo menos. Os intermediários podem ser preservados por um tempo para fins de revisão, mas quando tudo é considerado bom, um único commit por recurso é justo.
fonte
É meu entendimento do mundo que se compromete a marcar um ponto ao qual pode ser desejável retornar. O ponto em que um teste falha (mas compila) é definitivamente um desses pontos. Se eu me afastasse na direção errada, tentando passar no teste, gostaria de poder reverter o código de volta ao ponto de partida e tentar novamente; Não posso fazer isso se não tiver cometido.
fonte
Com um SCM ramificado (vi você usar o Git), você deve confirmar sempre que quiser um ponto de backup ("eu estraguei tudo; vou redefinir o diretório de trabalho para o último ponto de backup") ou quando você tiver uma versão estável. Quando você possui uma versão estável (todos os testes são aprovados), considere também mesclar o ramo de recursos atual ao ramo de desenvolvimento principal.
Depende de você (o git oferece a flexibilidade de se comprometer sempre que você quiser, sem afetar outros membros da sua equipe ou sua capacidade de trabalhar em diferentes recursos). Apenas verifique se você não possui vários recursos incompletos (que não funcionam) na mesma ramificação ao mesmo tempo (eles se bloquearão).
Eu costumo fazer dois commits para isso, a menos que o código de teste seja realmente pequeno / trivial para escrever.
Essa poderia ser uma suposição errada a ser feita. Se você trabalha sozinho (projeto pessoal) nada o impede de sempre fazer isso. Em um dos meus projetos mais bem-sucedidos (com relação à manutenção de alta qualidade de código e TDD durante todo o desenvolvimento do projeto), definimos testes algumas vezes semanas antes de implementá-los (ou seja, diríamos "o teste" test_FOO_with_null_first_parameter "agora é definido como uma função vazia e comprometa-o assim). Depois, fazeríamos um sprint (ou meio sprint) algumas vezes um mês depois, apenas para aumentar a cobertura do teste do módulo.Como já tínhamos os testes declarados, era fácil estimar.
Eu diria que definitivamente me comprometo a criar pontos de backup . Isso funciona muito bem para testes exploratórios ("Vou apenas adicionar algumas impressões em toda a base de código, executar e
git reset --hard
removê-las quando terminar) e para criação de protótipos.fonte
No meu fluxo de trabalho, sempre que possível, trabalho incerto em um ramo de controle de fonte pessoal. Para que eu possa tentar, falhar, tente novamente, se necessário, até que funcione, e só me comprometa com o projeto maior quando eu tiver um código de trabalho real.
Da perspectiva do TDD, a pergunta "você faz o check-in primeiro?" depende inteiramente do código em que você está trabalhando. Se for um código novo, você não fará o check-in até ter algo que valha a pena fazer o check-in. Mas se for um erro encontrado no código já compilado ou enviado, vale a pena fazer o check-in em um teste para reproduzir o erro, POR SI MESMO. Especialmente se for o fim de um dia útil e você sair do escritório antes de consertar o código.
(Obviamente, se sua loja possui um processo automatizado de criação que morre se algum teste de unidade falhar, talvez você não queira fazer check-in de um teste com falha até corrigir o erro. Mas isso parece uma maneira estranha de trabalhar, pois "encontre e documentar erros "e" corrigir erros "podem ser executados por duas equipes totalmente diferentes.)
fonte