ATM Digital | Artigos - A importância dos testes unitários

Blog

A importância dos testes unitários

Postado em: 20/02/2015 | Por: João Paulo

Para que um soldado possa suportar os desafios físicos, o estresse e estar preparado na batalha, ele é submetido a treinamentos. Na Roma Antiga, os soldados, ou legionários, praticavam diversas atividades físicas, como natação e corrida, e também marchavam em formação com todo seu pesado equipamento a fim de estarem totalmente preparados para a batalha.

No desenvolvimento de software, podemos dizer que os testes funcionam como o treinamento dos soldados. Eles dão maior qualidade ao software, pois no treinamento, ou melhor, teste, colocamos o código numa simulação de batalha. Submetemos o mesmo a várias combinações de entradas e validamos suas saídas, e em consequência desta ação, falhas ou deficiências, são identificadas e corrigidas antes do código ser disponibilizado em situação real, economizando tempo de suporte, que se traduz em economia de dinheiro.

Os generais romanos organizavam seus legionários em Formações. Havia sete tipos de Formação, cada qual para uma situação no campo de batalha. Da mesma forma, podemos lançar mão de diversos tipos de testes de software, que podem ser categorizados por nível (unitário, de integração, de sistema etc), objetivo (regressão, alfa, beta, aceitação) ou performance (load, stress, pico, etc). Nosso foco nesta publicação será o Teste Unitário.

Em primeiro lugar, o que é “Teste Unitário”? Basicamente é o teste automatizado de uma unidade mínima de software, que em Java, seriam os métodos das classes. É um teste white box, ou seja, no cenário do teste temos conhecimento dos detalhes do funcionamento interno da unidade de código. Este teste não tem o objetivo de validar o funcionamento da aplicação como um todo, mas apenas de suas pequenas unidades isoladamente. Quando se testa várias unidades no mesmo teste, tem-se então o Teste de Integração, que não deve ser confundido com Teste de Integração de Sistemas, que visa testar os pontos de interação da aplicação com sistemas externos.

Uma Formação Romana consistia de soldados organizados em fileiras, formando um grande retângulo. Os soldados da primeira fila, eram os primeiros a enfrentar o inimigo. Contavam com o pilo, uma lança pesada e que tinha pouco alcance. Assim é o Teste Unitário. É o primeiro na linha de frente contra os bugs e deve ter pouco alcance, testar pequenas unidades de código.

Mas como dito, o Teste Unitário é o primeiro. Ele é uma ferramenta do programador (afinal é white box). Devemos ter mais de um tipo de teste. O desenvolvedor, como um legionário da linha de frente, deve garantir que aquilo que ele escreveu em suas unidades, esteja em conformidade com sua intenção. Seu código deve estar preparado para os “Edge cases”, ou situações extremas, como valor máximo, mínimo, valores nulos, números negativos, textos com somente espaços vazios, etc. Após o desenvolvimento, com teste das unidades, o sistema deve ser submetido a outros tipos de teste, automatizados ou não, para garantir a qualidade final.

O design dos componentes do software devem levar em conta os testes unitários, ou seja, os componentes produzidos devem ser testáveis. Deve-se privilegiar um design com unidades concisas e com o menor grau possível de acoplamento a outras unidades. Um bom conhecimento de design patterns e o despendimento de um tempo razoável no design e planejamento ajudam a alcançar um desenho com boas condições de testes das unidades.

Mas nada adianta se o time de desenvolvedores não estiver alinhado e engajado com os testes unitários. Imagine um legionário com seu pilo na frente da Formação, mas sem preparo físico, sem treinamento de batalha e desmotivado. Presa fácil para o inimigo. É importante que todo o time tenha conhecimento da metodologia e estratégia adotadas. Quando um novo desenvolvedor se junta ao grupo, deve ser preparado para garantir que os testes unitários sejam produzidos e que cumpram sua função de fato.

Não só os desenvolvedores devem levar a sério os testes unitários, mas a administração também. É comum ver os testes unitário relegados a “desperdício de tempo”. “O tempo que um desenvolvedor ‘perde’ codificando testes poderia ser utilizado no desenvolvimento de código ‘útil’”. Outros enxergam como algo legal, bonitinho, mas não se convencem da importância dos testes unitários, e na primeira oportunidade - como prazos apertados ou equipe reduzida - desertam.

Uma das vantagens dos testes unitários é a capacidade de serem executados quantas vezes forem necessárias, portanto seu custo de execução é baixo se comparado com testes manuais, que por outro lado demandam menos tempo no seu planejamento.

Uma desvantagem dos testes unitários é a complexidade que traz aos refactories. É difícil repensar os componentes, e ao mesmo manter os testes já desenvolvidos. Outro fator negativo é a falta de cultura de testes automatizados de muitos dos desenvolvedores.

É importante que desenvolvedores de software e sua administração adotem ou reforcem a cultura de testes unitários. A organização deve ter metodologia e estratégia claras para os testes. Todos devem ter conhecimento do escopo dos testes unitários, que não são adequados para testes funcionais ou de regras de negócios complexas (compostas de várias unidades de código). O objetivo deve ser sempre entregar software de qualidade e não desperdiçar recursos financeiros, incluindo os dos clientes, com a correção de bugs.

Como diria o general Júlio César, veni, vidi, vici, que no nosso contexto, digamos, quer dizer: codifiquei, testei, entreguei.

Referência:
http://en.wikipedia.org/wiki/Software_testing
http://en.wikipedia.org/wiki/Edge_case
http://pt.wikipedia.org/wiki/Forma%C3%A7%C3%B5es_romanas#Lidando_com_bigas_e_elefantes

SOBRE O AUTOR
João Paulo é arquiteto java na ATM Digital, com 15 anos de experiência em desenvolvimento de sistemas, e atua no desenvolvimento e sustentação de aplicações web e integração de sistemas.