Respostas às suas perguntas
Existe algo como ter muitos testes de unidade?
Claro ... Você pode, por exemplo, ter vários testes que parecem diferentes à primeira vista, mas realmente testam a mesma coisa (depende logicamente das mesmas linhas de código de aplicativo "interessante" em teste).
Ou você pode testar as partes internas do seu código que nunca surgem externamente (ou seja, não fazem parte de nenhum tipo de contrato de interface), onde se pode discutir se isso faz sentido. Por exemplo, o texto exato das mensagens de log internas ou o que for.
Fui encarregado de escrever testes de unidade para um aplicativo existente. Depois de terminar meu primeiro arquivo, tenho 717 linhas de código de teste para 419 linhas de código original.
Isso me parece bastante normal. Seus testes gastam muitas linhas de código na instalação e desmontagem, além dos testes reais. A proporção pode melhorar ou não. Eu próprio sou bastante pesado em testes e frequentemente investo mais tempo e local nos testes do que o código real.
Essa proporção se tornará incontrolável à medida que aumentamos nossa cobertura de código?
A proporção não leva em consideração tanto. Existem outras qualidades de testes que tendem a torná-los incontroláveis. Se você precisar refatorar regularmente vários testes ao fazer alterações bastante simples no seu código, dê uma boa olhada nos motivos. E essas não são quantas linhas você tem, mas como você aborda a codificação dos testes.
Minha compreensão do teste de unidade era testar cada método da classe para garantir que todos os métodos funcionassem conforme o esperado.
Isso é correto para testes "unitários" no sentido estrito. Aqui, "unidade" é algo como um método ou uma classe. O objetivo do teste "unitário" é testar apenas uma unidade específica de código, não o sistema inteiro. Idealmente, você removeria todo o resto do sistema (usando dobros ou outros enfeites).
No entanto, na solicitação de recebimento, meu líder técnico observou que eu deveria me concentrar em testes de nível superior.
Então você caiu na armadilha de supor que as pessoas realmente significavam testes de unidade quando diziam testes de unidade. Eu conheci muitos programadores que dizem "teste de unidade", mas significam algo bem diferente.
Ele sugeriu testar 4-5 casos de uso mais usados com a classe em questão, em vez de testar exaustivamente cada função.
Claro, concentrar-se apenas nos 80% dos códigos importantes também reduz a carga ... Compreendo que você pense muito em seu chefe, mas isso não me parece a melhor opção.
Para mim, 100% de cobertura de teste de unidade é uma meta elevada, mas mesmo que atingíssemos apenas 50%, saberíamos que 100% desses 50% estavam cobertos.
Não sei o que é "cobertura de teste de unidade". Suponho que você queira dizer "cobertura de código", ou seja, depois de executar o conjunto de testes, todas as linhas de código (= 100%) foram executadas pelo menos uma vez.
Essa é uma boa métrica de estimativa, mas de longe não é o melhor padrão para o qual alguém poderia atirar. Apenas executar linhas de código não é a imagem toda; isso não leva em conta caminhos diferentes por meio de ramificações aninhadas e complicadas, por exemplo. É mais uma métrica que aponta o dedo para partes de código que são testadas muito pouco (obviamente, se uma classe tem 10% ou 5% de cobertura de código, algo está errado); por outro lado, uma cobertura de 100% não informa se você testou o suficiente ou se testou corretamente.
Teste de integração
Irrita-me substancialmente quando as pessoas estão constantemente falando sobre testes de unidade hoje, por padrão. Na minha opinião (e experiência), o teste de unidade é ótimo para bibliotecas / APIs; em áreas mais voltadas para negócios (onde falamos de casos de uso, como na pergunta em questão), elas não são necessariamente a melhor opção.
Para o código geral do aplicativo e para as empresas comuns (onde é importante ganhar dinheiro, cumprir prazos e satisfazer a satisfação do cliente, é importante evitar erros que estão diretamente na cara do usuário ou que podem levar a desastres reais - não estamos falando lançamentos de foguetes da NASA aqui), testes de integração ou de recursos são muito mais úteis.
Aqueles andam de mãos dadas com o Desenvolvimento Orientado ao Comportamento ou ao Desenvolvimento Orientado a Recursos; aqueles não funcionam com testes de unidade (estritos), por definição.
Para mantê-lo curto (ish), um teste de integração / recurso exercita toda a pilha de aplicativos. Em um aplicativo baseado na Web, ele funcionaria como um navegador clicando no aplicativo (e não, obviamente, não precisa ser tão simplista, existem estruturas muito poderosas para fazer isso - confira http: // pepino. io por exemplo).
Ah, para responder às suas últimas perguntas: você faz com que toda a sua equipe tenha uma alta cobertura de teste, certificando-se de que um novo recurso seja programado apenas após a implementação e falha do teste. E sim, isso significa todos os recursos. Isso garante uma cobertura de recurso 100% (positiva). Por definição, garante que um recurso do seu aplicativo nunca "desapareça". Ele não garante uma cobertura de código de 100% (por exemplo, a menos que você programe ativamente recursos negativos, não estará exercitando seu tratamento de erros / tratamento de exceções).
Ele não garante um aplicativo sem erros; é claro que você deseja escrever testes de recursos para situações de bugs óbvias ou muito perigosas, entrada incorreta do usuário, hackers (por exemplo, gerenciamento de sessões, segurança e outros) etc .; mas mesmo a programação dos testes positivos tem um tremendo benefício e é bastante viável com estruturas modernas e poderosas.
Os testes de recursos / integração obviamente têm sua própria lata de worms (por exemplo, desempenho; teste redundante de estruturas de terceiros; como você geralmente não usa duplos, eles também tendem a ser mais difíceis de escrever, na minha experiência ...), mas eu ' d use um aplicativo 100% testado por recurso positivo em vez de um aplicativo 100% testado por unidade de cobertura de código (não biblioteca!) a qualquer dia.