Isto é.
Mesmo se você fizer apenas testes de unidade, não é incomum ter mais código nos testes do que o código realmente testado. Não há nada de errado com isso.
Considere um código simples:
public void SayHello(string personName)
{
if (personName == null) throw new NullArgumentException("personName");
Console.WriteLine("Hello, {0}!", personName);
}
Quais seriam os testes? Existem pelo menos quatro casos simples para testar aqui:
O nome da pessoa é null
. A exceção é realmente lançada? São pelo menos três linhas de código de teste para escrever.
O nome da pessoa é "Jeff"
. Nós recebemos uma "Hello, Jeff!"
resposta? São quatro linhas de código de teste.
O nome da pessoa é uma sequência vazia. Que resultado esperamos? Qual é a saída real? Pergunta secundária: corresponde aos requisitos funcionais? Isso significa outras quatro linhas de código para o teste de unidade.
O nome da pessoa é curto o suficiente para uma sequência, mas muito longo para ser combinado com "Hello, "
o ponto de exclamação. O que acontece?
Isso requer muito código de teste. Além disso, as partes mais elementares do código geralmente exigem código de configuração que inicializa os objetos necessários para o código em teste, o que também leva a escrever stubs e zombarias, etc.
Se a proporção for muito grande, nesse caso, você pode verificar algumas coisas:
Existe duplicação de código nos testes? O fato de ser um código de teste não significa que o código deve ser duplicado (cópia-colado) entre testes semelhantes: essa duplicação dificultará a manutenção desses testes.
Existem testes redundantes? Como regra geral, se você remover um teste de unidade, a cobertura da filial deverá diminuir. Caso contrário, isso pode indicar que o teste não é necessário, pois os caminhos já estão cobertos por outros testes.
Você está testando apenas o código que deve testar? Não é esperado que você teste a estrutura subjacente das bibliotecas de terceiros, mas exclusivamente o código do próprio projeto.
Com testes de fumaça, testes de sistema e integração, testes funcionais e de aceitação e testes de estresse e carga, você adiciona ainda mais código de teste, portanto, não é de se preocupar que você tenha quatro ou cinco LOC de testes para cada LOC do código real.
Uma observação sobre TDD
Se você estiver preocupado com o tempo que leva para testar seu código, pode ser que você esteja fazendo errado, ou seja, primeiro o código, testes depois. Nesse caso, o TDD pode ajudar incentivando você a trabalhar em iterações de 15 a 45 segundos, alternando entre código e testes. De acordo com os defensores do TDD, ele acelera o processo de desenvolvimento, reduzindo o número de testes que você precisa fazer e, mais importante, a quantidade de código comercial a ser escrito e especialmente reescrito para teste.
¹ Deixe n ser o comprimento máximo de uma cadeia de caracteres . Podemos chamar SayHello
e passar por referência uma cadeia de comprimento n -1 que deve funcionar perfeitamente. Agora, na Console.WriteLine
etapa, a formatação deve terminar com uma sequência de comprimento n + 8, que resultará em uma exceção. Possivelmente, devido aos limites de memória, mesmo uma string contendo n / 2 caracteres levará a uma exceção. A pergunta que se deve fazer é se esse quarto teste é um teste de unidade (parece um, mas pode ter um impacto muito maior em termos de recursos em comparação com os testes de unidade médios) e se ele testa o código real ou a estrutura subjacente.