Onde devo traçar a linha entre testes de unidade e testes de integração? Eles deveriam estar separados?

11

Eu tenho uma pequena estrutura MVC em que estou trabalhando. Sua base de código definitivamente não é grande, mas não é mais apenas algumas classes. Finalmente decidi dar um mergulho e começar a escrever testes para isso (sim, eu sei que deveria ter feito isso o tempo todo, mas a API era super instável até agora)

Enfim, meu plano é tornar extremamente fácil testar, incluindo testes de integração. Um exemplo de teste de integração seria algo como:

Objeto de solicitação HTTP falso -> Estrutura MVC -> Objeto de resposta HTTP -> verifique se a resposta está correta

Como tudo isso é possível sem qualquer estado ou ferramentas especiais (automação do navegador etc.), eu poderia fazer isso com facilidade com estruturas de teste de unidade regulares (eu uso o NUnit).

Agora a grande questão. Onde exatamente devo traçar a linha entre testes de unidade e testes de integração? Devo testar apenas uma turma de cada vez (o máximo possível) com testes de unidade? Além disso, os testes de integração devem ser colocados no mesmo projeto de teste do meu projeto de teste de unidade?

Earlz
fonte
O teste de integração envolve o teste de mais de uma implementação real de seus componentes juntos (implementações reais significam sem zombaria).
Kemoda
1
Esta pergunta está relacionada a testes e controle de qualidade. Então, eu sugeriria migrá-lo para o site correspondente, SQA na pilha Exchange ( sqa.stackexchange.com )
dzieciou
@dzieciou nem sabia que existia!
Earlz

Respostas:

19

Integração vs. testes de unidade

Você deve manter seus testes de unidade e de integração completamente separados. Seus testes de unidade devem testar apenas uma coisa e apenas uma coisa e em completo isolamento do resto do seu sistema. Uma unidade é vagamente definida, mas geralmente se resume a um método ou função.

Faz sentido ter testes para cada unidade para que você saiba que seus algoritmos foram implementados corretamente e saiba imediatamente o que deu errado onde, se a implementação for falha.

Como você testa em isolamento completo durante o teste de unidade, você usa objetos stub e mock para se comportar como o resto do seu aplicativo. É aqui que entram os testes de integração. Testar todas as unidades isoladamente é ótimo, mas você precisa saber se as unidades estão realmente trabalhando juntas.

Isso significa saber se um modelo está realmente armazenado em um banco de dados ou se um aviso é realmente emitido após a falha do algoritmo X.

Desenvolvimento orientado a testes

Dando um passo atrás e olhando para o Test Driven Development (TDD), há várias coisas a serem levadas em consideração.

  1. Você escreve seu teste de unidade antes de realmente escrever o código que o faz passar.
  2. Você faz o teste passar, escreve apenas o código suficiente para fazer isso.
  3. Agora que o teste passa, é hora de dar um passo atrás. Há algo para refatorar com essa nova funcionalidade? Você pode fazer isso com segurança, pois tudo é coberto por testes.

Integração em primeiro lugar vs Integração em último

Os testes de integração se encaixam nesse ciclo TDD de uma das duas maneiras. Conheço pessoas que gostam de escrever com antecedência. Eles chamam um teste de integração de teste de ponta a ponta e definem um teste de ponta a ponta como um teste que testa completamente todo o caminho de um caso de usuário (pense em configurar um aplicativo, inicializá-lo, acessá-lo, acessar um controlador, executá-lo, verificação do resultado, saída, etc ...). Em seguida, eles começam com o primeiro teste de unidade, passam, adicionam um segundo, passam, etc ... Lentamente, mais e mais partes do teste de integração também são aprovadas até que o recurso seja concluído.

O outro estilo é criar um teste de unidade de recurso por teste de unidade e adicionar os testes de integração considerados necessários posteriormente. A grande diferença entre esses dois é que, no caso do teste de integração, você é forçado a pensar no design de um aplicativo. Isso meio que discorda da premissa de que o TDD trata tanto do design de aplicativos quanto de testes.

Praticidades

No meu trabalho, temos todos os nossos testes no mesmo projeto. Existem diferentes grupos no entanto. A ferramenta de integração contínua executa primeiro o que é marcado como teste de unidade. Somente se forem bem-sucedidos, os testes de integração mais lentos (porque eles fazem solicitações reais, usam bancos de dados reais etc.) também são executados.

A propósito, geralmente usamos um arquivo de teste para uma classe.

Leitura sugerida

  1. Desenvolvimento de software orientado a objetos, guiado por testes Este livro é um exemplo extremamente bom da primeira metodologia de teste de integração
  2. A arte do teste de unidade, com exemplos no dot.net No teste de unidade, com exemplos no dot.net: D Livro muito bom sobre os princípios por trás do teste de unidade.
  3. Robert C. Martin no TDD (artigos gratuitos): leia os dois primeiros artigos que ele vinculou lá também.
hoppa
fonte
2

O que é importante em qualquer estratégia de teste é a Cobertura de Teste - ou seja, poder mostrar que todas as funcionalidades estão sendo testadas.

Em geral, e a menos que você tenha requisitos específicos em contrário (por exemplo, DO178 Nível A, IEC61508 SIL 4, etc.) que não parecem ser o caso na sua situação, se você puder testar a função completa da classe ou de um módulo (e demonstrar que você possui) no nível do sistema, o teste no nível do sistema é adequado. E assim por diante. O teste de unidade é necessário apenas quando você ainda não o abordou.

Onde exatamente devo traçar a linha entre testes de unidade e testes de integração?

Dado que o teste de integração é geralmente mais fácil, mais rápido e mais barato, trace a linha o mais longe que puder ...

Devo testar apenas uma turma de cada vez (o máximo possível) com testes de unidade?

Depende do escopo, novamente ... por definição, um teste de unidade está testando uma única unidade. Mas se você puder testar completamente um módulo completo de uma só vez, se desejar, faça-o. Na verdade, você está realizando vários testes de unidade em um único hit.

Além disso, os testes de integração devem ser colocados no mesmo projeto de teste do meu projeto de teste de unidade?

Não há razão fundamental para não ... a menos que o teste de nível superior seja realizado por um testador independente, nesse momento você deve emitir apenas uma instrumentação executável e mínima.

Andrew
fonte
2
Não vejo como o teste de integração é mais fácil, mais rápido ou mais barato. Para mim é o oposto de todos os testes 3. E de integração são geralmente mais frágil do que testes de unidade
Earlz
0

Quando tenho projetos pequenos, apenas coloco todos os testes no mesmo projeto. Como um projeto maior teria essas divisões, apenas garanto que seria possível separá-las, se necessário.

Com testes de unidade, normalmente teste apenas uma classe (SUT) em um arquivo.


fonte