Quais são as práticas recomendadas para nomear classes de teste de unidade e métodos de teste?
Isso foi discutido anteriormente no SO, em Quais são algumas convenções de nomenclatura populares para testes de unidade?
Não sei se essa é uma abordagem muito boa, mas atualmente em meus projetos de teste, tenho mapeamentos individuais entre cada classe de produção e uma classe de teste, por exemplo, Product
e ProductTest
.
Nas minhas aulas de teste, tenho métodos com os nomes dos métodos que estou testando, um sublinhado e, em seguida, a situação e o que espero que aconteça, por exemplo Save_ShouldThrowExceptionWithNullName()
.
unit-testing
naming-conventions
James Newton-King
fonte
fonte
test<MethodUnderTest>_<state>
por exemplo,testPop_emptyStack
google-styleguide.googlecode.com/svn/trunk/javaguide.html 5.2.3 Nomes dos métodos. Em caso de dúvida, siga o Google.Respostas:
Gosto da estratégia de nomes de Roy Osherove , é a seguinte:
[UnitOfWork_StateUnderTest_ExpectedBehavior]
Possui todas as informações necessárias sobre o nome do método e de maneira estruturada.
A unidade de trabalho pode ser tão pequena quanto um único método, uma classe ou tão grande quanto várias classes. Ele deve representar todas as coisas que devem ser testadas neste caso de teste e estão sob controle.
Para montagens, uso o
.Tests
final típico , que eu acho bastante difundido e o mesmo para as classes (terminando comTests
):[NameOfTheClassUnderTestTests]
Anteriormente, usei o Fixture como sufixo em vez de testes, mas acho que o último é mais comum, depois mudei a estratégia de nomeação.
fonte
UpdateManager.Update()
. Tendo isso em mente, costumo chamar meus testesWhenUpdating_State_Behaviour
ouWhenUpdating_Behaviour_State
. Dessa forma, testo uma ação específica de uma classe, evitando colocar um nome de método em um nome de teste. Mas o mais importante é que eu tenho que ter uma idéia de que lógica de negócios está falhando quando vejo o nome de um teste que falhou.Eu gosto de seguir o padrão de nomeação "Deveria" para testes enquanto nomeava o dispositivo de teste após a unidade em teste (ou seja, a classe).
Para ilustrar (usando C # e NUnit):
Por que "deveria" ?
Acho que isso força os autores do teste a nomearem o teste com uma frase como "Deve [estar em algum estado] [depois / antes / quando] [a ação ocorre]"
Sim, escrever "Deveria" em todos os lugares fica um pouco repetitivo, mas como eu disse, obriga os escritores a pensar da maneira correta (o que pode ser bom para iniciantes). Além disso, geralmente resulta em um nome de teste de inglês legível.
Atualização :
Percebi que Jimmy Bogard também é fã de 'should' e até tem uma biblioteca de testes de unidade chamada Should .
Atualização (4 anos depois ...)
Para os interessados, minha abordagem para nomear testes evoluiu ao longo dos anos. Um dos problemas com o padrão Should , descrito acima, não é fácil saber rapidamente qual método está sendo testado. Para OOP, acho que faz mais sentido iniciar o nome do teste com o método em teste. Para uma classe bem projetada, isso deve resultar em nomes de métodos de teste legíveis. Agora eu uso um formato semelhante a
<method>_Should<expected>_When<condition>
. Obviamente, dependendo do contexto, você pode substituir os verbos Dever / Quando por algo mais apropriado. Exemplo:Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()
fonte
increasesBalanceWhenDepositIsMade()
.Eu gosto deste estilo de nomeação:
e assim por diante. Isso deixa muito claro para quem não faz o teste qual é o problema.
fonte
should
I preferemwill
assimOrdersWithNoProductsWillFail()
Will
não é realmente apropriado e, ao fazê-lo, você está dizendo ao leitor por engano que de forma alguma o teste falhará ... se vocêWill
expressar algo no futuro que pode não acontecer, você estará usá-lo incorretamente. Considerando queShould
é a melhor opção aqui, porque indica que você deseja / deseja que algo aconteça, mas não aconteceu ou não, quando o teste é executado, ele diz se falhou / teve êxito, então você não pode realmente sugerir que de antemão, essa é a explicação lógica, qual é a sua? por que você evitaShould
?Kent Beck sugere:
Um dispositivo de teste por 'unidade' (classe do seu programa). Os equipamentos de teste são as próprias classes. O nome do dispositivo de teste deve ser:
Os casos de teste (os métodos dos equipamentos de teste) têm nomes como:
Por exemplo, tendo a seguinte classe:
Um acessório de teste seria:
fonte
Nomes de classe . Para nomes de acessórios de teste, acho que "Teste" é bastante comum na linguagem onipresente de muitos domínios. Por exemplo, em um domínio de engenharia:
StressTest
e em um domínio de cosméticos:SkinTest
. Desculpe discordar de Kent, mas usar "Teste" em meus equipamentos de teste (StressTestTest
?) É confuso."Unidade" também é muito usado em domínios. Por exemplo
MeasurementUnit
. É uma classe chamadaMeasurementUnitTest
teste de "Measurement" ou "MeasurementUnit"?Portanto, eu gosto de usar o prefixo "Qa" para todas as minhas classes de teste. Por exemplo,
QaSkinTest
eQaMeasurementUnit
. Nunca é confundido com objetos de domínio, e usar um prefixo em vez de um sufixo significa que todos os equipamentos de teste vivem juntos visualmente (útil se você tiver falsificações ou outras classes de suporte em seu projeto de teste)Namespaces . Trabalho em C # e mantenho minhas classes de teste no mesmo espaço para nome da classe que eles estão testando. É mais conveniente do que ter espaços para nome de teste separados. Obviamente, as classes de teste estão em um projeto diferente.
Teste os nomes dos métodos . Eu gosto de nomear meus métodos WhenXXX_ExpectYYY. Isso torna clara a pré-condição e ajuda na documentação automatizada (à la TestDox). Isso é semelhante ao conselho do blog de testes do Google, mas com mais separação de pré-condições e expectativas. Por exemplo:
fonte
Eu uso o conceito Given-When-Then . Dê uma olhada neste pequeno artigo http://cakebaker.42dh.com/2009/05/28/given-when-then/ . O artigo descreve esse conceito em termos de BDD, mas você pode usá-lo no TDD também sem alterações.
fonte
Veja: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html
Para nomes de métodos de teste, pessoalmente considero muito útil o uso de nomes detalhados e auto-documentados (juntamente com os comentários do Javadoc que explicam melhor o que o teste está fazendo).
fonte
Acho que uma das coisas mais importantes é ser consistente em sua convenção de nomenclatura (e concordo com outros membros de sua equipe). Muitas vezes vejo muitas convenções diferentes usadas no mesmo projeto.
fonte
Recentemente, criei a seguinte convenção para nomear meus testes, suas classes e conter projetos, a fim de maximizar seus descritores:
Digamos que estou testando a
Settings
classe em um projeto noMyApp.Serialization
espaço para nome.Primeiro, criarei um projeto de teste com o
MyApp.Serialization.Tests
espaço para nome.Nesse projeto e, é claro, no namespace, criarei uma classe chamada
IfSettings
(salva como IfSettings.cs ).Digamos que estou testando o
SaveStrings()
método. -> Vou nomear o testeCanSaveStrings()
.Quando eu executo este teste, ele mostra o seguinte título:
MyApp.Serialization.Tests.IfSettings.CanSaveStrings
Eu acho que isso me diz muito bem o que está testando.
Obviamente, é útil que em inglês o substantivo "Tests" seja o mesmo que o verbo "tests".
Não há limite para a sua criatividade ao nomear os testes, para que possamos obter títulos de frases completos para eles.
Geralmente, os nomes dos testes precisam começar com um verbo.
Exemplos incluem:
DetectsInvalidUserInput
)ThrowsOnNotFound
)WillCloseTheDatabaseAfterTheTransaction
)etc.
Outra opção é usar "that" em vez de "if".
O último me salva as teclas e descreve mais exatamente o que estou fazendo, já que não sei, que o comportamento testado está presente, mas estou testando, se estiver.
[ Editar ]
Depois de usar a convenção de nomenclatura acima por um pouco mais agora, descobri que o prefixo If pode ser confuso ao trabalhar com interfaces. Acontece que a classe de teste IfSerializer.cs se parece muito com a interface ISerializer.cs na "Guia Arquivos abertos". Isso pode ser muito irritante ao alternar entre os testes, a classe que está sendo testada e sua interface. Como resultado, eu iria agora escolher que mais de Se como um prefixo.
Além disso, agora eu uso - apenas para métodos nas minhas classes de teste, pois não é considerado uma prática recomendada em nenhum outro lugar - o "_" para separar palavras nos nomes dos meus métodos de teste, como em:
Acho que isso é mais fácil de ler.
[ Fim da edição ]
Espero que isso gere mais algumas idéias, pois considero nomear testes de grande importância, pois isso pode poupar muito tempo que, de outra forma, seria gasto tentando entender o que os testes estão fazendo (por exemplo, depois de retomar um projeto após um hiato prolongado) .
fonte
No VS + NUnit, costumo criar pastas no meu projeto para agrupar testes funcionais. Em seguida, crio classes de equipamentos de teste de unidade e nomeio-as de acordo com o tipo de funcionalidade que estou testando. Os métodos [Teste] são nomeados ao longo das linhas de
Can_add_user_to_domain
:fonte
Devo acrescentar que a manutenção de seus testes no mesmo pacote, mas em um diretório paralelo à origem que está sendo testada, elimina o inchaço do código quando você estiver pronto para implementá-lo sem ter que fazer muitos padrões de exclusão.
Eu pessoalmente gosto das melhores práticas descritas no "JUnit Pocket Guide" ... é difícil vencer um livro escrito pelo co-autor da JUnit!
fonte
o nome do caso de teste da classe Foo deve ser FooTestCase ou algo parecido (FooIntegrationTestCase ou FooAcceptanceTestCase) - já que é um caso de teste. consulte http://xunitpatterns.com/ para obter algumas convenções de nomenclatura padrão, como teste, caso de teste, dispositivo de teste, método de teste etc.
fonte