Para dar um exemplo um pouco artificial, digamos que eu queira testar se uma função retorna dois números e que o primeiro é menor que o segundo:
def test_length():
result = my_function()
assert len(result) == 2
def test_order()
a, b = my_function()
assert a < b
Aqui, se test_length
falhar, test_order
também falhará. É uma prática recomendada escrever test_length
ou pular?
EDIT: observe que, nessa situação, os dois testes são independentes em sua maioria, cada um pode ser executado isoladamente ou em ordem inversa, isso não importa. Portanto, nenhuma dessas perguntas anteriores
- Como devo testar a funcionalidade de uma função que usa outras funções nela?
- Preciso de teste de unidade se já tenho teste de integração?
- Como estruturar testes onde um teste é a instalação de outro teste?
- Como gerenciar a dependência de sucesso entre testes de unidade
é uma duplicata da acima.
unit-testing
Mihai
fonte
fonte
A
chamaB
e retorna o mesmo resultado, deve testar ambosA
eB
". Isso se refere mais à sobreposição dos testes, e não às funções sob teste. (Embora seja confuso como eles são nomeados atualmente).lambda: type('', (), {'__len__': lambda self: 2})()
passará a primeira, mas não a segunda.Respostas:
Pode haver valor, mas isso é um pouco de cheiro. Seus testes não são bem isolados (já que
test_order
realmente testam duas coisas) ou você está sendo dogmático demais (fazendo dois testes testando a mesma coisa lógica).No exemplo, eu mesclaria os dois testes. Sim, significa que você tem várias declarações. Que pena. Você ainda está testando uma única coisa - o resultado da função. Às vezes, no mundo real, isso significa fazer duas verificações.
fonte
my_function
não retornar exatamente dois valores, sem nenhuma afirmação - porque a atribuição resultará em uma exceção. Portanto, não há realmente a necessidade de usar várias declarações e duas verificações para testar a mesma coisa.Seus testes devem ser explícitos. Não é completamente inferido que, se text_length falhar, test_order falhará.
Não tenho certeza de como foi publicado em Python, mas se
len(result)
for 3, o primeiro falhará, mas o segundo poderá passar (e, se não for em Python, em idiomas como JavaScript, com certeza).Como você disse, você deseja testar se a função retorna dois números e se eles estão em ordem. São dois testes.
fonte
It's not completely inferred that if text_length fails test_order fails
- no Python, isso dará uma exceção.test_length
implica falha detest_order
. O fato de um par semelhante de testes escritos em Javascript não se comportar da mesma forma que esses dois testes python é irrelevante.O único valor
test_length
aqui é que, se tudo passar, sua presença indica que o "comprimento" foi testado.Portanto, é realmente desnecessário ter esses dois testes. Mantenha apenas,
test_order
mas considere renomeá-lotest_length_and_order
.Aliás, acho o uso de nomes que começam com
test
um pouco desajeitado. Sou um forte defensor dos nomes dos testes que descrevem a condição que você está afirmando.fonte
test
verruga é significativa para a estrutura de teste do Python. Qual dos necessidade claro que não mudar se você é um fã dele, mas não altera o peso do argumento necessário para impedir que alguém a usá-lo ;-)test_that_
, comotest_that_return_values_are_in_order
e assim por diante. Talvez uma versão futura da estrutura de teste resolva esse requisito de alguma forma.Eu deixaria esses testes separados se é assim que eles evoluíram. Sim,
test_order
é provável que falhe sempretest_length
que ocorrer , mas você definitivamente sabe o porquê.Concordo também que, se o
test_order
primeiro apareceu e você encontrou uma falha testável, o resultado possivelmente não foi de dois valores, adicionando essa verificação comoassert
e renomeando o teste paratest_length_and_order
fazer sentido.Se você também tivesse que verificar se os tipos de valores retornados eram números inteiros, incluiria isso neste teste de resultados "abrangente".
Mas observe que agora você tem uma bateria de testes para obter o resultado de
my_function()
. Se houver vários contextos (ou, mais provavelmente, vários parâmetros) para testar isso agora poderá ser uma sub-rotina para testar todos os resultadosmy_function()
.No entanto, quando escrevo testes de unidade, normalmente testo os casos extremos e ruins separadamente das boas entradas e saídas normais (em parte porque a maioria dos meus testes de "unidade" são geralmente mini testes de integração) e geralmente com várias afirmações, que são quebradas apenas em testes separados, se falharem nas maneiras em que acho que quero mais informações sem depuração.
Então eu provavelmente começaria com seus testes separados e expandiria
test_length
paratest_length_and_types
e deixariatest_order
separados, supondo que o último seja visto como "processamento normal".fonte