Qual é a diferença entre testes de unidade, funcionais, de aceitação e de integração? [fechadas]

799

Qual é a diferença entre os testes de unidade, funcional, aceitação e integração (e quaisquer outros tipos de testes que não foram mencionados)?

Andrew
fonte
1
Veja também sqa.stackexchange.com/a/23396/8992
Michael Durrant
1
Acho que você esqueceu de incluir o teste de carga!
Talk is Cheap Mostre-me código

Respostas:

1350

Dependendo de onde você olha, você receberá respostas ligeiramente diferentes. Eu li muito sobre o assunto, e aqui está minha destilação; Novamente, estes são levemente confusos e outros podem discordar.

Testes unitários

Testa a menor unidade de funcionalidade, geralmente um método / função (por exemplo, dada uma classe com um estado específico, chamar x método na classe deve fazer com que y aconteça). Os testes de unidade devem ser focados em um recurso específico (por exemplo, chamar o método pop quando a pilha está vazia deve gerar um InvalidOperationException). Tudo o que toca deve ser feito na memória; isso significa que o código de teste e o código em teste não devem:

  • Convide colaboradores (não triviais)
  • Acesse a rede
  • Atingir um banco de dados
  • Use o sistema de arquivos
  • Girar um fio
  • etc.

Qualquer tipo de dependência lenta / difícil de entender / inicializar / manipular deve ser stubbed / mocked / seja o que for, usando as técnicas apropriadas para que você possa se concentrar no que a unidade de código está fazendo, e não nas suas dependências.

Em resumo, os testes de unidade são o mais simples possível, fáceis de depurar, confiáveis ​​(devido a fatores externos reduzidos), rápidos de executar e ajudam a provar que os menores blocos de construção do seu programa funcionam conforme planejado antes de serem reunidos. A ressalva é que, embora você possa provar que eles funcionam perfeitamente isoladamente, as unidades de código podem explodir quando combinadas, o que nos leva a ...

Testes de integração

Os testes de integração se baseiam em testes de unidade combinando as unidades de código e testando se a combinação resultante funciona corretamente. Isso pode ser o interior de um sistema ou a combinação de vários sistemas para fazer algo útil. Além disso, outra coisa que diferencia os testes de integração dos testes de unidade é o ambiente. Os testes de integração podem e vão usar threads, acessar o banco de dados ou fazer o que for necessário para garantir que todo o código e as diferentes alterações no ambiente funcionem corretamente.

Se você criou algum código de serialização e a unidade testou suas entranhas sem tocar no disco, como você sabe que ele funcionará quando você estiver carregando e salvando no disco? Talvez você tenha esquecido de liberar e descartar os filmes. Talvez suas permissões de arquivo estejam incorretas e você tenha testado as entranhas usando em fluxos de memória. A única maneira de descobrir com certeza é testá-lo 'de verdade' usando um ambiente mais próximo da produção.

A principal vantagem é que eles encontrarão erros que os testes de unidade não podem, como erros de fiação (por exemplo, uma instância da classe A recebe inesperadamente uma instância nula de B) e erros de ambiente (ele funciona bem na minha máquina com CPU única, mas meu a máquina de 4 núcleos do colega não pode passar nos testes). A principal desvantagem é que os testes de integração tocam mais código, são menos confiáveis, as falhas são mais difíceis de diagnosticar e os testes são mais difíceis de manter.

Além disso, os testes de integração não necessariamente provam que um recurso completo funciona. O usuário pode não se importar com os detalhes internos dos meus programas, mas eu sim!

Testes Funcionais

Os testes funcionais verificam a exatidão de um recurso em particular, comparando os resultados de uma determinada entrada com a especificação. Os testes funcionais não se preocupam com resultados intermediários ou efeitos colaterais, apenas o resultado (eles não se importam que, após fazer x, o objeto y tenha o estado z). Eles são escritos para testar parte da especificação, como "chamar a função Square (x) com o argumento 2 retorna 4".

Testes de aptidão

O teste de aceitação parece ser dividido em dois tipos:

O teste de aceitação padrão envolve a execução de testes no sistema completo (por exemplo, usando sua página da web por meio de um navegador da web) para verificar se a funcionalidade do aplicativo atende à especificação. Por exemplo, "clicar no ícone de zoom deve aumentar a exibição do documento em 25%". Não há um continuum real de resultados, apenas um resultado aprovado ou reprovado.

A vantagem é que os testes são descritos em inglês simples e garantem que o software, como um todo, tenha recursos completos. A desvantagem é que você subiu outro nível na pirâmide de testes. Os testes de aceitação tocam montanhas de código, portanto, rastrear uma falha pode ser complicado.

Além disso, no desenvolvimento ágil de software, o teste de aceitação do usuário envolve a criação de testes para espelhar as histórias do usuário criadas pelo / para o cliente do software durante o desenvolvimento. Se os testes forem aprovados, significa que o software deve atender aos requisitos do cliente e as histórias podem ser consideradas completas. Um conjunto de testes de aceitação é basicamente uma especificação executável escrita em um idioma específico do domínio que descreve os testes no idioma usado pelos usuários do sistema.

Conclusão

Eles são todos complementares. Às vezes, é vantajoso focar em um tipo ou evitá-lo completamente. A principal diferença para mim é que alguns dos testes analisam as coisas da perspectiva de um programador, enquanto outros usam o foco no cliente / usuário final.

Mark Simpson
fonte
19
+1. @ Mark Simpson Os testes funcionais e de aceitação podem ser resumidos como "teste do sistema"? Onde os testes de ponta a ponta se encaixam? (vocabulário muito diferente para o meu gosto)
Torsten Engelbrecht
3
@Franz Eu estava falando sobre a capacidade e facilidade com as quais você pode reduzir o risco isolando unidades de código e testando-as. Você está certo, porém, a linguagem que usei era um pouco solta, pois os testes não podem provar que o código está livre de erros.
Mark Simpson
15
Apesar das votações positivas, isso está completamente errado. Os testes de unidade não testam nem mesmo os colaboradores "triviais"; qualquer dependência injetada deve ser ridicularizada. Testes funcionais não testam "comportamento"; eles testam apenas "função", ou seja, "f (A) retorna B". Se os efeitos colaterais são importantes, é "comportamental". Se incluem chamadas de sistema, também são testes de "sistema", como em "testes de sistema comportamental". (Consulte testerab @ abaixo.) Os testes de "aceitação" são um subconjunto de "testes de sistema comportamental" que cobrem a pilha completa. A "integração" testa para cima, simulando o uso real; ele testa que todas as dependências podem ser integradas na prática.
cdunn2001
7
@ cdunn2001: Não se preocupe, críticas construtivas sempre são boas :) Seu comentário me ensinou algumas coisas que eu não sabia e limpei um pouco minha terminologia. Estou sempre interessado em aprender coisas novas de desenvolvedores interessados ​​em testar. Lembro-me da primeira vez que eu descobri o blog de Miško Hevery - era como um tesouro :)
Mark Simpson
11
@ MarkSimpson, embora sua resposta seja muito boa, gostaria de um pouco mais de detalhes sobre os testes funcionais. Quero dizer, na sua resposta, para mim, é difícil distinguir entre testes funcionais e testes de unidade. Espero que você tenha tempo para isso, continue o excelente trabalho!
Andrei Sandulescu
90

O importante é que você saiba o que esses termos significam para seus colegas. Grupos diferentes terão definições ligeiramente variáveis ​​do que elas significam quando dizem testes "completos de ponta a ponta", por exemplo.

Me deparei com o sistema de nomes do Google para os testes recentemente, e eu gosto bastante - eles ignoram os argumentos usando apenas Pequeno, Médio e Grande. Para decidir em qual categoria um teste se encaixa, eles analisam alguns fatores - quanto tempo leva para executar, acessa a rede, banco de dados, sistema de arquivos, sistemas externos e assim por diante.

http://googletesting.blogspot.com/2010/12/test-sizes.html

Eu imagino que a diferença entre Pequeno, Médio e Grande para o seu local de trabalho atual possa variar das do Google.

No entanto, não se trata apenas de escopo, mas de propósito. O ponto de Mark sobre diferentes perspectivas para testes, por exemplo, programador versus cliente / usuário final, é realmente importante.

testerab
fonte
6
+1 para a coisa de nomeação de teste do Google, pois ajuda a dar um pouco de perspectiva sobre por que várias organizações / pessoas têm definições diferentes para testes.
Mark Simpson
Este também é um artigo muito interessante sobre por que você usaria diferentes níveis de teste e o que obtém deles: kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests
testerab
63

http://martinfowler.com/articles/microservice-testing/

A publicação no blog de Martin Fowler fala sobre estratégias para testar o código (especialmente em uma arquitetura de microsserviços), mas a maioria se aplica a qualquer aplicativo.

Vou citar seu slide de resumo:

  • Testes de unidade - exercite os menores pedaços de software testável no aplicativo para determinar se eles se comportam conforme o esperado.
  • Testes de integração - verifique os caminhos de comunicação e as interações entre os componentes para detectar defeitos na interface.
  • Testes de componentes - limite o escopo do software exercitado a uma parte do sistema em teste, manipulando o sistema por meio de interfaces internas de código e usando testes duplos para isolar o código em teste de outros componentes.
  • Testes de contrato - verifique as interações nos limites de um serviço externo, afirmando que ele atende ao contrato esperado por um serviço consumidor.
  • Testes de ponta a ponta - verifique se um sistema atende a requisitos externos e atinge seus objetivos, testando todo o sistema, de ponta a ponta.
Máxima
fonte
A propósito, esse é um ótimo artigo. No entanto, não entendo completamente para que servem os testes de contrato. Eles não são redundantes à luz dos testes de componentes e integração?
wheleph
Em alguns idiomas (que o Sr. Fowler usa), você pode implementar uma interface que não é exposta ao usar a definição padrão de uma classe, por exemplo, void IMyInterface.MyMethod (). Que, por sua vez, teria logicamente seus próprios testes. Embora nesse ponto você esteja voltando para o BDD. O que, ironicamente, o Sr. Fowler também conquistou.
Skarsnik
2
não é um artigo da Fowler, apenas postado lá. Testes de contrato são aqueles que são feitos depois que os clientes começam a usar seu serviço e, em seguida, você escreve testes que verificam se não quebrou algo para esses clientes em particular, ou seja, altera a API do serviço.
Rafał Łużyński
Os testes de unidade, integração e componente do @wheleph falam principalmente dos internos de software que são altamente controláveis ​​pelo desenvolvedor. Um problema nos três primeiros significa alterar sua fonte para corrigir o problema. - Os testes de contrato tocam o que lhe é prometido em termos de funcionalidade, mas talvez você não consiga mudar diretamente diante do defeito. Isso requer a adição de código de suporte para solucionar os possíveis problemas, em vez de apenas corrigir o defeito. - Então, você contornaria um serviço da Web, devolvendo o json malformado, mesmo que a especificação do contrato lhe dissesse que era de uma determinada estrutura.
Yemi Bedu
31

Teste de unidade - como o nome sugere, esse método é testado no nível do objeto. Os componentes de software individuais são testados quanto a erros. O conhecimento do programa é necessário para este teste e os códigos de teste são criados para verificar se o software se comporta conforme o planejado.

Teste Funcional - É realizado sem qualquer conhecimento do funcionamento interno do sistema. O testador tentará usar o sistema apenas seguindo os requisitos, fornecendo entradas diferentes e testando as saídas geradas. Esse teste também é conhecido como teste de caixa fechada ou caixa preta.

Teste de aceitação - Este é o último teste realizado antes do software ser entregue ao cliente. É realizado para garantir que o software desenvolvido atenda a todos os requisitos do cliente. Existem dois tipos de teste de aceitação - um realizado pelos membros da equipe de desenvolvimento, conhecido como teste interno de aceitação (teste alfa) e outro realizado pelo cliente ou usuário final conhecido como (teste beta)

Teste de integração - Módulos individuais que já estão sujeitos a teste de unidade são integrados entre si. Geralmente as duas abordagens são seguidas:

1) De cima para baixo
2) De baixo para cima


fonte
O que você quer dizer com de cima para baixo e de baixo para cima? O teste de integração é igual ao teste de ponta a ponta?
tamj0rd2
18

Isto é muito simples.

  1. Teste de unidade: Este é o teste realmente realizado por desenvolvedores que possuem conhecimento de codificação. Esse teste é realizado na fase de codificação e faz parte do teste da caixa branca. Quando um software vem para desenvolvimento, ele é desenvolvido no pedaço de código ou fatias de código conhecido como unidade. E testes individuais dessas unidades são chamados de testes de unidade realizados por desenvolvedores para descobrir algum tipo de erro humano, como falta de cobertura de declaração etc.

  2. Teste funcional: este teste é realizado na fase de teste (QA) e faz parte do teste de caixa preta. A execução real dos casos de teste escritos anteriormente. Esse teste é realmente realizado pelos testadores, eles encontram o resultado real de qualquer funcionalidade no site e comparam esse resultado ao resultado esperado. Se eles encontraram alguma disparidade, isso é um bug.

  3. Teste de aceitação: conhecido como UAT. E isso realmente foi feito pelo testador, além de desenvolvedores, equipe de gerenciamento, autor, escritores e todos os envolvidos neste projeto. Para garantir que o projeto esteja finalmente pronto para ser entregue sem erros.

  4. Teste de integração: as unidades de código (explicadas no ponto 1) são integradas entre si para concluir o projeto. Essas unidades de códigos podem ser escritas com tecnologia de codificação diferente ou podem ter versões diferentes. Portanto, esse teste é realizado pelos desenvolvedores para garantir que todas as unidades de código sejam compatíveis com outras e que não haja nenhum problema de integração.

Rakesh Kumar
fonte
1
@OlegTsyba a resposta veio 4 anos após a pergunta ser respondida.
bentesha
1
Nunca devemos começar uma resposta com "Isso é muito simples", especialmente se for um tópico complexo como este.
milosmns
6

Algumas idéias (relativamente) recentes contra zombarias excessivas e testes de unidade puros:

cdunn2001
fonte
Eu sou novo no teste de código. Os testes de unidade parecem principalmente como uma perda de tempo. Eu pensei que estava fazendo testes de unidade, mas estava fazendo testes de integração e depois li sobre testes de unidade e parece bobagem, talvez para pessoas com muito pouca experiência? Há uma chance de eu estar perdendo algum tipo de argumento.
PixMach
Se a Unidade for definida amplamente, você estará testando adequadamente a unidade. Oponho-me a detalhes de implementação de teste. Uma classe privada não deve ser "testada em unidade". No entanto, se você tiver várias classes públicas, poderá tentar zombar de uma enquanto estiver testando outra. Esse é o verdadeiro debate. A Unidade (a) é toda a sua biblioteca? (b) cada classe pública dentro da biblioteca? Ou (c), cada método público dentro de cada classe? Prefiro testar uma determinada biblioteca como um componente integrado, mas simular ou falsificar dependências externas (a menos que sejam rápidas e confiáveis). Então eu acho que estou com você.
cdunn2001
1
@PixMach: na verdade, é o contrário. Não ter (bons) testes de unidade em funcionamento, perde muito do seu tempo, se você (ou outra pessoa) precisar alterar esse código no futuro. Se você tiver experiência em manter código com e sem testes de unidade, saberá a diferença. A idéia é que, se um teste de unidade for interrompido, você deve saber exatamente qual parte do código deve ser corrigida. Os testes de aceitação / integração em larga escala geralmente dizem apenas: ele não funciona. E então você tem que iniciar a depuração velha escola ...
Goodsquirrel
@ Goodsquirrel, depende do que você chama de "unidade". Esse é o problema. Testes ruins serão excluídos durante a refatoração. Bons testes ainda serão úteis. Testes ruins não agregam valor e atrapalham. Bons testes são auto-documentados e muito apreciados. Vamos ser específicos. Eu tenho um método privado para retornar um valor se outro valor for True, caso contrário, um valor padrão. (Código legado.) Esse método deve ser testado? Eu disse não. Outro método privado retorna o enésimo número de Fibonacci. Isso deveria ser testado? Eu digo sim.
precisa saber é o seguinte
1
O menor código exposto . Grande diferença.
precisa saber é o seguinte
5

Vou explicar isso com um exemplo prático e sem nenhum material teórico:

Um desenvolvedor escreve o código. Nenhuma GUI ainda está implementada. O teste nesse nível verifica se as funções funcionam corretamente e os tipos de dados estão corretos. Essa fase do teste é chamada de teste de unidade.

Quando uma GUI é desenvolvida e o aplicativo é atribuído a um testador, ele verifica os requisitos de negócios com um cliente e executa os diferentes cenários. Isso é chamado de teste funcional. Aqui estamos mapeando os requisitos do cliente com os fluxos de aplicativos.

Teste de integração: digamos que nosso aplicativo tenha dois módulos: RH e Finanças. O módulo de RH foi entregue e testado anteriormente. Agora o Finance está desenvolvido e está disponível para teste. Os recursos interdependentes também estão disponíveis agora; portanto, nesta fase, você testará os pontos de comunicação entre os dois e verificará se estão funcionando conforme solicitado nos requisitos.

O teste de regressão é outra fase importante, que é realizada após qualquer novo desenvolvimento ou correção de bug. Seu objetivo é verificar as funções que funcionavam anteriormente.

fahad shaikh
fonte
1
"Um desenvolvedor escreve o código. Nenhuma GUI ainda foi implementada. O teste neste nível verifica se as funções funcionam corretamente e os tipos de dados estão corretos. Essa fase do teste é chamada de teste de unidade" Isso não é verdade. GUI é realmente apenas um "plugin". Você já pode gravar testes E2E na saída da API. (ou qualquer objeto de resposta você gera)
user3790897
4

teste de unidade: o teste de módulo individual ou componente independente em um aplicativo é conhecido por teste de unidade; o teste de unidade será realizado pelo desenvolvedor.

teste de integração: combinando todos os módulos e testando o aplicativo para verificar se a comunicação e o fluxo de dados entre os módulos estão funcionando corretamente ou não, esse teste também é realizado pelos desenvolvedores.

teste funcional que verifica a funcionalidade individual de um aplicativo significa teste funcional

teste de aceitação, esse teste é feito pelo usuário final ou pelo cliente, independentemente de o aplicativo de compilação estar de acordo com os requisitos do cliente, e as especificações do cliente são conhecidas por serem testes de aceitação

malini
fonte