Existe algum valor em escrever um teste de unidade que seja um subconjunto de outro teste?

14

Para dar um exemplo um pouco artificial, digamos que eu queira testar se uma função retorna dois números e se 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, então test_order falhará também. É uma prática recomendada escrever test_length ou ignorá-lo?

EDIT: note que nesta situação, ambos os testes são em sua maioria independentes uns dos outros, cada um pode ser executado isoladamente, ou podem ser executados em ordem inversa, isso não importa. Então, nenhuma dessas perguntas anteriores

é uma duplicata da acima.

    
por Mihai 12.01.2015 / 16:24
fonte

4 respostas

28

Pode haver valor, mas isso é um pouco de cheiro. Seus testes não são bem isolados (já que test_order realmente testa duas coisas) ou você está sendo muito dogmático em seus testes (fazendo dois testes testando a mesma coisa lógica).

No exemplo, eu mesclaria os dois testes juntos. Sim, significa que você tem várias afirmaçõ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.

    
por 12.01.2015 / 16:34
fonte
5

Seus testes devem ser explícitos. Não é completamente inferido que, se text_length falhar, test_order falhará.

Não sei como é o Python que você postou, mas se len(result) for 3, o primeiro falhará, mas o segundo poderá passar (e se não for em Python, então em linguagens como JavaScript, com certeza ).

Como você disse, você quer testar se a função retorna dois números e eles estão em ordem. Dois testes é.

    
por 12.01.2015 / 16:34
fonte
2

O único valor de test_length aqui é que, se tudo passar, sua própria presença indica que o "comprimento" foi testado.

Portanto, é realmente desnecessário ter ambos os testes. Mantenha apenas test_order , mas considere renomear test_length_and_order .

Aliás, acho que o uso de nomes que começam com test são um pouco desajeitados. Sou um strong defensor de nomes de testes que realmente descrevem a condição que você está afirmando.

    
por 12.01.2015 / 20:41
fonte
1

Eu deixaria esses testes separados se é assim que eles evoluíram para ser. Sim test_order provavelmente falhará sempre que test_length , mas você definitivamente sabe o motivo.

Também concordaria que, se o test_order aparecesse primeiro e você encontrasse uma falha testável, o resultado talvez não fosse dois valores, adicionar essa verificação como assert e renomear o teste para test_length_and_order faz sentido .

Se você tivesse que verificar também os tipos dos valores retornados eram inteiros, eu incluiria isso neste teste de resultados "omnibus".

Mas observe agora que você tem uma bateria de testes para o resultado de my_function() . Se houver vários contextos (ou, mais provavelmente, vários parâmetros) para testar isso, agora pode ser uma sub-rotina para testar todos os resultados de my_function() .

No entanto, quando escrevo testes de unidade, normalmente testo a borda e os casos ruins separadamente da boa entrada e da saída normal (parcialmente porque a maioria dos testes de "unidade" são geralmente testes de mini integração) e muitas vezes com várias afirmações, só são divididos em testes separados se falharem de maneiras em que eu acho que quero mais informações sem depuração.

Então eu provavelmente começaria com seus testes separados e expandiria test_length para test_length_and_types e deixaria test_order separado, assumindo que este último é visto como "processamento normal".

    
por 15.01.2015 / 02:21
fonte