Quantos testes por método?
Bem, o máximo teórico e altamente impraticável é a complexidade do N-Path (assuma que todos os testes são abrangidos diferentes maneiras através do código;)). O mínimo é UM!. Por método público ou seja, ele não testa detalhes de implementação, apenas comportamentos externos de uma classe (retorna valores e chama outros objetos).
Você cita:
*And the thought of testing each of your methods with its own test method (in a 1-1 relationship) will be laughable. *
e depois pergunte:
So if creating a test for each method is 'laughable', how/when do you chose what you write tests for?
Mas acho que você entendeu mal o autor aqui:
A idéia de ter one test method
por one method in the class to test
é o que o autor chama de "risível".
(Pelo menos para mim) Não é sobre "menos" é sobre "mais"
Então deixe-me reformular como eu o entendi:
E o pensamento de testar cada um dos seus métodos com APENAS UM MÉTODO (o seu próprio método de teste numa relação 1-1) será risível.
Para citar sua citação novamente:
When you realize that it's all about specifying behaviour and not writing tests, your point of view shifts.
Quando você pratica TDD você não pensa :
Eu tenho um método calculateX($a, $b);
e ele precisa de um teste testCalculcateX
que testa TUDO sobre o método.
O que o TDD lhe diz é pensar em como o seu código DEVE FAZER :
Eu preciso calcular o maior de dois valores ( primeiro caso de teste! ) mas se $ a for menor que zero, então ele deve produzir um erro ( segundo caso de teste! ) e se $ b for menor que zero, deve .... ( terceiro caso de teste! ) e assim por diante.
Você deseja testar comportamentos, não apenas métodos únicos sem contexto.
Dessa forma, você obtém uma suíte de testes que é a documentação do seu código e REALMENTE explica o que se espera, talvez até por que:)
Como você decide qual parte do seu código cria testes de unidade?
Bem, tudo o que acaba no repositório ou em qualquer lugar perto da produção precisa de um teste. Eu não acho que o autor de suas citações discordaria disso, como tentei dizer acima.
Se você não tem um teste para isso, fica muito mais difícil (mais caro) mudar o código, especialmente se você não está fazendo a mudança.
TDD é uma maneira de garantir que você tenha testes para TUDO, mas contanto que você ESCREVA os testes, tudo bem. Geralmente escrevê-los no mesmo dia ajuda, já que você não vai fazer isso mais tarde, está? :)
Resposta aos comentários:
a decent amount of methods can't be tested within a particular context because they either depend or are dependent upon other methods
Bem, existem três coisas que esses métodos podem chamar:
Métodos públicos de outras classes
Podemos ridicularizar outras classes, então definimos o estado lá. Estamos no controle do contexto, então isso não é um problema.
* Métodos protegidos ou privados no mesmo *
Tudo o que não faz parte da API pública de uma classe não é testado diretamente, normalmente.
Você deseja testar o comportamento e não a implementação e, se uma classe fizer tudo o que funciona em um grande método público ou em muitos métodos protegidos menores que forem chamados, será implementação . Você quer ser capaz de MUDAR esses métodos protegidos sem tocar nos seus testes. Porque seus testes vão quebrar se o seu código mudar de comportamento! É para isso que seus testes estão lá, para dizer quando você quebra algo:)
Métodos públicos na mesma classe
Isso não acontece com muita frequência? E se isso acontecer no exemplo a seguir, há algumas maneiras de lidar com isso:
$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute();
Que os setters existem e não fazem parte da assinatura do método de execução é outro tópico;)
O que podemos testar aqui é se as execuções explodem quando definimos os valores errados. Esse setBla
gera uma exceção quando você passa uma string pode ser testado separadamente, mas se quisermos testar se esses dois valores permitidos (12 e 14) não funcionam TOGETHER (por qualquer motivo) do que esse é um caso de teste. / p>
Se você quer um "bom" conjunto de testes, você pode, em php, talvez (!) adicionar uma anotação @covers Stuff::execute
para garantir que você só gere cobertura de código para este método e as outras coisas que são apenas configurações precisam ser testado separadamente (novamente, se você quiser isso).
Então o ponto é: Talvez você precise criar alguns dos mundos ao redor primeiro, mas você deve ser capaz de escrever casos de teste significativos que usualmente abrangem apenas uma ou talvez duas funções reais (setters don ' conte aqui). O resto pode ser jogado fora ou ser testado primeiro e depois confiado (veja @depends
)
* Nota: A questão foi migrada do SO e inicialmente era sobre PHP / PHPUnit, é por isso que o código de amostra e as referências são do mundo php, eu acho que isso também é aplicável a outros idiomas como phpunit não difere tanto de outras estruturas de testes xUnit.