O que é uma% razoável de cobertura de código para testes de unidade (e por que)? [fechadas]

605

Se você exigisse uma porcentagem mínima de cobertura de código para testes de unidade, talvez até como um requisito para se comprometer com um repositório, o que seria?

Por favor, explique como você chegou à sua resposta (já que, se tudo o que você fez foi escolher um número, eu poderia ter feito isso sozinho;)

sanidade
fonte
Hoje em dia, muitos IDEs vêm com destaque para a cobertura; certifique-se de cobrir as partes mais importantes do código pelo menos do que pensar em atingir uma determinada porcentagem.
Todos Іѕ Vаиітy
4
% Símbolo é cheiro de código para métricas (também% é um cheiro besteira em geral)
Hernán Eche
Os testes de unidade por definição podem ser métodos individuais, classes inteiras ou módulos inteiros. Mesmo se você testar todos os métodos, poderá não testar todos os caminhos ou todas as combinações que um usuário encontrará. A situação fica mais complexa com declarações, cobertura de agências e MCDCs.
Ska
Por que essa pergunta não foi excluída ou editada corretamente. Ele reuniu tanto interesse, mas é totalmente enganador.
Ska

Respostas:

1391

Essa prosa de Alberto Savoia responde exatamente a essa pergunta (de uma maneira bem divertida!):

http://www.artima.com/forums/flat.jsp?forum=106&thread=204677

Testivus na cobertura de teste

Certa manhã, um programador perguntou ao grande mestre:

“Estou pronto para escrever alguns testes de unidade. Qual cobertura de código devo procurar? ”

O grande mestre respondeu:

"Não se preocupe com a cobertura, basta escrever alguns bons testes."

O programador sorriu, curvou-se e saiu.

...

Mais tarde naquele dia, um segundo programador fez a mesma pergunta.

O grande mestre apontou para uma panela de água fervente e disse:

"Quantos grãos de arroz devo colocar nessa panela?"

O programador, parecendo intrigado, respondeu:

Como posso te contar? Depende de quantas pessoas você precisa alimentar, de como estão com fome, de quais outros alimentos você serve, de quanto arroz você tem disponível e assim por diante. ”

"Exatamente", disse o grande mestre.

O segundo programador sorriu, curvou-se e saiu.

...

No final do dia, um terceiro programador veio e fez a mesma pergunta sobre a cobertura do código.

"Oitenta por cento e nada menos!" Respondeu o mestre com uma voz severa, batendo com o punho na mesa.

O terceiro programador sorriu, curvou-se e saiu.

...

Após essa última resposta, um jovem aprendiz se aproximou do grande mestre:

“Grande mestre, hoje ouvi que você responde à mesma pergunta sobre cobertura de código com três respostas diferentes. Por quê?"

O grande mestre levantou-se da cadeira:

"Venha tomar um chá fresco comigo e vamos conversar sobre isso."

Depois de encherem suas xícaras com chá verde quente, o grande mestre começou a responder:

“O primeiro programador é novo e está começando a testar. No momento, ele tem muito código e nenhum teste. Ele tem um longo caminho a percorrer; concentrar-se na cobertura do código nesse momento seria deprimente e bastante inútil. É melhor se acostumar a escrever e executar alguns testes. Ele pode se preocupar com a cobertura mais tarde.

“O segundo programador, por outro lado, é bastante experiente em programação e teste. Quando respondi perguntando a ela quantos grãos de arroz eu deveria colocar em uma panela, ajudei-a a perceber que a quantidade de testes necessários depende de vários fatores, e ela os conhece melhor do que eu - afinal, é o código dela . Não existe uma resposta simples e simples, e ela é inteligente o suficiente para lidar com a verdade e trabalhar com isso. ”

“Entendo”, disse o jovem aprendiz, “mas se não há uma resposta simples e simples, por que você respondeu ao terceiro programador 'oitenta por cento e nada menos'?”

O grande mestre riu tão alto e alto que sua barriga, evidência de que ele bebeu mais do que apenas chá verde, caiu de um lado para o outro.

"O terceiro programador quer apenas respostas simples - mesmo quando não há respostas simples ... e depois não as segue de qualquer maneira."

O jovem aprendiz e o grande mestre grisalho terminaram de tomar seu chá em silêncio contemplativo.

Jon Limjap
fonte
62
Soa como um argumento contra o conceito geral de cobertura de código, como uma métrica para avaliar a utilidade dos testes de unidade. Tenho certeza de que todos concordam que não é uma métrica perfeita, mas esperamos que a experiência pessoal mostre alguma correlação entre o% de CC e a eficácia do teste de unidade ...
sanity
16
sanidade - sua declaração é refletida precisamente pela resposta ao "segundo desenvolvedor". A experiência pessoal deve ditá-la.
Jon Limjap
167
Resposta perfeita. Métricas não produzem um bom código. Você pode escrever códigos ruins com 100% de cobertura e isso não faz com que o código funcione bem. +1 de mim, pena que eu não posso mais :)
Rob Cooper
15
4 anos depois, e ainda útil. Só peguei isso em dois dos meus colegas esta manhã.
SickHippie
9
Para mim, essa anedota representa uma visão idealista. No mundo real das equipes de projeto com prioridades concorrentes, a cobertura do código chega a 0%. Precisamos de um número necessário para criar o hábito de teste de unidade dentro da equipe. Cheguei a essa pergunta procurando algumas orientações sobre como determinar esse número para uma área com a qual não estou muito familiarizado, e isso realmente não ajuda em nada. Estou feliz que as pessoas em outros cenários estejam achando isso útil.
samspot
85

A cobertura de código é uma métrica enganosa se a sua meta é 100% de cobertura (em vez de 100% de teste de todos os recursos).

  • Você pode obter 100% pressionando todas as linhas uma vez. No entanto, você ainda pode deixar de testar uma sequência específica (caminho lógico) na qual essas linhas são atingidas.
  • Você não conseguiu obter 100%, mas ainda assim testou todos os seus caminhos de código usados ​​a 80% / freq. Fazer testes que testem todos os 'throw ExceptionTypeX' ou guarda de programação defensiva semelhante que você colocou é um 'bom ter' e não um 'deve ter'

Portanto, confie em você ou em seus desenvolvedores para ser minucioso e cobrir todos os caminhos do código. Seja pragmático e não persiga a cobertura mágica de 100%. Se você TDD seu código, você deve obter uma cobertura de 90% + como bônus. Use a cobertura de código para destacar os trechos de código que você perdeu (não deve acontecer se você fizer o TDD .. pois você escreve o código apenas para fazer um teste ser aprovado. Nenhum código pode existir sem o teste do parceiro).

Gishu
fonte
4
- Exceções - se você não testar seu tratamento de exceções, como sabe que seu código não explode quando isso acontece? - Setters / Getters - sensíveis ao contexto, suponho, mas certamente seus testes devem executá-los como parte do conjunto de testes, e se não estiverem, eles realmente estão sendo usados?
Tddmonkey 30/01/09
1
As exceções devem ser excepcionais - não deveriam acontecer. Se o fizerem, você registra o ponto de falha e fiança. Você não pode testar todas as exceções que possam acontecer. Se o aplicativo deve lidar com um caminho / evento não feliz, você deve fazer um teste. Os acessadores podem ser adicionados para futuros clientes .. depende #
3025
5
Não sei ao certo o que você quer dizer com seu segundo ponto ", mas ainda testei todos os seus caminhos de código". Se você de fato quer dizer cobertura de caminho completo, não, não poderá ter cobertura de caminho completo sem 100% de cobertura de linha / filial / decisão. De fato, a cobertura do caminho completo geralmente não é possível em qualquer programa não trivial, devido à natureza combinatória das ramificações nos caminhos de geração. en.wikipedia.org/wiki/Code_coverage#Other_coverage_criteria
Zach Burlingame
3
Você não testa todas as exceções possíveis; claro que você não pode fazer isso. Você deve tentar testar cada bloco de código que lida com exceções. Por exemplo, se você exige que, quando o bloco X lança uma exceção, a exceção é registrada no banco de dados, a faixa verde na parte inferior da tela fica vermelha e um e-mail é enviado ao Papa; então é isso que você deve testar. Mas você não precisa testar todas as exceções possíveis que possam acionar esses eventos.
Dawood ibn Kareem
2
+1 em "Use a cobertura de código para destacar os trechos de código que você perdeu". É basicamente para isso que serve essa métrica.
beluchin
61

A cobertura do código é excelente, mas a cobertura da funcionalidade é ainda melhor. Não acredito em cobrir todas as linhas que escrevo. Mas acredito em escrever 100% de cobertura de teste de todas as funcionalidades que desejo fornecer (mesmo para os recursos adicionais interessantes que eu acompanhei e que não foram discutidos durante as reuniões).

Eu não me importo se eu teria um código que não é coberto nos testes, mas eu me importaria se refatorasse meu código e acabasse tendo um comportamento diferente. Portanto, 100% de cobertura da funcionalidade é meu único alvo.

tofi9
fonte
4
Esta é uma resposta fantástica. O código que atende a seus requisitos é uma meta muito mais interessante do que o código que atende a alguma métrica arbitrária de cobertura LoC.
Dawood ibn Kareem
46
Se você pode fornecer todas as funcionalidades sem pressionar todas as linhas de código, o que essas linhas extras de código estão fazendo lá?
Jens Timmerman
4
@JensTimmerman teoricamente você está certo. No entanto, 100% de cobertura de código é muito caro em termos de tempo, e forçar minha equipe a fazer isso não apenas os desmotiva, mas também faz com que meu projeto seja executado dentro do prazo. Eu gosto de estar em algum lugar no meio, e a funcionalidade de teste (chame: teste de integração) é o que me sinto confortável. Qual código eu não testei? Tratamento de exceções técnicas, (faixa / parâmetro) verificações que podem ser necessárias. Em resumo, todo o encanamento técnico que aprendi a aplicar por experiência própria ou pelas melhores práticas que li sobre.
tofi9
2
Eu dei um passo adiante, fazendo uma lista de situações comuns que deveriam ser incluídas ou excluídas dos testes. Dessa forma, nunca estávamos alcançando um percentual, mas uma cobertura funcional de todas as partes da base de código em funcionamento.
Skeeterdrums
58

A resposta aceita faz um bom argumento - não há um único número que faça sentido como padrão para cada projeto. Existem projetos que simplesmente não precisam desse padrão. Onde a resposta aceita é insuficiente, na minha opinião, é descrever como alguém pode tomar essa decisão para um determinado projeto.

Vou tentar. Não sou especialista em engenharia de testes e ficaria feliz em ver uma resposta mais informada.

Quando definir os requisitos de cobertura de código

Primeiro, por que você deseja impor esse padrão em primeiro lugar? Em geral, quando você deseja introduzir confiança empírica em seu processo. O que quero dizer com "confiança empírica"? Bem, a verdadeira meta de correção . Para a maioria dos softwares, não podemos saber isso em todas as entradas, por isso decidimos dizer que o código é bem testado . Isso é mais compreensível, mas ainda é um padrão subjetivo: sempre estará aberto para debater se você o encontrou ou não. Esses debates são úteis e devem ocorrer, mas também expõem incertezas.

A cobertura do código é uma medida objetiva: depois de ver seu relatório de cobertura, não há ambiguidade sobre se os padrões foram cumpridos são úteis. Isso prova a correção? Nem um pouco, mas ele tem uma relação clara com o quão bem testado é o código, que por sua vez é a melhor maneira de aumentar a confiança em sua correção. A cobertura do código é uma aproximação mensurável das qualidades incomensuráveis ​​com as quais nos preocupamos.

Alguns casos específicos em que ter um padrão empírico podem agregar valor:

  • Satisfazer as partes interessadas. Para muitos projetos, existem vários atores interessados ​​na qualidade do software que podem não estar envolvidos no desenvolvimento diário do software (gerentes, líderes técnicos, etc.) Dizendo "vamos escrever todos os os testes de que realmente precisamos "não são convincentes: eles precisam confiar inteiramente ou verificar com uma supervisão rigorosa contínua (assumindo que eles tenham o conhecimento técnico para fazer isso.) Fornecer padrões mensuráveis ​​e explicar como eles se aproximam razoavelmente dos objetivos reais é melhor.
  • Normalizar o comportamento da equipe. Partes interessadas de lado, se você estiver trabalhando em uma equipe em que várias pessoas estão escrevendo código e testes, há espaço para ambiguidade no que se qualifica como "bem testado". Todos os seus colegas têm a mesma idéia de que nível de teste é bom o suficiente? Provavelmente não. Como você reconcilia isso? Encontre uma métrica com a qual todos concordem e aceite-a como uma aproximação razoável. Isso é especialmente útil (mas não exclusivamente) em equipes grandes, onde os leads podem não ter supervisão direta sobre os desenvolvedores juniores, por exemplo. As redes de confiança também são importantes, mas sem medições objetivas, é fácil o comportamento do grupo se tornar inconsistente, mesmo que todos estejam agindo de boa fé.
  • Para se manter honesto. Mesmo se você for o único desenvolvedor e o único interessado no seu projeto, talvez tenha certas qualidades em mente para o software. Em vez de fazer avaliações subjetivas contínuas sobre o quão bem testado o software é (o que dá trabalho), você pode usar a cobertura de código como uma aproximação razoável e permitir que as máquinas a medam para você.

Quais métricas usar

A cobertura do código não é uma métrica única; existem várias maneiras diferentes de medir a cobertura. Qual deles você pode definir um padrão depende do que você está usando esse padrão para satisfazer.

Usarei duas métricas comuns como exemplos de quando você pode usá-las para definir padrões:

  • Cobertura de declaração : qual porcentagem de declarações foi executada durante o teste? Útil para ter uma noção da cobertura física do seu código: Quanto do código que eu escrevi eu realmente testei?
    • Esse tipo de cobertura suporta um argumento de correção mais fraco, mas também é mais fácil de obter. Se você está apenas usando a cobertura de código para garantir que as coisas sejam testadas (e não como um indicador da qualidade do teste além disso), a cobertura da declaração provavelmente é suficiente.
  • Cobertura de ramificação : Quando existe uma lógica de ramificação (por exemplo, uma if), ambas as ramificações foram avaliadas? Isso dá uma noção melhor da cobertura lógica do seu código: Quantos dos possíveis caminhos que meu código pode seguir eu testei?
    • Esse tipo de cobertura é um indicador muito melhor de que um programa foi testado em um conjunto abrangente de entradas. Se você estiver usando a cobertura de código como sua melhor aproximação empírica para ter certeza da exatidão, defina padrões com base na cobertura da filial ou similar.

Existem muitas outras métricas (a cobertura de linha é semelhante à cobertura de extratos, mas produz resultados numéricos diferentes para extratos de várias linhas, por exemplo; cobertura condicional e cobertura de caminho são semelhantes à cobertura de agências, mas refletem uma visão mais detalhada das possíveis permutações de execução do programa que você pode encontrar.)

Qual porcentagem exigir

Finalmente, voltando à pergunta original: se você definir os padrões de cobertura de código, qual deve ser esse número?

Espero que esteja claro neste momento que estamos falando de uma aproximação, para que qualquer número que escolhermos seja inerentemente aproximado.

Alguns números que você pode escolher:

  • 100% . Você pode escolher isso porque deseja ter certeza de que tudo foi testado. Isso não fornece informações sobre a qualidade dos testes, mas informa que alguns testes de alguma qualidade afetaram todas as afirmações (ou ramificações etc.). Novamente, isso volta ao grau de confiança: se sua cobertura estiver abaixo de 100% , você sabe que algum subconjunto do seu código não foi testado.
    • Alguns podem argumentar que isso é bobagem, e você só deve testar as partes do seu código que são realmente importantes. Eu diria que você também deve manter apenas as partes do seu código que são realmente importantes. A cobertura do código também pode ser aprimorada com a remoção do código não testado.
  • 99% (ou 95%, outros números nos anos 90). Apropriado nos casos em que você deseja transmitir um nível de confiança semelhante a 100%, mas deixe uma margem para não se preocupar com o canto ocasionalmente difícil de testar. código.
  • 80% . Já vi esse número em uso algumas vezes e não sei exatamente onde ele se origina. Eu acho que pode ser uma estranha apropriação indébita da regra 80-20; geralmente, a intenção aqui é mostrar que a maior parte do seu código é testada. (Sim, 51% também seria "a maioria", mas 80% reflete mais o que a maioria das pessoas entende por maioria.) Isso é apropriado para casos intermediários em que "bem testado" não é uma alta prioridade (você não não quero desperdiçar esforços em testes de baixo valor), mas é uma prioridade suficiente para que você ainda queira ter algum padrão.

Não vi números abaixo de 80% na prática e não consigo imaginar um caso em que alguém os possa definir. O papel desses padrões é aumentar a confiança na correção, e números abaixo de 80% não são particularmente inspiradores de confiança. (Sim, isso é subjetivo, mas, novamente, a idéia é fazer a escolha subjetiva uma vez quando você definir o padrão e, em seguida, usar uma medida objetiva daqui para frente.)

Outras notas

O exposto acima pressupõe que a correção é o objetivo. A cobertura do código é apenas informação; pode ser relevante para outros objetivos. Por exemplo, se você está preocupado com a manutenção, provavelmente se preocupa com o acoplamento frouxo, o que pode ser demonstrado pela testabilidade, que por sua vez pode ser medida (em certas modas) pela cobertura do código. Portanto, seu padrão de cobertura de código fornece uma base empírica para aproximar também a qualidade da "manutenção".

tela de matar
fonte
Boa resposta. Você pode me ajudar a encontrar cobertura de funcionalidade por meio de testes de unidade? Alguma ferramenta que pode me ajudar a conseguir isso?
23916 curlyreggie
2
Ótima resposta. É o único que se concentra em testar como um problema de equipe em um ambiente industrial. Não consigo revisar tudo e minha equipe é muito brilhante, mas verde. Estabeleci um percentual mínimo de 90% em um novo projeto como uma verificação de sanidade para desenvolvedores juniores, não porque acredito que seja "suficiente". "90%" e "positivo, negativo e nulo" são mantras fáceis para jovens desenvolvedores brilhantes que eu sei que farão um bom trabalho, mas não têm a experiência necessária para escrever esse caso de teste extra que é irritante para os desenvolvedores. de volta à sua mente.
0x1mason
2
Eu acho que esta é a melhor resposta disponível.
Erro # # 9/18
27

Minha cobertura de código favorita é 100% com um asterisco. O asterisco vem porque eu prefiro usar ferramentas que me permitam marcar certas linhas como linhas que "não contam". Se eu cobri 100% das linhas que "contam", eu terminei.

O processo subjacente é:

  1. Eu escrevo meus testes para exercitar todas as funcionalidades e casos extremos em que consigo pensar (geralmente trabalhando na documentação).
  2. Eu corro as ferramentas de cobertura de código
  3. Examino todas as linhas ou caminhos não cobertos e os que considero não importantes ou inacessíveis (devido à programação defensiva) que marquei como não contando
  4. Escrevo novos testes para cobrir as linhas ausentes e melhorar a documentação se esses casos extremos não forem mencionados.

Dessa forma, se eu e meus colaboradores adicionarmos um novo código ou alterarmos os testes no futuro, há uma linha brilhante para nos dizer se perdemos algo importante - a cobertura caiu abaixo de 100%. No entanto, também oferece flexibilidade para lidar com diferentes prioridades de teste.

Epônimo
fonte
3
@ErikE Asterix é, é claro, um guerreiro baixo, mas destemido da Gália, que cria exceções à monótona ocupação romana e, portanto, o pequeno símbolo tipográfico sinalizando exceções recebeu seu nome. (Mais a sério, obrigado, eu já corrigiu o erro ortográfico.)
epónimo
3
Você gostaria de incluir as "ferramentas que permitem [você] marcar determinadas linhas como linhas que não contam"?
domdambrogia
2
@domdambrogia Como exemplo em PHP, se você estiver usando a biblioteca de cobertura de código da Bergmann, anote uma linha com // @codeCoverageIgnoree ela será excluída da cobertura.
bispo
19

Eu teria outro aneto em cobertura de teste que gostaria de compartilhar.

Temos um grande projeto em que, no twitter, observei que, com 700 testes de unidade, temos apenas 20% de cobertura de código .

Scott Hanselman respondeu com palavras de sabedoria :

São os 20% CERTOS? São os 20% que representam o código que seus usuários mais acessam? Você pode adicionar mais 50 testes e adicionar apenas 2%.

Novamente, ele volta ao meu Testivus na resposta de cobertura de código . Quanto arroz você deve colocar na panela? Depende.

Jon Limjap
fonte
Obviamente, tem que haver bom senso lá. Não é muito útil se os 50% do código que você está testando são comentários.
Sanity
2
Está mais nas linhas de ... a sua cobertura é gasta na funcionalidade principal do seu aplicativo ou está testando inutilmente recursos triviais / agradáveis?
Jon Limjap
Soa como uma grande% do seu código ou é clichê, ou tratamento de exceções, ou condicional coisas "modo de depuração"
Erik Aronesty
8

Para um sistema bem projetado, onde os testes de unidade impulsionaram o desenvolvimento desde o início, eu diria que 85% é um número bastante baixo. Classes pequenas projetadas para serem testáveis ​​não devem ser difíceis de cobrir melhor que isso.

É fácil descartar esta pergunta com algo como:

  • As linhas cobertas não são iguais à lógica testada e não se deve ler muito a porcentagem.

É verdade, mas há alguns pontos importantes a serem feitos sobre a cobertura do código. Na minha experiência, essa métrica é realmente bastante útil, quando usada corretamente. Dito isto, eu não vi todos os sistemas e tenho certeza de que existem muitos deles onde é difícil ver a análise de cobertura de código agregando algum valor real. O código pode parecer tão diferente e o escopo da estrutura de teste disponível pode variar.

Além disso, meu raciocínio refere-se principalmente a ciclos de feedback de teste bastante curtos. Para o produto que estou desenvolvendo, o menor ciclo de feedback é bastante flexível, cobrindo tudo, desde testes de classe a sinalização entre processos. O teste de um subproduto entregável normalmente leva 5 minutos e, para um ciclo de feedback tão curto, é realmente possível usar os resultados do teste (e especificamente a métrica de cobertura de código que estamos vendo aqui) para rejeitar ou aceitar confirmações no repositório.

Ao usar a métrica de cobertura de código, você não deve apenas ter uma porcentagem fixa (arbitrária) que deve ser cumprida. Fazer isso não oferece os benefícios reais da análise de cobertura de código na minha opinião. Em vez disso, defina as seguintes métricas:

  • Low Water Mark (LWM), o menor número de linhas descobertas já vistas no sistema em teste
  • High Water Mark (HWM), a maior porcentagem de cobertura de código já vista para o sistema em teste

O novo código só pode ser adicionado se não ultrapassarmos o LWM e não o HWM. Em outras palavras, a cobertura do código não pode diminuir e o novo código deve ser coberto. Observe como eu digo que deve e não deve (explicado abaixo).

Mas isso não significa que será impossível limpar o lixo velho e bem testado, do qual você não serve mais? Sim, e é por isso que você precisa ser pragmático sobre essas coisas. Há situações em que as regras precisam ser quebradas, mas para a sua integração diária típica, minha experiência é que essas métricas são bastante úteis. Eles dão as duas implicações a seguir.

  • O código testável é promovido. Ao adicionar novo código, você realmente precisa fazer um esforço para torná-lo testável, porque precisará tentar cobrir tudo isso com seus casos de teste. Código testável é geralmente uma coisa boa.

  • A cobertura de teste para código legado está aumentando com o tempo. Ao adicionar novo código e não poder cobri-lo com um caso de teste, pode-se tentar cobrir algum código legado para contornar a regra LWM. Essa trapaça às vezes necessária, pelo menos, dá o efeito colateral positivo de que a cobertura do código legado aumentará com o tempo, tornando a aplicação aparentemente rigorosa dessas regras bastante pragmática na prática.

E, novamente, se o loop de feedback for muito longo, pode ser completamente impraticável configurar algo assim no processo de integração.

Também gostaria de mencionar mais dois benefícios gerais da métrica de cobertura de código.

  • A análise de cobertura de código faz parte da análise dinâmica de código (em oposição à estática, ou seja, Lint). Problemas encontrados durante a análise dinâmica de código (por ferramentas como a família purify, http://www-03.ibm.com/software/products/en/rational-purify-family ) são coisas como leituras de memória não inicializada (UMR), vazamentos de memória etc. Esses problemas só podem ser encontrados se o código for coberto por um caso de teste executado . O código que é o mais difícil de cobrir em um caso de teste são geralmente os casos anormais no sistema, mas se você deseja que o sistema falhe normalmente (ou seja, rastreamento de erros em vez de travamento), pode ser necessário esforçar-se para cobrir os casos anormais. na análise dinâmica de código também. Com apenas um pouco de má sorte, um UMR pode levar a um segfault ou pior.

  • As pessoas se orgulham de manter 100% do novo código e discutem problemas de teste com uma paixão semelhante a outros problemas de implementação. Como essa função pode ser escrita de maneira mais testável? Como você tentaria cobrir esse caso anormal, etc.

E um negativo, por completude.

  • Em um grande projeto com muitos desenvolvedores envolvidos, todo mundo não será um gênio dos testes, com certeza. Algumas pessoas tendem a usar a métrica de cobertura de código como prova de que o código foi testado e isso está muito longe da verdade , conforme mencionado em muitas das outras respostas a esta pergunta. É uma métrica que pode oferecer bons benefícios se usada corretamente, mas se for mal usada, pode levar a testes ruins. Além dos efeitos colaterais muito valiosos mencionados acima, uma linha coberta mostra apenas que o sistema em teste pode alcançar essa linha para alguns dados de entrada e que pode ser executado sem travar ou travar.
Martin G
fonte
7

Se este fosse um mundo perfeito, 100% do código seria coberto por testes de unidade. No entanto, como esse NÃO é um mundo perfeito, é uma questão do que você tem tempo. Como resultado, recomendo focar menos em uma porcentagem específica e focar mais nas áreas críticas. Se o seu código estiver bem escrito (ou pelo menos um fac-símile razoável), deve haver vários pontos-chave nos quais as APIs estão expostas a outro código.

Concentre seus esforços de teste nessas APIs. Verifique se as APIs estão 1) bem documentadas e 2) têm casos de teste escritos que correspondem à documentação. Se os resultados esperados não corresponderem aos documentos, você terá um erro no seu código, documentação ou casos de teste. Todos os quais são bons para avaliar.

Boa sorte!

64BitBob
fonte
6

Muitas lojas não valorizam os testes; portanto, se você estiver acima de zero, pelo menos há alguma apreciação do valor - então, sem dúvida, zero não é ruim, pois muitas ainda são zero.

No mundo .Net, as pessoas costumam citar 80% como razoáveis. Mas eles dizem isso no nível da solução. Prefiro avaliar no nível do projeto: 30% pode ser bom para o projeto de interface do usuário se você tiver o Selenium, etc ou testes manuais, 20% para o projeto da camada de dados pode ser bom, mas mais de 95% pode ser bastante viável para os negócios camada de regras, se não for totalmente necessário. Portanto, a cobertura geral pode ser, digamos, 60%, mas a lógica crítica dos negócios pode ser muito maior.

Eu também ouvi isso: aspirar a 100% e você atingirá 80%; mas aspire a 80% e atingirá 40%.

Conclusão: aplique a regra 80:20 e deixe que a contagem de bugs do seu aplicativo o guie.

Greg Trevellick
fonte
5

A cobertura do código é apenas outra métrica. Por si só, pode ser muito enganador (consulte www.thoughtworks.com/insights/blog/are-test-coverage-metrics-overrated ). Portanto, seu objetivo não deve ser atingir 100% de cobertura do código, mas garantir que você teste todos os cenários relevantes do seu aplicativo.

klementtt
fonte
4

85% seria um bom ponto de partida para os critérios de check-in.

Provavelmente eu escolheria uma variedade de barras mais altas para os critérios de envio - dependendo da criticidade dos subsistemas / componentes sendo testados.

stephbu
fonte
54
Como você chegou a essa porcentagem?
sanity
Como nota de rodapé - isso pode ser confuso para projetos em que a automação é difícil - como sempre seja pragmático sobre o que é viável ou desejável.
stephbu
4
Principalmente através da experimentação. É muito fácil obter uma cobertura de código de 80 a 90% para testes de unidade relacionados ao Dev - subir mais alto normalmente requer intervenção divina de teste - ou caminhos de código realmente simples.
stephbu
1
Começo normalmente com 1) principais caminhos de código de tempo de execução 2) casos óbvios de exceção que explico explicitamente 3) casos condicionais que terminam com "falha" Isso geralmente leva você ao intervalo 70-80 refatoração para permitir a injeção de métodos etc. Geralmente, dedico pelo menos tanto tempo para escrever / refatorar testes relacionados ao desenvolvedor quanto o próprio código principal.
stephbu
4

Eu uso cobertura, e qualquer que seja a porcentagem, eu recomendaria manter os valores na tarefa de verificação de cobertura atualizados. No mínimo, continue aumentando a taxa de alinhamento e a taxa de câmbio total para um valor abaixo da cobertura atual, mas nunca abaixe esses valores. Também vincule a propriedade de falha de construção do Ant a esta tarefa. Se a compilação falhar por falta de cobertura, você saberá o código adicionado de alguém, mas não o testou. Exemplo:

<cobertura-check linerate="0"
                 branchrate="0"
                 totallinerate="70"
                 totalbranchrate="90"
                 failureproperty="build.failed" />
Gary Kephart
fonte
4

Quando acho que meu código não é testado em unidade o suficiente e não tenho certeza do que testar em seguida, uso a cobertura para me ajudar a decidir o que testar em seguida.

Se eu aumentar a cobertura em um teste de unidade - sei que esse teste de unidade vale alguma coisa.

Isso vale para o código que não é coberto, 50% coberto ou 97% coberto.

brickner
fonte
3
Eu discordo completamente. Um teste de unidade só vale algo se houver uma chance de descobrir um bug (um bug que existe agora ou um bug de regressão no futuro); ou se ajudar a documentar o comportamento da sua turma. Se um método é tão simples que realmente não pode falhar, como um getter de uma linha, existe um valor zero em fornecer um teste de unidade para ele.
Dawood ibn Kareem
6
Eu tinha bugs em getters de uma linha. Da minha experiência, não há código livre de bugs. Não existe um método que realmente não possa falhar.
Brickner
1
Supondo que seu getter de uma linha seja usado por outro código que você cobre e que os testes desse código sejam aprovados, você também cobriu indiretamente o getter de uma linha. Se você não está usando o getter, o que está fazendo no seu código? Eu concordo com David Wallace ... não há necessidade de testar diretamente funções auxiliares simples que são usadas em outros lugares se o código e os testes que dependem do auxiliar não mostrarem que pode haver um problema com ele.
Lowell Montgomery
@LowellMontgomery e se o teste do seu outro código falhar por causa do getter de uma linha (que não foi testado)? Se houvesse um teste para a linha única, seria muito mais fácil chegar à causa da falha. Fica muito ruim quando você tem centenas de one-liners não testados sendo usados ​​em vários lugares diferentes.
Daniel
A suposição foram os testes usando o getter de uma linha passado. Se falhar (por exemplo, onde você tenta usar o valor de retorno do seu getter de uma linha), pode resolvê-lo. Mas, a menos que haja uma razão realmente premente de ser tão paranóico, você precisa traçar a linha em algum lugar. Minha experiência foi que eu preciso priorizar o que suga meu tempo e atenção e realmente simples "getters" (que funcionam) não precisam de testes separados. Esse tempo pode ser gasto em melhorar os outros testes ou em uma cobertura mais completa do código com maior probabilidade de falha. (ou seja, mantenho minha posição original, com David Wallace).
Lowell Montgomery
4

Prefiro fazer o BDD, que usa uma combinação de testes de aceitação automatizados, possivelmente outros testes de integração e testes de unidade. A questão para mim é qual deve ser a cobertura alvo do conjunto de testes automatizados como um todo.

Além disso, a resposta depende da sua metodologia, idioma e ferramentas de teste e cobertura. Ao fazer TDD em Ruby ou Python, não é difícil manter 100% de cobertura, e vale a pena fazê-lo. É muito mais fácil gerenciar 100% de cobertura do que 90%. Ou seja, é muito mais fácil preencher lacunas de cobertura à medida que aparecem (e ao fazer TDD, as lacunas de cobertura são raras e geralmente valem o seu tempo) do que gerenciar uma lista de lacunas de cobertura que você não encontrou e perdeu a cobertura regressões devido ao seu histórico constante de código descoberto.

A resposta também depende do histórico do seu projeto. Eu só achei o exposto prático em projetos gerenciados dessa maneira desde o início. Aprimorei bastante a cobertura de grandes projetos herdados, e valeu a pena fazê-lo, mas nunca achei prático voltar e preencher todas as lacunas de cobertura, porque o código antigo não testado não é bem compreendido o suficiente para fazê-lo corretamente e rapidamente.

Dave Schweisguth
fonte
3

Se você faz testes de unidade há um período decente, não vejo razão para não se aproximar de 95% ou mais. No entanto, no mínimo, eu sempre trabalhei com 80%, mesmo quando novo nos testes.

Esse número deve incluir apenas o código escrito no projeto (exclui frameworks, plugins, etc.) e talvez até excluir determinadas classes compostas inteiramente de código escrito de chamadas para código externo. Esse tipo de chamada deve ser ridicularizado / stubbed.

Tony Pitale
fonte
3

De um modo geral, dos vários documentos de melhores práticas de excelência em engenharia que li, 80% para o novo código em testes de unidade é o ponto que gera o melhor retorno. Ir acima desse CC% gera uma quantidade menor de defeitos pela quantidade de esforço exercido. Essa é uma prática recomendada usada por muitas grandes empresas.

Infelizmente, a maioria desses resultados é interna às empresas; portanto, não existem literaturas públicas que eu possa apontar.

user17222
fonte
3

A cobertura do código é excelente, mas apenas enquanto os benefícios que você obtém superam o custo / esforço para alcançá-lo.

Trabalhamos com um padrão de 80% há algum tempo, no entanto, acabamos de tomar a decisão de abandonar isso e, em vez disso, estar mais focados em nossos testes. Concentrando-se na lógica de negócios complexa etc,

Essa decisão foi tomada devido à quantidade crescente de tempo que passamos perseguindo a cobertura do código e mantendo os testes de unidade existentes. Sentimos que tínhamos chegado ao ponto em que o benefício que estávamos obtendo da nossa cobertura de código era considerado menor do que o esforço que tínhamos que envidar para alcançá-lo.

Simon Keep
fonte
2

Resposta curta: 60-80%

Resposta longa: acho que depende totalmente da natureza do seu projeto. Normalmente, começo um projeto testando todas as peças práticas. No primeiro "release" do projeto, você deve ter uma porcentagem básica bastante boa com base no tipo de programação que está executando. Nesse ponto, você pode começar a "impor" uma cobertura mínima de código.

user11087
fonte
2

Confira o Crap4j . É uma abordagem um pouco mais sofisticada do que a cobertura direta de código. Ele combina medidas de cobertura de código com medidas de complexidade e, em seguida, mostra qual código complexo não está testado no momento.

Don Kirkby
fonte
2

Minha resposta a esse dilema é ter 100% de cobertura de linha do código que você pode testar e 0% de cobertura de linha do código que você não pode testar.

Minha prática atual no Python é dividir meus módulos .py em duas pastas: app1 / e app2 / e, ao executar testes de unidade, calcular a cobertura dessas duas pastas e verificar visualmente ( preciso automatizar isso algum dia) que o app1 tenha 100% de cobertura e app2 tem 0% de cobertura.

Quando / se eu achar que esses números diferem do padrão, eu investigo e altero o design do código para que a cobertura esteja em conformidade com o padrão.

Isso significa que eu posso recomendar obter 100% de cobertura de linha do código da biblioteca.

Ocasionalmente, também analiso o app2 / para verificar se é possível testar algum código e, se posso, movo-o para o app1 /

Agora não estou muito preocupado com a cobertura agregada, porque isso pode variar muito, dependendo do tamanho do projeto, mas geralmente eu tenho visto de 70% a mais de 90%.

Com o python, eu devo ser capaz de criar um teste de fumaça que possa executar automaticamente meu aplicativo enquanto mede a cobertura e, esperançosamente, ganhar uma porta de 100% ao combinar o teste de fumaça com números mais baixos.

quamrana
fonte
2

Visualizando a cobertura de outra perspectiva: código bem escrito com um fluxo de controle claro é o mais fácil de cobrir, o mais fácil de ler e, geralmente, o código com menos bugs. Ao escrever o código com clareza e capacidade de cobertura em mente, e ao escrever os testes de unidade em paralelo com o código, você obtém os melhores resultados IMHO.


fonte
2

Na minha opinião, a resposta é "Depende de quanto tempo você tem". Eu tento alcançar 100%, mas não faço barulho se não conseguir com o tempo que tenho.

Quando escrevo testes de unidade, uso um chapéu diferente em comparação com o chapéu ao desenvolver código de produção. Penso no que o código testado pretende fazer e em quais situações é possível quebrá-lo.

Eu costumo seguir os seguintes critérios ou regras:

  1. Que o teste de unidade deve ser uma forma de documentação sobre qual é o comportamento esperado dos meus códigos, ou seja. a saída esperada dada uma determinada entrada e as exceções que os clientes podem querer capturar (o que os usuários do meu código devem saber?)

  2. Que o Teste de Unidade me ajude a descobrir as condições de que se eu ainda não tenha pensado. (Como tornar meu código estável e robusto?)

Se essas duas regras não produzirem 100% de cobertura, que assim seja. Mas, assim que tiver tempo, analiso os blocos e linhas descobertos e determino se ainda há casos de teste sem testes de unidade ou se o código precisa ser refatorado para eliminar os códigos desnecessários.

Mark Menchavez
fonte
1

Depende muito da sua aplicação. Por exemplo, alguns aplicativos consistem principalmente em código da GUI que não pode ser testado em unidade.

Thomas
fonte
5
Você provavelmente deve usar o Model View Presenter para sua interface do usuário se estiver em um ambiente TDD.
Charles Graham
1

Eu não acho que possa haver uma regra de P / B.
O código deve ser revisado, com atenção especial aos detalhes críticos.
No entanto, se não foi testado, há um erro!

Nescio
fonte
Não queira uma regra, apenas feedback sobre qualquer experiência pessoal sobre a correlação entre a porcentagem de cobertura de código e a eficácia do teste de unidade.
Sanity
1

Dependendo da criticidade do código, entre 75% e 85% é uma boa regra geral. O código de remessa deve ser definitivamente testado mais minuciosamente do que os utilitários internos, etc.

William Keller
fonte
1

Isso precisa depender da fase do ciclo de vida de desenvolvimento de aplicativos em que você está.

Se você está em desenvolvimento há algum tempo e já possui muitos códigos implementados e agora percebe que precisa pensar na cobertura do código, verifique sua cobertura atual (se houver) e use essa linha de base para definir marcos em cada sprint (ou um aumento médio ao longo de um período de sprints), o que significa assumir uma dívida de código enquanto continua a fornecer valor ao usuário final (pelo menos na minha experiência, o usuário final não se importa nem um pouco se você aumentou o teste cobertura se não virem novos recursos).

Dependendo do seu domínio, não é razoável disparar para 95%, mas eu tenho que dizer que, em média, você estará olhando para um caso médio de 85% a 90%.

codeLes
fonte
1

Acho que o melhor sintoma da cobertura correta do código é que a quantidade de problemas concretos que os testes de unidade ajudam a corrigir corresponde, razoavelmente, ao tamanho do código de testes de unidade que você criou.

dimarzionista
fonte
1

Acho que o que mais importa é saber qual é a tendência de cobertura ao longo do tempo e entender os motivos das mudanças na tendência. Se você vê as mudanças na tendência como boas ou ruins, dependerá da sua análise do motivo.

Rob Scott
fonte
0

Estávamos alvejando> 80% até alguns dias atrás, mas depois que usamos muito código gerado, não nos importamos com% de idade, mas fazemos com que o revisor atenda a cobertura necessária.

reva
fonte
0

Na publicação do Testivus, acho que o contexto da resposta deve ser o segundo programador. Dito isto, de um ponto de vista prático, precisamos de parâmetros / objetivos para lutar. Considero que isso pode ser "testado" em um processo Agile, analisando o código que temos a arquitetura, a funcionalidade (histórias de usuários) e, em seguida, apresentamos um número. Com base na minha experiência na área de Telecom, eu diria que 60% é um bom valor para verificar.

D Lovece
fonte