
O que é teste de software?
Testes muitas vezes podem parecer um bicho de sete cabeças, mas não passam de uma forma codificada de validar se uma regra está sendo atendida ou não, pois um teste só será válido se o que é esperado dele acontecer.
Exemplifiquemos:
Quando minha função de somar dois números inteiros recebe seus parâmetros para soma de um com outro (por exemplo, 1 + 1), espera-se que seu resultado seja a soma dos mesmos (resultado esperado igual a 2). Então, o nosso teste seria basicamente a validação de que nossa função está fazendo isso e não nos retornando um dado errado (se 1 + 1 for igual a 2, então nossa função está correta, teste passou).
Tipos de testes de software
Testes FUNCIONAIS:
Esse tipo de teste visa validar se os requisitos de negócios estão sendo atendidos, se as coisas que o cliente pediu estão sendo entregues. Por exemplo, valida se um formulário de inscrição está funcionando e direcionando as informações para o lugar correto. Isso pode se assemelhar muito a um teste de ponta a ponta, que falaremos mais à frente, mas a premissa dos testes funcionais é a validação dos requerimentos do cliente.
Testes NÃO FUNCIONAIS:
Ao contrário dos testes funcionais, esse tipo visa validar aspectos esperados pelo cliente, que não necessariamente podem ter sido requeridos durante a fase de negociação ou levantamento de requisitos junto ao cliente, mas são necessários para garantir um bom software. Os testes não funcionais visam garantir aspectos como desempenho (através de testes de carga), segurança e usabilidade.
Testes de UNIDADE:
Esse tipo serve para garantir o funcionamento correto no nível mais molecular de um software. Nele, como no exemplo do começo do artigo, testamos cada função ou método para saber se o que esperamos está acontecendo.
Teste de INTEGRAÇÃO:
O teste de integração já está um nível acima do teste de unidade, sendo mais abrangente e testando a interação entre métodos e funções. Ele é responsável por testar um fluxo. Vamos a um exemplo: imaginemos o fluxo de geração de um holerite de um funcionário, onde nosso teste seria responsável por validar se todos os fluxos foram aplicados corretamente, se as horas extras foram calculadas e se os descontos também foram computados corretamente. Atente-se que não faremos a validação de cada etapa, pois isso é responsabilidade dos testes unitários. No teste de integração, verificaríamos se, com base nos dados de um funcionário com X carga de horas e Y de impostos a serem deduzidos da folha de pagamento, o resultado esperado está sendo entregue pelo sistema.
Teste de PONTA A PONTA:
Assim como o anterior, o teste de ponta a ponta tem um escopo ainda maior. Ele é responsável por testar um fluxo completo. Então, continuando com o exemplo anterior, agora, com o teste de ponta a ponta, iremos testar o fluxo completo de fechamento da folha de pagamento. Devemos validar se, ao requisitarmos o fechamento da folha de um funcionário, o sistema é capaz de fazer o cálculo, além de validarmos se, ao fim da geração, os dados já foram encaminhados para o financeiro para pagamento dessa folha, além de disponibilizar para o funcionário seu holerite no sistema interno da empresa.
Teste de REGRESSÃO:
O teste de regressão se assemelha muito aos anteriores, pois, ao aplicá-lo, devemos validar o sucesso e a falha de um fluxo, o que devemos fazer para todos os anteriores. Devemos sempre projetar cenários de sucesso e de falha para termos certeza do que deve dar certo e do que deve dar erro. Mas esse tipo de teste tem mais uma finalidade: garantir que algo que está funcionando permaneça funcionando. Quem nunca se deparou com um problema que foi corrigido em seu programa ou jogo favorito e, após algum tempo, esse problema voltou a acontecer? O teste de regressão evita esse tipo de problema, pois, ao realizarmos uma alteração ou uma correção, devemos escrever o cenário para o teste que antes fazia o problema acontecer e, depois da correção, isso não ocorre mais. Assim, se por ventura esse problema acontecer novamente, o teste irá acusar que algo está errado nessa nova versão que está sendo implementada.
Por que usar testes?
Como podemos ver até aqui, testes são uma ferramenta muito poderosa para garantir que uma alteração não quebre algum fluxo ou mesmo nosso software por completo. Em ambientes onde testes não são uma prática comum, pode-se ver muitos problemas de atualizações que quebram alguma coisa ou que afetam o funcionamento de outras.
Alguns argumentam que testes são muito custosos e demandam muito da equipe, pois testes bem feitos realmente demandam tempo para serem implementados. Existem algumas alternativas e abordagens que o mundo da programação usa para ajudar quem precisa de mais agilidade na hora de realizar testes em seus softwares. Mas não existe forma fácil de realizar essa mudança de mentalidade. É comprovado que softwares com testes têm uma confiabilidade maior e uma maior velocidade de desenvolvimento a longo prazo.
Observações:
Recomendo a quem se interessar pelo tema e quiser se aprofundar que busque ferramentas de testes para sua linguagem de programação favorita e faça alguns cenários para entender melhor o que são testes. Abaixo, vou deixar alguns links das ferramentas mais conhecidas para testes de cada linguagem:
- JavaScript / TypeScript → Jest – Cypress
- Python → pytest – Selenium
- Java → JUnit
- C# (.NET) → xUnit
- PHP → PHPUnit
- Ruby → RSpec
E se você quer se aprofundar ainda mais, recomendo pesquisar sobre TDD (Test-Driven Development ou Desenvolvimento Orientado por Testes). TDD é basicamente o desenvolvimento guiado por testes, como o nome diz, onde, para o desenvolvimento de um software, você parte da implementação de seus cenários de testes antes de partir para a implementação real das funções e métodos. Isso pode inicialmente parecer loucura, afinal, como testar algo que ainda não existe? Mas a lógica é exatamente essa: a partir de um requisito de negócio, constrói-se o cenário de teste que deve garantir que o requisito seja atendido. Com os testes prontos, torna-se mais fácil a implementação do código, pois o que deve ser construído já é sabido.