TDD para código de infraestrutura? Acho que não…

Após iniciar um texto sobre a importância de testes automatizados para código de definição de infraestrutura, refleti sobre o uso de TDD nesses casos e cheguei a uma conclusão um pouco polêmica.

Queria deixar claro que esse texto é propositivo e aberto a mudança de opiniões com base nas interações. Meu objetivo é iniciar esse debate, apresentado as minhas conclusões sobre esse assunto e assim possamos juntos concluir algo coletivamente sobre isso.

Antes de pular para conclusão, vamos primeira contextualizar o que é TDD. De acordo com o nosso “nerd alfa” Martin Fowler:

“Test-Driven Development (TDD) é uma técnica para construção de software que o processo de desenvolvimento através da escrita de testes.”

De acordo com esse artigo, é uma prática que força o desenvolvedor a pensar sobre seu código antes de ele escrever ele e que TDD é muito mais sobre design do que teste. (Dica do Luis, no comentário).

Em essência você segue dois simples passos repetidamente:

  • Escreva um teste para validar a funcionalidade que precisa adicionar

Exemplo: Quero uma função para somar dois números, eu escrevo um teste que a soma de 2 + 2 o resultado seja sempre 4. Qualquer resultado diferente desse indica que a função está errada

  • Escreva de forma imperativa o código até ele passe nos testes

Exemplo: Você escreve o código que recebe dois número como parâmetros e soma.

Seguindo essa lógica é fácil pensar que seria ideal isso acontecer também para infraestrutura, certo? Não necessariamente.

Código de infra geralmente é descritivo e não imperativo

Nos exemplos demonstrados acima, temos, a partir de um único teste, uma grande gama de possibilidade de implementação da função a ser testada, ou seja, para um teste de soma de dois números, o código resultante para satisfazer essa validação pode variar bastante.

Desenvolvimento de software normalmente utiliza o modelo imperativo de construção, ou seja, você precisa dizer detalhadamente de que forma ,o que você deseja, seja feito. O código de infraestrutura regularmente segue uma outra linha, que é a descritiva. Você apenas precisa dizer o que deseja e não precisa implementar como isso será executado.

Comparação entre código imperativo e descritivo

Porque não TDD

Levando em consideração que um dos motivadores do TDD seja o auxilio na construção da lógica por trás da solução do teste em questão e no modelo descritivo a lógica é algo raro, fazer um teste para cada definição de infraestrutura me parece um trabalho desnecessário, já que o código de teste seria bem parecido com o usado para atender o teste.

Exemplo:

Quero criar o usuário elmo e o teste seria criado da seguinte maneira com o serverspec

describe user('elmo') do it { should exist } end

O código de infraestrutura para atende o teste acima seria:

user { 'elmo': ensure => present, }

Você há de concordar que esse teste nunca falharia, uma vez que não precisei de nenhuma lógica aqui. Sem falar que eles são bem parecidos na sua escrita, ou seja, no final de contas seria um grande desperdício de tempo.

E se meu código tiver lógica, faz sentido TDD?

Tecnicamente falando, sim, mas na prática nem toda definição terá lógica e ter isso como metodologia de desenvolvimento talvez atrapalhe mais do que gere algum valor para seu processo de desenvolvimento.

Isso quer dizer que não devo ter teste no meu código?

Claro que não! Testes automatizados são bem importantes para a confiança do seu código. Não vou me aprofundar nas razões de ser fazer teste, pois isso foi bem explicado aqui.

Atualização pós comentários

Depois de uma boa interação nos comentários, vale a pena deixar claro algumas coisas que talvez tenham ficado meio solta no artigo e adicionar outras que faltaram no texto ou estavam de forma incorreta.

TDD somente com teste unitário?

A ideia que é TDD seja orientado a teste unitário não foi proposital, mas no caso de teste de infraestrutura esqueci de comentar que testes de integração e outros mais complexos demandam interação com uma infraestrutura provisionada, ou seja, o feedback é bem lento, o que inviabiliza (em minha opinião) o trabalho orientado a teste.

É importante que você crie seu ambiente “do zero” a cada teste, para que você garanta que não tem dado de outro teste ou alguma modificação fora da definição no ambiente. Com isso em mente, é comum encontrar situações que podem demorar até 30 minutos para reconstruir o ambiente, aplicar as definições e então executar os testes.

Se você for utilizar testes de integração ou outros mais complexos pra guiar seu processo de desenvolvimento, ter esse tempo de espera a cada interação “Red-Green-Refactor” seria complicado para o processo de escrita de código.


Originally published at techfree.com.br.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.