Testes de integração, mas quanto?

8

Um debate recente dentro da minha equipe me fez pensar. O tópico básico é quanto e o que devemos cobrir com testes funcionais / de integração (com certeza, eles não são os mesmos, mas o exemplo é fictício onde não importa).

Digamos que você tenha uma classe "controller" algo como:

public class SomeController {
    @Autowired Validator val;
    @Autowired DataAccess da;
    @Autowired SomeTransformer tr;
    @Autowired Calculator calc;

    public boolean doCheck(Input input) {
        if (val.validate(input)) {
             return false;
        }

        List<Stuff> stuffs = da.loadStuffs(input);
        if (stuffs.isEmpty()) {
             return false;
        }

        BusinessStuff businessStuff = tr.transform(stuffs);
        if (null == businessStuff) {
            return false;
        }

       return calc.check(businessStuff);
    }
}

Precisamos de muitos testes de unidade com certeza (por exemplo, se a validação falhar ou se não houver dados no DB, ...), isso está fora de questão.

Nossa questão principal e sobre o que não podemos concordar é que a quantidade de testes de integração deve cobrir :-)

Estou do lado de que procuraremos menos testes de integração (pirâmide de teste). O que eu cobriria disso é apenas um caminho feliz e infeliz, em que a execução retorna da última linha, apenas para ver se eu coloco essas coisas juntas, não vai explodir.

O problema é que não é tão fácil dizer por que o teste resultou em falso, e isso faz com que alguns dos caras se sintam desconfortáveis ​​com ele (por exemplo, se simplesmente verificarmos apenas o valor de retorno, fica oculto que o teste é verde porque alguém alterou a validação e ela retorna false). Claro, sim, podemos cobrir todos os casos, mas isso seria um imho excessivo.

Alguém tem uma boa regra de ouro para esse tipo de problema? Ou uma recomendação? Lendo? Conversa? Postagem no blog? Alguma coisa sobre o assunto?

Muito obrigado antecipadamente!

PS: Procure o exemplo feio, mas é muito difícil traduzir uma parte específica do código em um exemplo. Sim, pode-se discutir sobre lançar exceções / usar um tipo de retorno diferente / etc. mas nossa mão está mais ou menos limitada por causa de dependências externas.

PS2: mudei este tópico de SO para cá (pergunta original, marcada em espera )

rlegendi
fonte

Respostas:

6

Existe uma escola de pensamento que questiona seriamente o valor dos testes de integração.

Suspeito que você obtenha um amplo espectro de respostas aqui, mas, na minha opinião, você só deve usá-las quando elas oferecerem um valor claro.

Primeiramente, você deve escrever o maior número possível de testes de unidade, porque a) eles são baratos eb) podem ser os únicos testes executados no servidor de compilação (se você tiver um).

É tentador escrever testes do lado do cliente para verificar o banco de dados ou alguma outra camada, mas eles devem realmente ocorrer no nível apropriado, se possível, em vez de criar um teste de integração. É claro que isso pode exigir algumas bases na forma de interfaces, etc.

Considere também o escopo do seu teste. Se você está simplesmente escrevendo um teste de integração para encobrir o que acontece de qualquer maneira quando seu conjunto é executado ou duplicando um teste de fumaça, isso tem valor limitado. Além disso, pense se mais log em locais pertinentes seria uma opção melhor do que receber uma mensagem obscura de uma dúzia de componentes interconectados e ter que rastreá-la.

Então, supondo que você tenha decidido escrever alguns, precisa pensar em quando eles serão executados. Se eles podem pegar algum problema desagradável, isso é ótimo, mas fica inútil se os desenvolvedores nunca se lembrarem de executá-los.

Por fim, os testes de integração são uma substituição totalmente inadequada para testes de fumaça e testes de usuários. Se você se preocupar com eles, eles devem formar uma pequena parte de um processo de teste bem projetado.

Robbie Dee
fonte
4
Apenas um comentário: observe que, inversamente, existe uma escola de pensamento que questiona seriamente o valor dos testes de unidade (o DHH afirma estar questionando o TDD, mas se você ler o post dele, ele também questiona os testes de unidade). Para ser honesto, eu encontrar coisas para concordam e discordam de ambas as escolas extremistas de pensamento :)
Andres F.
1
Uma grande parte do dogma em torno de TDD em torno não está escrevendo qualquer coisa que você não precisa que qualquer desenvolvedor experiente sabe através YAGNI de qualquer maneira ...
Robbie Dee
4
Sua resposta é boa (+1); o artigo que você citou, no entanto, tem o problema que o autor dá a impressão apenas porque os testes de integração não funcionaram para o caso dele , eles não funcionarão para mais ninguém. Em nossa equipe, estamos usando testes de integração aqui para o nosso produto há mais de 10 anos na prática, e eles nos impediram de implantar bugs graves muitas vezes, então acho que é realmente possível escrever testes de integração que ofereçam alto valor.
Doc Brown
O autor também escreve em um comentário "Testes integrados (não" testes de integração "!) [...]" - Não tenho certeza da diferença, mas parece-me que há muitas nuances envolvidas se um teste de integração é útil ou bom.
Carson Myers
Na minha experiência, apenas testes de integração realmente agregam valor. Os testes de unidade, em particular aqueles que usam zombaria, são mais problemáticos do que valem. No meu projeto atual, por exemplo, temos 650 testes de integração baseados em JUnit que são executados em todas as confirmações em um servidor Jenkins, com a compilação completa levando menos de 10 minutos. Obviamente, também executamos testes em nossos IDEs enquanto fazemos TDD. Não vemos a necessidade de ter um conjunto adicional de testes de unidade - isso acrescentaria muito mais esforço sem nenhum ganho aparente. Talvez a razão pela qual alguns desenvolvedores evitem os testes de integração seja simplesmente porque eles realmente não tentaram?
Rogério
8

Contrariamente a essa resposta , considero o teste em diferentes níveis parte importante do processo de teste do software. Unidade, funcional, integração, fumaça, aceitação e outros tipos de testes estão testando coisas diferentes, e quanto mais, melhor.

E se você conseguir automatizá-los, eles poderão ser executados como um trabalho de sua integração contínua (como jenkins). Ninguém precisa executá-los para ver se eles quebraram, pois todos podem ver se os testes falharam.

Nos meus testes de integração, não entro em detalhes - detalhes e casos de canto são para testes de unidade. O que eu testei é apenas a principal funcionalidade, passando todos os parâmetros corretos. Isso significa que, no seu exemplo, nos testes de integração, eu não cobriria caminhos falsos.

BЈовић
fonte
1
+1 Sim, se você pode fazer testes de integração na compilação, tanto melhor, mas isso pode ser uma tarefa significativa nas soluções de nível corporativo.
Robbie Dee