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;)
unit-testing
code-coverage
code-metrics
sanidade
fonte
fonte
Respostas:
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
fonte
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).
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).
fonte
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.
fonte
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:
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:
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?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:
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".
fonte
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 é:
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.
fonte
// @codeCoverageIgnore
e ela será excluída da cobertura.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 :
Novamente, ele volta ao meu Testivus na resposta de cobertura de código . Quanto arroz você deve colocar na panela? Depende.
fonte
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:
É 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:
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.
fonte
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!
fonte
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.
fonte
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.
fonte
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.
fonte
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:
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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
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:
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?)
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.
fonte
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.
fonte
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!
fonte
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.
fonte
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%.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte