Não estou claro como o TDD, a metodologia, lida com o seguinte caso. Suponha que eu queira implementar o algoritmo mergesort, em Python. Eu começo escrevendo
assert mergesort([]) === []
e o teste falha com
NameError: o nome 'mergesort' não está definido
Eu adiciono
def mergesort(a):
return []
e meu teste passa. Em seguida eu adiciono
assert mergesort[5] == 5
e meu teste falha com
AssertionError
com que passo
def mergesort(a):
if not a:
return []
else:
return a
Em seguida, adiciono
assert mergesort([10, 30, 20]) == [10, 20, 30]
e agora tenho que tentar fazer isso passar. Eu "conheço" o algoritmo mergesort, então escrevo:
def mergesort(a):
if not a:
return []
else:
left, right = a[:len(a)//2], a[len(a)//2:]
return merge(mergesort(left)), mergesort(right))
E isso falha com
NameError: o nome 'mesclar' não está definido
Agora, aqui está a pergunta. Como posso fugir e começar a implementar merge
usando o TDD? Parece que não posso porque tenho esse teste "pendurado" não realizado e com falha mergesort
, que não será aprovado até que merge
seja concluído! Se esse teste persistir, nunca poderei realmente executar o TDD porque não serei "verde" durante a construção das iterações do TDD merge
.
Parece que estou preso aos três cenários feios a seguir e gostaria de saber (1) qual deles a comunidade TDD prefere ou (2) há outra abordagem que estou perdendo? Eu assisti várias orientações do tio Bob TDD e não me lembro de ter visto um caso como esse antes!
Aqui estão os 3 casos:
- Implemente a mesclagem em um diretório diferente com um conjunto de testes diferente.
- Não se preocupe em ser ecológico ao desenvolver a função auxiliar, apenas acompanhe manualmente os testes que realmente deseja passar.
- Comente (GASP!) Ou exclua as linhas
mergesort
nessa chamadamerge
; depoismerge
de trabalhar, coloque-os de volta.
Tudo isso me parece bobo (ou estou vendo isso errado?). Alguém sabe a abordagem preferida?
mergesort
, como já é um algoritmo muito bem definido, esse processo de descoberta não é necessário e torna-se uma questão de mapear o que você já sabe ser o design para uma série de testes de unidade. Presumivelmente, o seu teste de nível superior afirma que seu método em teste aceita uma coleção não triados e retorna um ordenado um ...mergesort
. Se você está procurando a maneira "certa" de fazer isso, não há outra, além de ser preciso sobre o mapeamento domergesort
algoritmo para uma série de testes de unidade; ou seja, eles devem refletir o quemergesort
realmente faz.mergesort
design saia naturalmente do refator vermelho-verde, isso não acontecerá, a menos que você guie o processo com base no seu conhecimento existentemergesort
.merge
deve ser inventado apenas no estágio de "refatoração". Se você perceber que essemerge
método pode ser introduzido para passar no teste,mergesort
primeiro faça seus testes semmerge
método. Em seguida, refatorar sua implementação, introduzindo omerge
métodoRespostas:
Aqui estão algumas maneiras alternativas de analisar suas opções. Mas primeiro, as regras do TDD, do tio Bob, com ênfase por mim:
Portanto, uma maneira de ler a regra número 3 é que você precisa da
merge
função para passar no teste, para poder implementá-la - mas apenas na sua forma mais básica.Ou, alternativamente, você começa escrevendo a operação de mesclagem on-line e depois a refatora em uma função depois de fazer o teste funcionar.
Outra interpretação é que você está escrevendo um mergesort, sabe que precisará de uma
merge
operação (ou seja, não é YAGNI, que é o que a regra "suficiente" tenta reduzir). Portanto, você deve ter iniciado os testes para a mesclagem e só então prosseguir para os testes para a classificação geral.fonte
merge
é surpreendentemente bagunçado, inteligente (e útil como um autônomo), a ideia de fazê-lo como uma função separada fazia mais sentido. No entanto, o estilo de fazê-lo em linha na sua forma básica e depois fatorá-lo no estágio do chapéu azul realmente parece estar certo e muito o que eu estava procurando.merge
operação antes de fazer a classificação (bem como testes separados dapartition
operação). Eu acho que os benefícios reivindicados pelo design emergente vêm do trabalho lento em direção a um objetivo conhecido. No caso do mergesort, não acho que o objetivo seja classificar em geral (porque você acabará com a classificação por bolhas). Você conhece as operações básicas e trabalha nessas operações; o tipo é principalmente uma reflexão tardia.merge
funçãomergesort
e zombe de seu comportamento. Então volte e implemente omerge
teste primeiro. Os delegados são impressionantes ™.