Como testar APIs REST do Express.js usando o Cypress
Cypress é uma estrutura de teste popular adaptada para aplicações JavaScript. Embora tenha sido projetado principalmente para testar componentes da interface do usuário e interações com elementos da interface do usuário em um navegador, ele também é adequado para testar APIs. Pode utilizar a estrutura para testar APIs RESTful através de pedidos HTTP e validar as respostas.
O Cypress permite a criação de extensos conjuntos de testes que abrangem toda a gama operacional de uma aplicação Web, desde o início até à conclusão.
Introdução ao teste de APIs usando o Cypress
O Cypress permite a validação da interface de programação (API) de uma aplicação para garantir que ela funcione de acordo com o projeto pretendido. Como parte deste processo, os pontos de extremidade da API, os parâmetros de entrada e as respostas do protocolo de transferência de hipertexto (HTTP) são testados. Além disso, a compatibilidade com quaisquer sistemas externos é verificada e a funcionalidade dos mecanismos de tratamento de erros é confirmada.
É fundamental garantir a funcionalidade, fiabilidade e adequação para a integração de aplicações das suas APIs através de testes. A identificação precoce e a retificação de quaisquer problemas evitarão que surjam potenciais problemas num ambiente real.
Cypress é uma óptima ferramenta de teste da interface do utilizador, utilizada por algumas das estruturas JavaScript mais populares. A sua capacidade de efetuar e testar pedidos HTTP torna-a igualmente eficaz no teste de APIs.
A aplicação utiliza o Node.js como tecnologia subjacente para executar pedidos HTTP e gerir eficazmente as respostas correspondentes.
O código-fonte deste projeto está acessível através do seu repositório GitHub dedicado.
Criar uma API REST Express.js
Para iniciar o processo, estabeleça um servidor Web Express como base e incorpore este pacote na estrutura do seu projeto.
npm install cors
Para incorporar a funcionalidade do Cypress ao seu projeto atual, você precisará seguir uma série de etapas que envolvem a instalação e a configuração das dependências necessárias. Este processo envolve a adição do pacote Cypress como um ativo no ficheiro de configuração ou repositório do seu projeto, especificando a sua versão e localização no seu sistema, e assegurando que está corretamente integrado com outros componentes e módulos na sua aplicação. Uma vez feito isto, pode começar a utilizar o Cypress para automatizar e testar vários aspectos do seu fluxo de trabalho de desenvolvimento de software, incluindo interacções do utilizador, chamadas API e pedidos de rede.
npm install cypress --save-dev
Por fim, modifique seu arquivo package.json
para incorporar o script de teste mencionado acima.
"test": "npx cypress open"
Definir os controladores de API
Para demonstrar a funcionalidade de nosso aplicativo em um cenário prático, vamos simular o processo de fazer chamadas de API para interagir com um banco de dados ou uma API externa. Embora a implementação real envolva tais interacções, por uma questão de clareza, utilizaremos uma matriz para armazenar e recuperar dados do utilizador no âmbito deste exemplo.
No diretório principal da estrutura de pastas do seu projeto, crie um subdiretório “controllers” e, dentro dele, gere um ficheiro “userControllers.js”. Neste ficheiro, incorpore o conteúdo seguinte.
Comecemos, de facto, por criar uma função
const users = [];
exports.registerUser = async (req, res) => {
const { username, password } = req.body;
try {
const newUser = { username, password };
users.push(newUser);
res.status(201).send({ message: 'User registered successfully' });
} catch (error) {
console.error(error);
res.status(500).send({ message: 'An error occurred!!' });
}
};
Modifique a função existente getAllUsers
para incluir uma funcionalidade adicional que recupera os dados do utilizador da matriz e os devolve sob a forma de uma resposta JSON. Esta nova função é designada por getUsers
.
exports.getUsers = async (req, res) => {
try {
res.json(users);
} catch (error) {
console.error(error);
res.status(500).send({ message: 'An error occurred!!' });
}
};
Em conclusão, é possível efetuar tentativas de início de sessão simuladas incorporando uma parte específica de código no script fornecido. Esta funcionalidade adicional permite validar se um determinado conjunto de credenciais corresponde corretamente às informações armazenadas num conjunto de “utilizadores”.
exports.loginUser = async (req, res) => {
const { username, password } = req.body;
try {
const user = users.find((u) =>
u.username === username && u.password === password);
if (user) {
res.status(200).send({ message: 'Login successful' });
} else {
res.status(401).send({ message: 'Invalid credentials' });
}
} catch (error) {
console.error(error);
res.status(500).send({ message: 'An error occurred!!' });
}
};
Definir as rotas da API
Para estabelecer a configuração de rotas para a sua aplicação RESTful baseada em Express, deve gerar um novo ficheiro chamado “routes/userRoutes.js” situado no diretório principal do seu projeto. Esse arquivo específico conterá o seguinte conteúdo:
const express = require('express');
const router = express.Router();
const userControllers = require('../controllers/userControllers');
const baseURL = '/v1/api/';
router.post(baseURL \\+ 'register', userControllers.registerUser);
router.get(baseURL \\+ 'users', userControllers.getUsers);
router.post(baseURL \\+ 'login', userControllers.loginUser);
module.exports = router;
Atualizar o arquivo Server.js
Modifique o conteúdo do arquivo server.js
ajustando sua configuração de acordo com as seguintes especificações:
const express = require('express');
const cors = require('cors');
const app = express();
const port = 5000;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
const userRoutes = require('./routes/userRoutes');
app.use('/', userRoutes);
app.listen(port, () => {
console.log(`Server is listening at http://localhost:${port}`);
});
module.exports = app;
Configurar o ambiente de teste
Para estabelecer o ambiente de teste para a interface de programação de aplicações (API) de demonstração, inicie a inicialização do servidor de desenvolvimento executando a instrução de terminal acima mencionada.
node server.js
Em seguida, execute o script de teste utilizando o executável “test” a partir de outra janela de terminal ou consola:
npm run test
A execução desta instrução dará início à implementação da aplicação de ambiente de trabalho Cypress, que serve de plataforma de avaliação. Após a sua instalação bem sucedida, navegue até ao separador “E2E Testing” e active-o clicando no botão designado. As avaliações de ponta a ponta englobam uma avaliação abrangente de toda a API Express, incluindo o servidor Web, as configurações de rota e os módulos de função do controlador associados.
Continue clicando em “Continue” para incorporar os ficheiros de configuração Cypress.
Após a conclusão bem sucedida do procedimento de configuração inicial, os utilizadores devem observar a presença de um diretório Cypress recentemente criado no seu projeto. Além disso, o Cypress gera automaticamente um ficheiro cypress.config.js que engloba os parâmetros de configuração do conjunto de testes.
Sinta-se à vontade para modificar este documento incorporando o endereço base do seu servidor da seguinte forma:
const { defineConfig } = require("cypress");
module.exports = defineConfig({
chromeWebSecurity: false,
e2e: {
baseUrl: 'http://localhost:5000',
setupNodeEvents(on, config) {
},
},
});
Escrever os Casos de Teste
Para começar a escrever os casos de teste usando o Cypress, comece escolhendo o navegador da Web desejado para teste dentre as opções disponíveis na interface do Cypress.
Ao clicar no botão “Criar nova especificação”, forneça um título para o seu caso de teste, clicando em seguida na opção “Criar especificação”.
Por favor, edite o conteúdo do ficheiro “cypress/fixtures/example.json” incorporando as credenciais de utilizador fornecidas. Os ficheiros de dispositivos servem como repositórios para dados de teste estacionários que podem ser utilizados em conjuntos de testes.
{
"username": "testuser",
"password": "password123"
}
O Cypress oferece uma abordagem versátil para a execução de pedidos HTTP através do seu comando cy.request
incorporado. Esse recurso permite que os desenvolvedores interajam com vários tipos de pontos de extremidade HTTP que lidam com diversas funcionalidades, como GET, POST, PUT e DELETE.
Para validar a funcionalidade dos três pontos finais da API implementados anteriormente, temos de começar por formular um cenário de teste para o processo de registo. O principal objetivo deste cenário de teste será confirmar que o endpoint funciona como pretendido, criando efetivamente uma nova conta de utilizador e verificando as asserções associadas.
Abra o ficheiro “cypress/e2e/user.routes.spec.cy.js” e substitua o seu conteúdo existente pelo trecho de código fornecido abaixo:javascriptdescribe(‘User Routes’, () => {it(‘should have a proper navigation bar on mobile devices’, (done) => {cy.visit(’/’)cy. get(’#app-title’).should(‘have.text’, ‘My Website’);cy.get(’.burger’).click();cy.get(’#menu-toggle’).should(‘be.visible’);cy.get(’#profile-btn’).click({ force: true });cy.url().should(‘include’, ‘/dashboard’);cy.get(’#nav-links li:nth-child(1) a’).
describe('User Routes', () => {
it('registers a new user', () => {
cy.fixture('example').then((testUser) => {
cy.request({
method: 'POST',
url: `${baseUrl}/v1/api/register`,
body: testUser,
}).then((response) => {
expect(response.status).to.eq(201);
expect(response.body.message).to.eq('User registered successfully');
});
});
});
Durante a execução desta avaliação, a Cypress utilizará as informações fornecidas no ficheiro de instalação para gerar uma série de pedidos POST dirigidos ao ponto final designado, acompanhados dos pormenores contidos no corpo do pedido. Se cada uma das afirmações for validada como exacta, a instância de teste será considerada bem sucedida e considerada aprovada. Por outro lado, se alguma asserção não cumprir os critérios estabelecidos, o caso de teste global será considerado sem êxito e marcado como falhado.
Os testes Cypress são estruturados utilizando uma sintaxe semelhante à utilizada pelos testes Mocha, uma vez que a Cypress integrou esta estrutura de testes.
Para validar que a resposta gerada pelo ponto de extremidade users
fornece informações pertinentes sobre o utilizador ao receber um pedido nesse local, é imperativo incorporar as seguintes medidas no conjunto de testes describe
abrangente.
it('gets users data and the username matches test data', () => {
cy.fixture('example').then((expectedUserData) => {
cy.request({
method: 'GET',
url: `${baseUrl}/v1/api/users`,
}).then((response) => {
expect(response.status).to.eq(200);
const username = response.body[0].username;
expect(username).to.eq(expectedUserData.username);
});
});
});
Por fim, incorpore um cenário de teste para avaliar o ponto de extremidade de início de sessão e assegure que o estado da resposta HTTP é 200, o que significa uma tentativa de início de sessão bem sucedida.
it('logs in a user', () => {
cy.fixture('example').then((loginData) => {
cy.request({
method: 'POST',
url: `${baseUrl}/v1/api/login`,
body: loginData,
}).then((response) => {
expect(response.status).to.eq(200);
});
});
});
});
Para executar os testes, navegue de volta para o aplicativo da Web que está sendo monitorado pelo Cypress e escolha o script de teste específico que você deseja executar dentre os disponíveis.
A execução do Cypress test runner deve resultar no teste e na documentação dos resultados de cada caso de teste individual, indicando se foram aprovados ou reprovados.
Para avaliar de forma abrangente o desempenho e a fiabilidade de uma API, é crucial alargar o âmbito dos testes para além da simples análise dos seus aspectos funcionais. Ao explorar camadas adicionais de interação entre a interface de programação de aplicações e outros componentes envolvidos no processamento de pedidos ou respostas, é possível obter uma avaliação mais abrangente da eficiência e eficácia globais do sistema.
Uma abordagem completa ao teste da API engloba não só a funcionalidade, mas também aspectos como o desempenho, a escalabilidade e a integração com sistemas externos. Para tal, a incorporação de uma gama diversificada de metodologias de teste na sua estratégia de teste é essencial para obter uma cobertura de teste exaustiva e garantir a fiabilidade e estabilidade das APIs da sua aplicação antes da sua implementação num ambiente real.
Testar toda a sua experiência na Web utilizando o Cypress
O Cypress é um recurso excecional para avaliar facilmente as aplicações baseadas na Web, abrangendo avaliações exaustivas tanto da interface do utilizador como dos componentes do lado do servidor.
A utilização das nossas ferramentas de teste intuitivas permite a criação sem esforço de um ambiente de teste abrangente numa única plataforma. Isto permite uma avaliação extensiva de várias facetas do seu software, garantindo uma funcionalidade óptima e um desempenho excecional.