O Elemar Jr está em dúvida sobre isso e colocou no blog dele um diálogo interessante que teve com o Juan Lopes, onde o Juan defende que testes de unidade são mais importantes, e o Elemar acha o contrário. Leiam lá pra entender a discussão, e leiam também os comentários.

Em vez de deixar um comentário no blog do Elemar achei melhor colocar o comentário aqui e depois eu volto lá e linko pro comentário, e vocês ganham poder ler a discussão toda. Aproveitem e já leiam o resto do blog também que é muito bom. Vamos lá.

É difícil classificar testes de unidade ou integrado ou aceitação como importante ou menos importante. Depende de qual ponto de vista você observa. É isso que tenho visto que leva alguns a defender um ou outro como mais importante. Basta observar o post e os comentário pra perceber isso.

Por esse motivo, temos que entender exatamente do que estamos falando.

Do ponto de vista de que um teste é responsável por me dizer quando um sistema quebra: tanto testes de unidade quanto de integração são capazes de dizer isso, mas de fato, assim como aponta o Juan, os de integração dificilmente vão apontar exatamente o local. Os de unidade são muito mais precisos do que os de integração nesse sentido. Por outro lado, se um teste de unidade quebrar, um de integração também deveria quebrar. Dessa forma, tenho uma informação mais genérica, mas que aponta na direção do negócio, e tenho uma informação mais precisa, que aponta na direção técnica. Qual a mais importante? Depende da sua necessidade. Eu diria que as duas são importantes e depende do que você está fazendo. Não diria que dá pra prescindir de nenhuma das duas.

Mas há uma diferença aí: não necessariamente quando um teste de integração quebrar, um teste de unidade irá quebrar também. O problema pode ser justamente na integração, enquanto as unidades funcionam bem, há um erro em como elas se inter-relacionam. Isso torna os testes de integração mais efetivos pra pegar erros, por serem mais abrangentes: testam as unidades, mas também como se integram.

Do ponto de vista da facilidade de escrita e produtividade de escrita: lógicamente testes de unidade são melhores nesse ponto de vista. A questão é: essa característica é mais importante do que as outras? Difícil dizer isso. É verdade que se você focar em escrever testes de ponta a ponta não vai ter tempo de fazer testes de unidade? Não, não é verdade, dado o uso correto das ferramentas disponsíveis esses testes serão mais lentos para serem escritos, mas não vão tomar todo o seu tempo. Por outro lado, o código usado em testes integrados com frequencia pode ser utilizado também para o caso real, servindo de inspiração para a escrita das camadas mais externas.

Quanto ao estilo de trabalhar usando BDD ou ATDD, com outside-in. Eu sei do benefício de trabalhar dessa forma, essa é a forma com que eu trabalho, e praticamente toda a equipe da Lambda3 trabalha. Nós criamos testes de aceitação automatizados utilizando técnicas como o BDD. Esse tipo de teste, que na verdade é uma especificação executável, é importante porque ajuda a guiar o comportamento do software. Nem encaro esse tipo de artefato como um teste, ao menos enquanto está sendo usado para descrever um comportamento. Depois, ok, trata-se de um teste de regressão. Mas esse é simplemente um efeito colateral positivo, não é o motivo que me faz trabalhar com BDD. Se o objetivo fosse ter testes de regressão eu poderia escrever testes depois, e eles não guiariam o comportamento.

Nem toda especificação executável escrita ao estilo de BDD será um teste integrado, mas em geral é muito mais comum que os testes escritos com BDD sejam testes integrados que podem ser encarados como testes de aceitação. Essa é a ideia por trás do outside-in, criar uma descrição de como o software se comporta, em termos de negócio, e dificlmente você faz isso com testes de unidade.

Com relação à fragilidade de testes integrados, isso é fato, testes que vão de uma ponta a outra do sistema com frequencia quebram por motivos alheios ao comportamento do sistema. Isso obviamente é um problema, que, é importante dizer, pode ser mitigado e diminuido ao ponto em que não chega a ser um problema, na grande maioria dos casos. E isso não quer dizer que testes de unidade são mais importantes, só que são mais resistentes.

Assim,  gostaria que, em vez de falarmos de importância, falemos de relevância dentro de um contexto. Alguns cenários serão melhores com testes de unidade, outros com testes integrados. Abrir mão de um martelo, só porque você tem uma excelente chave de fenda, me parece um pouco míope. Ambas as ferramentas são igualmente importantes quando necessárias.

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.