The different types of software testing

Compare diferentes tipos de testes de software, como teste de unidade, teste de integração, teste funcional, teste de aceitação e muito mais!

Sten Pittet Sten Pittet

There are many different types of testing that you can use to make sure that changes to your code are working as expected. Not all testing is equal, though, and we will see here how the main testing practices differ from each other.

Teste manual vs. automatizado

Em um alto nível, precisamos fazer uma distinção entre testes manuais e automatizados. Teste manual é feito pessoalmente, clicando no aplicativo ou interagindo com o software e as APIs com as ferramentas adequadas. Isso tem um custo muito alto e requer alguém para configurar um ambiente e executar os testes por si mesmo, e pode estar propenso a erros humanos, uma vez que o testador pode cometer erros ortográficos ou omitir etapas no script de teste.

Testes automatizados, por outro lado, são realizados por uma máquina que executa um script de teste escrito com antecedência. Esses testes podem variar muito em termos de complexidade, de verificar um único método em uma classe a garantir que realizar uma sequência de ações complexas na interface do usuário leve aos mesmos resultados. São muito mais robustos e confiáveis que testes automatizados. Porém, a qualidade dos testes automatizados depende de quão bem seus scripts de teste foram escritos.

Teste automatizado é um componente essencial de integração contínua e entrega contínua e é uma ótima maneira de dimensionar seu processo de QA conforme você adiciona novos recursos ao seu aplicativo. Porém, ainda há valor em realizar alguns testes manuais com o que se chama de teste exploratório, como veremos neste guia.

Os diferentes tipos de testes

Testes de unidade

Testes de unidade são feitos em um nível muito baixo, próximo ao código-fonte do seu aplicativo. Eles consistem em testar métodos e funções individuais de classes, componentes ou módulos usados pelo seu software. Testes de unidade geralmente têm um baixo custo para automatizar e podem ser executados muito rapidamente por um servidor de integração contínua.

Testes de integração

Testes de integração verificam se diferentes módulos ou serviços usados pelo seu aplicativo funcionam bem juntos. Por exemplo, pode ser testar a interação com o banco de dados ou garantir que os microsserviços funcionem juntos conforme o esperado. A execução desses tipos de testes tem um custo maior, uma vez que exigem que várias partes do aplicativo estejam ativas e em execução.

Testes funcionais

Functional tests focus on the business requirements of an application. They only verify the output of an action and do not check the intermediate states of the system when performing that action.

Às vezes há uma confusão entre testes de integração e testes funcionais, uma vez que ambos exigem vários componentes para interagirem entre si. A diferença é que um teste de integração pode simplesmente verificar que você pode consultar o banco de dados, enquanto um teste funcional esperaria obter um valor específico do banco de dados conforme definido pelos requisitos do produto.

Testes de ponta a ponta

Teste de ponta a ponta replica o comportamento de um usuário com o software em um ambiente de aplicativo completo. Ele verifica se vários fluxos de usuário funcionam como o esperado e podem ser tão simples quanto carregar uma página da web ou fazer login ou cenários muito mais complexos verificando notificações por e-mail, pagamentos on-line etc.

Testes de ponta a ponta são muito úteis, mas têm um alto custo e podem ser difíceis de atualizar quando automatizados. Recomendamos ter alguns testes de ponta a ponta essenciais e contar mais com tipos de testes de nível inferior (testes de unidade e de integração) para poder identificar rapidamente alterações que causam falha.

Teste de aceitação

Os testes de aceitação são testes formais executados para verificar se um sistema atende aos requisitos de negócios. Eles exigem que todo o aplicativo esteja ativo e em execução e foca em replicar os comportamentos do usuário. Porém, também pode ir mais além e medir o desempenho do sistema e rejeitar alterações se determinadas metas não forem cumpridas.

Performance testing

Performance tests check the behaviors of the system when it is under significant load. These tests are non-functional and can have the various form to understand the reliability, stability, and availability of the platform. For instance, it can be observing response times when executing a high number of requests, or seeing how the system behaves with a significant of data.

Testes de desempenho são, por natureza, bastante caros de implementar e executar, mas podem ajudá-lo a entender se novas alterações forem degradar seu sistema.

Teste de sanidade

Testes de sanidade são testes básicos que verificam a funcionalidade básica do aplicativo. Eles são feitos para terem execução rápida, e sua meta é garantir que os principais recursos do seu sistema estejam funcionando conforme o esperado.

Smoke tests can be useful right after a new build is made to decide whether or not you can run more expensive tests, or right after a deployment to make sure that they application is running properly in the newly deployed environment.

Como automatizar seus testes

Uma pessoa pode executar todos os testes mencionados acima, mas será muito dispendioso e contraproducente fazer isso. Como humanos, temos capacidade limitada para realizar um grande número de ações de maneira repetível e confiável. Porém, uma máquina pode fazer isso de modo rápido e fácil e testará se a combinação de login/senha funciona pela 100ª vez sem reclamar.

Para automatizar seus testes, você primeiro vai precisar escrevê-los de modo programático usando uma estrutura de teste adequada ao seu aplicativo. PHPUnitMochaRSpec são exemplos de estruturas de teste que você pode usar para PHP, Javascript e Ruby, respectivamente. Há muitas opções por aí para cada linguagem, assim, você precisa pesquisar e pedir para as comunidades de desenvolvedores descobrirem qual seria a melhor estrutura para você.

Quando seus testes podem ser executados por meio de script do seu terminal, você pode fazer com que sejam executados automaticamente por um servidor de integração contínua, como o Bamboo, ou usar um serviço de nuvem, como o Bitbucket Pipelines. Essas ferramentas vão monitorar seus repositórios e executar seu pacote de teste sempre que novas alterações forem enviadas ao repositório principal.

Cada push para o repositório é verificado graças ao Bitbucket Pipelines

If you're just getting started with testing, you can read our continuous integration tutorial to help you with your first test suite.

Teste exploratório

Quanto mais recursos e melhorias forem incluídos no seu código, mais você precisará testar para garantir que seu sistema funcione adequadamente. Então, para cada bug que você corrigir, é bom verificar para que não voltem em novas versões. Automação é crucial para tornar isso possível e escrever testes mais cedo ou mais tarde se tornará parte do seu fluxo de desenvolvimento.

Assim, a pergunta é: ainda vale a pena realizar teste manual? A resposta breve é sim, e deve ser focado no que chamamos de teste exploratório, em que a meta é descobrir erros não óbvios.

An exploratory testing session should not exceed two hours and need to have a clear scope to help testers focus on a specific area of the software. Once all testers have been briefed, is up to them to try various actions to check how the system behaves. This type of testing is expensive by nature but is quite helpful to uncover UI issues or verify complex user workflows. It's something especially worth doing whenever a significant new capability is added to your application to help understand how it behaves under edge cases.

Uma observação sobre testes

To finish this guide, it's important to talk about the goal of testing. While it's important to test that users can use your application (I can log in, I can save an object) it is equally important to test that your system doesn't break when bad data or unexpected actions are performed. You need to anticipate what would happen when a user makes a typo, tries to save an incomplete form or uses the wrong API. You need to check if someone can easily compromise data, get access to a resource they're not supposed to. A good testing suite should try to break your app and help understand its limit.

And finally, tests are code too! So don't forget them during code review as they might be the final gate to production.