Fala, galera! Tudo bem? Meu nome é Tereza e eu serei a instrutora da aula de Automação de Testes.
Clique aqui, para acessar o material da aula.
O nível da nossa aula é introdutório, onde aprenderemos o que é e como fazer testes desde a fase inicial de construção de uma aplicação (teste unitário), como também na fase de um projeto já pronto e estruturado (teste de API). Vamos entender os tipos e regras de testes, conceitos que envolvem qualidade, investimentos e a famosa pirâmide de testes.
Nós iremos colocar a mão no código, padronizando códigos com o ESLint e criando testes com as ferramentas Jest e Supertest.
Durante a aula, nós vamos utilizar dois projetos:
-
O diretório projeto1 será para testes estáticos e unitários. Vamos criar alguns códigos, padronizar e fazer leitura de testes usando ESLint, e fazer testes manuais construindo um framework.
-
O segundo projeto será para teste de API, nos guiaremos com o arquivo md
testesAPI.md
. Se observarem, é a mesma API Livraria que praticamos na aula Integração Banco de Dabos. O objetivo é testar os endpoints que elaboramos. Aprenderemos como testar com a ferramenta Jest.
A atividade para casa será reproduzir os testes na mesma API que você utilizou na atividade da aula Integração Banco de Dados. Você deverá seguir o passo a passo do teste de API, que está no arquivo testeAPI.md
e aplicar na API de sua escolha.
A atividade será avaliada nos seguintes critérios:
-
Criação de pasta e arquivo de test;
-
Estutura de código para teste das rotas da API;
-
Sintaxe de testes usando describe e matchers;
-
Uso do Jest e ESLint.
Vamos começar a nossa primeira experiência com testes, é muito importante darmos uma atenção aos testes que já estão presentes nas primeiras etapas do desenvolvimento de códigos, antes da aplicação ser executada. Chamamos de testes estáticos.
Teste estático, é uma análise feita nos artefatos de uma aplicação, ou seja, as unidades físicas de execução da aplicação, alguns exemplos são os requisitos, estória de usuário, arquitetura e o código-fonte do projeto.
Esse tipo de teste visa garantir uma padronização ortográfica, evitando defeitos por erros de escrita e sintaxe inadequada.
A grande característica do teste estático é que ele é feito sem a execução do código, ele pode ser feito manualmente como forma de revisão (um colega pode revisar seu código procurando erros) e pode ser feita como análise estática com o uso de ferramentas. Ferramentas assim são do tipo lint. Podemos encontrar ferramentas lint para variadas linguagens de programação.
Nesta aula, usaremos o lint ESLint
.
Vamos instalar o ESLint como "dev dependencie", pois vamos usa-lo apenas enquanto no processo de desenvolvimento. Nesta aula vamos usar a versão 8.16.0, para evitar risco de atualização de versão e divergências na execução do projeto, vamos usar o comando --save-exact
, que garante manter exatamente a versão escolhida.
npm install --save-dev eslint@8.16.0 --save-exact
Agora vamos executar o ESLint com o comando:
npx eslint --init
No terminal, será iniciado o processo de configuração do ESLint e aparecerão algumas perguntas. Você pode "customizar" o ESLint de acordo com a necessidade do seu projeto.
Para esta aula, configuramos o ESLint da seguinte forma:
- √ How would you like to use ESLint? · style
- √ What type of modules does your project use? · commonjs
- √ Which framework does your project use? · none
- √ Does your project use TypeScript? · No
- √ Where does your code run? · node
- √ How would you like to define a style for your project? · guide
- √ Which style guide do you want to follow? · airbnb
- √ What format do you want your config file to be in? · JSON
- √ Would you like to install them now? · Yes
- √ Which package manager do you want to use? · npm
Após a conclusão da intalação, na raiz do projeto será criado o arquivo .eslintrc.json
, um JSON contendo os dados que definimos no processo de configuração.
No diretório do curso, dentro da pasta teste-estático
, vamos criar um arquivo chamado index.js
. Iremos criar uma função simples para simular soma de compras e taxa de entrega.
Após a fazermos a instalação, foi criado um arquivo chamado .eslintrc.json, que logo mais iremos dar uma olhada.
No arquivo package.json, vamos adicionar um script para executar o ESLint na pasta que criamos teste-estático
que ficará assim:
"scripts": {
"lint": "npx eslint --fix ./testes-estaticos",
"test": "echo \"Error: no test specified\" && exit 1"
},
No arquivo index.js
, vamos criar um trecho de código para executarmos o eslint, colocaremos um erro de grafia propositalmente.
const livros = 3;
const biblioteca = livro + 1;
Vamos executar o comando lint no terminal:
npm run lint
No terminal, o resultado poderá ser semelhante a imagem abaixo.
Ao executarmos o comando, o ESLinte irá gerar um resumo da análise de erro, vamos aprender a fazer a leitura dessa validação, cada linha de erro é composta de blocos de informações.
- A linha e coluna do erro é informada logo no início, para facilitar a localização;
- Em seguida temos a identificação se é um erro ou um alerta (podemos configurar isso);
- Em seguida temos a mensagem detalhando o problema que será corrigido;
- Por último, a regra que esse erro pertence (também iremos configurar).
No terminal, observamos que o ESLinte analisou nosso código e identificou os seguintes erros:
- Na linha 1:7 diz que a variável “livros” teve valor atribuído mas não foi utilizada.
- Na linha 2:7 diz que a variável “biblioteca” teve valor atribuído mas não foi utilizada.
- Na linha 2:20 diz que a variável “livro” não foi definida (justamente o erro proposital que criamos e que impactou em todo restante do código).
Vamos manter esse erro e testar um pouco mais a frente.
Apesar do relatório gerado pelo comando npm run lint
ser muito eficiente, é possível melhorar ainda mais nossa produtividade nos testes estáticos. No VSCODE é possível instalar o plugin do ESLint, ao instalarmos somos alertados em tempo real dos erros existentes no código.
Instale o plugin e observe o código novamente. Veremos que os mesmos erros mostrados no relatório do terminal, estão sinalizados em vermelho. Se passarmos o mouse por cima, veremos uma mensagem sinalizando o erro.
Agora que entendemos como aplicar uma ferramenta de análise estática em nosso ambiente de desenvolvimento, podemos começar a entender como funciona a criação de cenários para testes.
Iremos aprender a fazer uma simulação simples de teste e criaremos um cenário para aplicação através de um mini framework de testes. Essa aula será importante para entender como os testes funcionam sem o uso de ferramenta, tendo a experiência de simular um teste manualmente.
Dentro da pasta testes-unitarios
, você encontrará o arquivo teste-framework.js
No arquivo existe a função somaCompra
, essa função recebe dois parâmetros “livroSelecionado” e “carrinho”, o objetivo dela é somar o valor dos livros selecionados na plataforma da livraria e somar com a taxa de entrega.
Para conferir se a função está somando corretamente, foi atribuido o bloco "if/else" para executar o teste de validação, usando a variável chamada esperado
que recebe o
resultado da soma das compras.
const somaCompras = (livroSelecionado, taxaEntrega) => {
return livroSelecionado + taxaEntrega;
};
let esperado = 55;
let retorno = somaCompras(50, 5);
if (esperado === retorno) {
console.log(`O teste deu certo :)`);
} else {
console.error(`O teste deu ruim :(`);
}
Na linha seguinte, existe uma outra função chamada estoque, que recebe os parâmetros livroEstoque
e livroSelecionado
, ela tem a tarefa de calcular a diferença disponível no estoque após a saída de uma certa quantidade de livros.
const estoque = (livroEstoque, livroSelecionado) => {
return livroEstoque - livroSelecionado;
};
esperado = 5;
retorno = estoque(10, 5);
if (esperado === retorno) {
console.log(`O teste deu certo :)`);
} else {
console.error(`O teste deu ruim :(`);
}
Vamos executar o teste? Digite no terminal o comando
node teste-framework.js
Para testar se ele reconhece se o cálculo está errado, podemos alterar o sinal de adição (+) para subtração (-) na função que criamos de somaCompras, e executar o teste novamente.
O comportamento está sendo o esperado, porém, considerando num projeto maior, se houver uma falha, não saberemos de onde está partindo o erro. Por esse motivo, precisaremos refatorar o código do arquivo teste-framework.js
vamos criar uma variável chamada teste, ela receberá um parâmetro chamado “titulo”, também incluiremos os parâmetros "retorno” e “esperado”, eles serão úteis para nominar o teste quando executarmos.
Vamos também simplificar nosso código para um único if/else, e por fim, iremos atribuir os valores de entrada com a nova variável. Conseguiremos usar para o teste das funções somaCompras e estoque.
const somaCompras = (livroSelecionado, taxaEntrega) => {
return livroSelecionado + taxaEntrega;
};
const estoque = (livroEstoque, livroSelecionado) => {
return livroEstoque - livroSelecionado;
};
const teste = (titulo, esperado, retornado) => {
if (esperado === retornado) {
console.log(` ${titulo} deu certo :)`);
} else {
console.log(` ${titulo} deu ruim :(`);
}
};
teste("somaCompras", 10, somaCompras(5, 5));
teste("estoque", 30, estoque(50, 20));
Agora vamos executar o framework novamente no terminal, e observar o resultado:
node teste-framework.js
Agora conseguimos ter um retorno mais preciso, sinalizando exatamente de onde está partindo o resultado do teste.
Chegamos numa etapa importante dos testes, nós vamos conhecer a ferramenta de teste mais conhecida da comunidade JavaScript, que é o Jest.
Ele foi inicialmente desenvolvido pelo Facebook para testar o framework React, porém ganhou tanta destaque que também é usado com TypeScript, Node, Angular, Vue entre outros.
Além de ser seguro, o Jest tem uma documentação com orientações claras e objetivas.
Vamos iniciar o processo seguindo alguns passos:
- Instalamos o jest como devDependencies
npm install --save-exact jest@28.1.0 --save-dev
- Vamos modificar o script "test" que já existe dentro do arquivo package-json, iremos modificar para executar o Jest.
“test”: “jest”
Agora podemos fazer nossos testes automatizados com o Jest. Vamos usar o exemplo do framework de teste que criamos anteriormente, precisaremos copiar as funções "somaCompras" e "estoque".
Dentro da pasta testes-unitarios
criaremos o arquivo compras.js
, dentro do arquivo vamos colar apenas a função "somaCompras" e exportar com o método "module.exports".
const somaCompras = (livroSelecionado, taxaEntrega) => {
return livroSelecionado + taxaEntrega;
}
module.exports = somaCompras;
Criaremos o arquivo estoque.js
, vamos colar apenas a função "estoque" e exportar com o método "module.exports".
const estoque = (livroEstoque, livroVendido) => {
return livroEstoque - livroVendido;
}
module.exports = estoque;
Na raiz do projeto1, criaremos uma pasta chamada test
e dentro dela, criaremos o arquivo chamado vendas.test.js
. No arquivo iremos estruturar nosso código de teste do framework. Iremos utilizar os método expect
e o matcher toBe
do Jest.
const somaCompras = require ("../testes-unitarios/compras.js");
const estoque = require ("../testes-unitarios/estoque.js");
test("Deve retornar a soma das compras com taxa de entrega", () => {
const esperado = 2530;
const retornado = somaCompras(2500, 30);
expect(retornado).toBe(esperado)
});
test("Deve retornar a diferença que restou no estoque", () => {
const esperado = 280;
const retornado = estoque(310, 30);
expect(retornado).toBe(esperado)
});
Vamos executar nosso script no terminal e fazer a leitura do nosso teste:
npm run test
É esperado que seja feito outros testes, para evitar termos que executar sempre o Jest, podemos executar o teste no modo watch
, uma opção incluida no Jest que permite manter a ferramenta funcionando em tempo integral.
Podemos atribuir a função --watchAll
no script do jest, dentro do arquivo package.json. O script ficará da seguinte forma:
"test:watch": "jest --watchAll"