Flavio Milani
- Introdução ao TDD
- Frameworks TDD para JavaScript / Node
- Pirâmide de Testes
- Iniciar projeto com TDD
- Demonstrações de cada teste
Entender como iniciar um projeto TDD, como garantir qualidade de software e códigos limpos, conceitos de testes unitários, compreender como implementar e rodar os testes em funcionamento, com o resultado esperado ou erros gerados no relatório.
TDD significa Desenvolvimento Orientado por Testes (Test Driven Development), e trata-se de uma prática de desenvolvimento de software onde a codificação das funcionalidades começa a partir da escrita de testes unitários.
Essa técnica foi criada por Kent Beck e é um dos pilares do XP (Extreme Programming).
Red: escreva um pequeno teste automatizado que, ao ser executado, irá falhar;
Green: implemente um código que seja suficiente para ser aprovado no teste recém-escrito;
Refactor: refatore o código, a fim dele ser melhorado, deixando-o mais funcional e mais limpo.
No topo da pirâmide, temos os testes de ponta a ponta (end to end ou e2e, pra resumir). O objetivo deles é imitar o comportamento do usuário final nas nossas aplicações (seja ele uma pessoa, uma api, ou qualquer outro tipo de cliente).
Na base, temos os testes de unidade, onde verificamos o funcionamento da menor unidade de código testável da nossa aplicação.
Entre essas duas camadas, temos os testes de integração. A ideia deles é verificar se um conjunto de unidades se comporta da maneira correta, só que de forma menos abrangente do que os testes de ponta a ponta.
Escrever um teste que falha
Fazer o teste passar
test('should sum the numbers correctly', () => {
let num1 = 3;
let num2 = 2;
result = calculator.sum(num1, num2);
expect(result).toBe(5);
});
-------------------------------
$ yarn test
yarn run v1.22.17
$ jest
PASS unit-tests/tests/calculator.test.js
PASS unit-tests/tests/message.test.js
● Console
console.log
Mensagem enviada com sucesso
at console.<anonymous> (node_modules/jest-mock/build/index.js:837:25)
PASS integration-test/tests/integration/persons.test.js
Test Suites: 3 passed, 3 total
Tests: 14 passed, 14 total
Snapshots: 0 total
Time: 1.294 s, estimated 2 s
Ran all test suites.
Done in 2.09s.
Refatorar o código
Rodar teste unitário e de integração:
yarn test
yarn test:watch
Rodar cobertura de testes:
yarn coverage
Rodar teste de ponta a ponta (e2e):
yarn run cypress:open
Vantagens de testes de unidade:
-
Diminuir a quantidade de bugs do sistema;
-
Diminuir a necessidade de testes manuais;
-
Desenvolver uma arquitetura mais eficiente;
-
Facilitar o refactoring e aumentar a confiança.
Arrange: Para que o teste possa rodar que inicializa variáveis
Act: Executa o código em teste.
Assert: Verifica se o resultado é esperado quando o teste passa ou falha.
test('should sum the numbers correctly', () => {
// Arrange (Preparar o teste)
let num1 = 3;
let num2 = 2;
// Act (Rodar o teste)
result = calculator.sum(num1, num2);
// Assert (Verificar as asserções)
expect(result).toBe(5);
});
Abrindo o arquivo gerado em coverage/lcov-report/index.html), faltam alguns testes para garantir o correto funcionamento da aplicação, e por assim uma boa cobertura de testes.
Teste de integração é o teste que é realizado entre módulos diferentes em um sistema.
- Testar o sistema fazendo requisições HTTP (GET, POST, PUT, DELETE)
- Analisar a requisição, verificar o resultado retornado e código de resposta
- Comunicar entre sistema e banco de dados
- Integrar sistema em API
Testes end-to-end são úteis para testar grandes fluxos de trabalho, especialmente quando eles são críticos para o seu negócio
- Pagamentos
- Criação de contas
- Renderização da aplicação inteira
- Endpoints da API
- Sessões e Cookies
- Navegação entre links diferentes
Documentação de Cypress: https://docs.cypress.io/guides/getting-started/installing-cypress
Instalar cypress:
yarn add cypress --dev
Rodar teste de ponta a ponta (e2e):
yarn run cypress:open
No arquivo package.json:
{
"devDependencies": {
"cypress": "^10.8.0",
"jest": "^29.0.1",
"supertest": "^6.2.4"
},
"scripts": {
"test": "jest",
"start": "nodemon integration-test/index.js",
"test:watch": "jest --watch",
"coverage": "jest --coverage",
"cypress:open": "cypress open"
},
"dependencies": {
"express": "^4.18.1",
"nodemon": "^2.0.20"
}
}