Quando você tem testes automáticos suficientes para confiar no seu pipeline de integração contínua?


10

A integração contínua com o teste é útil para garantir que você tenha o código "expedível" verificado o tempo todo.

No entanto, é realmente difícil manter um conjunto abrangente de testes e, muitas vezes, parece que a compilação será de qualquer maneira danificada.

Quantos testes você deve ter para se sentir confiante nos seus testes de pipeline de IC? Você usa algum tipo de métrica para decidir quando há testes suficientes?

Respostas:


16

Em geral

Quando você tem testes automáticos suficientes para confiar no seu pipeline de integração contínua?

A resposta provavelmente fica clara se você pensar no que deseja confiar. Por fim, ele mapeia 1-1; todo teste deixa você confiante sobre a única coisa que ele testa:

  • O teste de unidade dá a você a confiança de que uma classe (ou módulo) faz o que é testado.
  • O teste de integração dá a você a confiança de que várias unidades trabalham juntas da maneira que são testadas.
  • O teste de ponta a ponta dá a você confiança de que todo o aplicativo faz uma determinada coisa, da maneira como é descrito no teste.

Pela maneira como formulou sua pergunta, você provavelmente está pensando em um cenário geral de negócios agora, por exemplo:

Eu quero ter certeza de que meu aplicativo pode fazer X .

Então, você escreve um teste de ponta a ponta que tenta fazer o X e verifica se faz isso corretamente.

Mais concreto

Tudo isso é muito auto-referencial, mas é por isso que tudo se resume. Simplesmente não existe mais.

Por exemplo, imagine que você escreva um aplicativo para criar receitas de culinária. Uma característica é que, se você adicionar quantidades diferentes de vários tipos diferentes de queijo, ele fornecerá a temperatura e o tempo corretos para que todos derretam.

Assim, você pode escrever um teste de unidade para o seu CheeseMeltCalculator, onde você administra 100g de queijo Gouda e 200g de Emmental e depois verifica se a temperatura e o tempo estão certos. Isso significa que agora você pode ter certeza de que CheeseMeltCalculatorfunciona para 100g de queijo Gouda e 200g. Agora, se você repetir este teste com 300g de Gouda em vez de 200g, pode ter certeza de que ele funciona corretamente para valores diferentes. Você pode adicionar testes para 0, -1e int.MaxValueg de Gouda para ter certeza de que o código não tropeçar (ou excursões corretamente como pretendido) para a entrada de estranhos.

Você pode escrever um teste de integração para verificar se CheeseMeltCalculatorestá incorporado corretamente em todo o processo de cálculo de temperatura e tempo dos alimentos. Se isso der errado, mas os CheeseMeltCalculatortestes acima estiverem corretos, você pode ter certeza de que o erro está em outras calculadoras ou na maneira como os dados de diferentes calculadoras são combinados.

E, finalmente, você pode escrever um teste de ponta a ponta para criar uma receita inteira, e uma das coisas que você verifica é a temperatura e o tempo do resultado. Se os dois níveis anteriores de testes estiverem corretos, mas não der certo, então você pode ter certeza de que essas peças estão corretas e o erro é sobre como o cálculo da temperatura é integrado ao aplicativo. Por exemplo, talvez a entrada do usuário não seja transferida corretamente.

E , finalmente , se todos esses testes estiverem corretos , você pode ter certeza de que " se você adicionar quantidades diferentes de vários tipos diferentes de queijo, ele fornecerá a temperatura e o tempo corretos para que todos derreta "

Longa história curta

O ponto é que você não pode ter um teste "funciona corretamente". Você só pode testar "Se eu fizer X, Y acontecerá".

No entanto, é exatamente isso que deve constar nas especificações técnicas do projeto. Uma declaração como " se você adicionar quantidades diferentes de vários tipos diferentes de queijo, fornecerá a temperatura e o tempo corretos para que todos derreterem " não apenas dará ao cliente expectativas claras sobre o que o produto acabado fará, mas também poderá ser transformado em testes automatizados.

informação adicional

O usuário Richard adicionou essas informações em uma edição:

Martin Fowler tem um resumo muito bom em seu site sobre as estratégias mais comuns: https://martinfowler.com/articles/microservice-testing/

Não quero remover isso, mas quero dizer o seguinte: Comparado a esta resposta, não é um "resumo", mas uma explicação muito mais aprofundada, com bons gráficos e tudo mais.

Meu conselho seria: se tudo fizer sentido para você depois de ler minha resposta, está feito. Se as coisas ainda não estiverem claras, reserve um pouco de tempo e leia o artigo vinculado.


Esta é uma boa visão conceitual. Você teria exemplos de métricas que seriam úteis para fornecer confiança em nossa cobertura de teste?
Stonefruit 18/07/19

@stonefruit Não realmente, mas eu acho que tenho exatamente a resposta que você precisa: Testivus Na Cobertura de Teste
R. Schmitz

@stonefruit Em relação ao número nessa parábola, 80%, é um número que você ouve com mais frequência nesse contexto. Principalmente por causa do princípio do pareto - os últimos 20% de cobertura são 80% do trabalho. Em outras palavras, é 4 vezes mais trabalho obtê-lo de 80% para 100%, como era para obtê-lo até 80% em primeiro lugar. Isso geralmente é um exagero, mas imagine que você esteja escrevendo um código de controle para um satélite: se um bug aparecer, você não poderá consertar isso; obter 100% de cobertura é um investimento que vale a pena.
R. Schmitz

Parece que sou o terceiro programador. haha Acho que no final do dia, ele volta a adotar uma abordagem baseada em risco, como você mencionou no exemplo de satélite.
Stonefruit 18/07/19

1
@stonefruit Talvez você seja o primeiro, no entanto. Se você tem um projeto existente com cobertura de 0%, não comece uma marcha da morte para 80%. Na verdade, " basta escrever alguns bons testes ". Talvez use a última metade das sextas-feiras para escrever testes, algo assim. Na minha experiência, você apresentará automaticamente os testes com a melhor relação esforço-recompensa primeiro, e todos os testes lhe darão um pouco mais de confiança.
R. Schmitz

4

Você não pode calcular nenhuma métrica que lhe dará a confiança que você procura. A confiança é construída ao fazer algo e, em seguida, ter sucesso ou falhar e aprender algo com isso.

As únicas "métricas" que eu descobri que me dão confiança em nossa cobertura de teste são:

  1. Número de defeitos encontrados na produção
  2. Você pode refatorar a base de código e confiar na sua cobertura de teste para detectar defeitos de regressão?

Testes automatizados não são uma bala de prata. Você precisa acompanhar quantos defeitos de produção são encontrados durante cada ciclo de liberação. Quando esse número diminui, você está entregando um software melhor. Testes automatizados e integração contínua são apenas ferramentas usadas para fornecer um software melhor.

A única métrica que você pode realmente medir é "Você está entregando um software melhor?"

E mesmo assim, é subjetivo.


Comparada a outras respostas, essa resposta aborda possíveis métricas. Estou pensando em tornar as métricas sugeridas mais significativas. Talvez, além de encontrar o número de defeitos encontrados na produção, atribua uma pontuação a cada defeito com base no gerenciamento de riscos e estabeleça um limite (por exemplo, 30 pontos de defeitos encontrados nos últimos 3 meses). Atingir o limite pode ser uma indicação de uma revisão do sistema quanto a possíveis erros, antes que a dívida técnica do código de bugs aumente exponencialmente.
stonefruit 18/07/19

2

Quando você tem testes automáticos suficientes para confiar no seu pipeline de integração contínua?

Na maioria dos ambientes econômicos, você não terá orçamento para implementar confiança suficiente (> 99%), mas precisará gerenciar um orçamento limitado: trata-se da relação custo / benefício.

  • Alguns testes automatizados são baratos para implementar, outros são extremamente caros.
  • Dependendo do seu gerenciamento de riscos real , alguns riscos devem ser cobertos por testes, enquanto outros não.

Portanto, na realidade, os testes fáceis / baratos / de risco serão implementados, enquanto os testes caros / improváveis, não.

Um subobjetivo do desenvolvimento de software leve é ​​criar uma arquitetura que seja fácil / barata para testar (crie uma testabilidade aplicando o Test-driven_development ) para manter o teste automatizado acessível.

Suponho que o Pareto_principle também possa ser aplicado a software de manutenção / testável aqui: ele diz que, ao gastar 20% a mais, você obtém um benefício extra de 80%. Para alcançar os 20% a mais restantes, você precisa gastar 80% a mais.

Você pode aplicar Métricas de Teste, como cobertura de código e cobertura de mutação, para mostrar o código-fonte potencial não testado.

Mas mesmo com 100% de cobertura, você não pode ter certeza de que seu código está livre de bugs.

A gerência gosta de codemetria. Se "cobertura de código> = 80%" for aplicada pelo gerenciamento, enquanto os desenvolvedores não suportam / gostam de testes automatizados, existem maneiras de escrever código de teste com alta cobertura que não prova nada que dê uma falsa sensação de segurança.


1

O truque aqui não é se preocupar com a cobertura completa, mas com o gerenciamento do risco de suas alterações.

Digamos que você esteja usando seu pipeline para implantar exatamente a mesma versão que já está em produção - qual é o risco de erro de regressão? Zero (porque não há alterações).

Agora, digamos que eu queira alterar um pedaço de texto em uma das telas. Adicionei o teste para verificar se o texto agora é exibido corretamente (vamos supor, por uma questão de argumento, que é um pedaço de texto MUITO importante). Quais outros testes são necessários para verificar se não há erros de regressão? Realisticamente nenhum ...

Portanto, o número de testes automatizados necessários para a liberação de cada release não depende do tamanho do seu aplicativo, mas do tamanho da sua alteração. Se você estiver fazendo alterações pequenas e de baixo risco, precisará de muito menos testes para atenuar os riscos.

Mas espere um minuto ... isso não se alinha muito bem com o ponto de CI e CD?

Sim! Ao manter todas as suas alterações e deltas muito pequenas, você está atenuando muitos dos riscos de regressão por meio do processo, e não do teste. Além disso, a questão não se torna realmente de automação (é apenas a ferramenta que usaremos) - é simplesmente uma questão de teste e apetite ao risco. Esqueça totalmente a automação, quais testes você executaria em relação a uma alteração para garantir que ela não introduza problemas? A resposta a essa pergunta não muda de um processo de teste manual para um sistema de IC - a única vantagem é que muitos desses testes de regressão podem ter sido desenvolvidos anteriormente na funcionalidade anterior e o CI o incentiva a fazer alterações menores e mais seguras.

TLDR

Seus testes são para mitigar o risco da mudança. Uma implantação com um delta zero não tem riscos e, portanto, não corre riscos. Ao manter suas alterações pequenas, fica muito mais fácil identificar os testes necessários para validá-las - a reutilização da automação é um bônus.


0

É a mesma métrica de quando você está testando seu produto manualmente.

Na prática, é fácil identificar essas zonas de baixa confiança: supondo que você esteja enviando o produto, suponho que você tenha algumas etapas manuais pós-pipeline que melhoram sua confiança em ser entregável. Essas são as áreas que você deve automatizar para melhorar a confiança no próprio processo automático.

Sua automação é um esforço contínuo. Ele cresce e melhora à medida que seu produto melhora. Um defeito é um motivo para repensar seu código, além de repensar o IC. E o lado positivo aqui é que, como a confiança no próprio produto é alcançável - a confiança na automação também é alcançável.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.