📚 Módulo 13: QA - Garantia de Qualidade com Testes E2E (Cypress) no Vue 3 e FastAPI
Neste módulo avançado de Garantia de Qualidade (QA) da TecLoja 02, implementaremos testes ponta a ponta (End-to-End - E2E) utilizando o framework Cypress.
Enquanto os testes unitários e de integração validam funções e endpoints isolados, os testes E2E simulam a experiência real do usuário interagindo diretamente com o navegador. Configuraremos a suíte do Cypress para abrir a nossa SPA Vue 3, simular o login do usuário comum, navegar pelo catálogo, manipular o carrinho reativo de compras e validar a resposta da API FastAPI.
🗺️ 1. Arquitetura do Fluxo de Testes E2E com Cypress
O diagrama abaixo ilustra o comportamento do Cypress controlando o navegador local de forma isolada e testando o fluxo integrado de frontend e backend:
flowchart TD
%% Styling
classDef cy fill:#00b48a,stroke:#005c45,stroke-width:2px,color:#fff;
classDef browser fill:#2088ff,stroke:#005cc5,stroke-width:2px,color:#fff;
classDef app fill:#41B883,stroke:#35495E,stroke-width:2px,color:#fff;
classDef backend fill:#009688,stroke:#00796B,stroke-width:2px,color:#fff;
subgraph Cypress_Runner ["⚙️ Cypress Runner Thread"]
A[Cypress Test Spec]:::cy -->|Controlar via WebDriver| B[Navegador de Teste Chrome]:::browser
end
subgraph Application_Stack ["💻 Ambiente da Aplicação"]
B -->|Acessar UI e cliques| C[Vue 3 SPA - localhost:5173]:::app
C -->|Disparar requisições HTTP| D[FastAPI API - localhost:8000]:::backend
end
⚙️ 2. Instalação e Configuração do Cypress
Acesse a pasta raiz do seu repositório frontend (tecloja-frontend) e instale o Cypress como dependência de desenvolvimento:
# Instalar o Cypress
npm install -D cypress
Após a instalação, abra a interface gráfica de configuração do Cypress pela primeira vez. Isso gerará as pastas e o arquivo de configuração básica automaticamente na raiz do seu projeto:
npx cypress open
- Na tela do Cypress, selecione a opção E2E Testing.
- Aceite os arquivos de configuração sugeridos clicando em Continue.
- Selecione seu navegador preferido (ex: Chrome) e clique em Start E2E Testing.
- Feche a janela do navegador aberta pelo Cypress para retornar ao editor de código.
Configurando o arquivo cypress.config.ts
Abra o arquivo cypress.config.ts recém-criado na raiz do projeto e configure a URL base do frontend para simplificar a escrita dos testes:
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:5173", // Porta padrão do servidor dev do Vite
viewportWidth: 1280,
viewportHeight: 720,
setupNodeEvents(on, config) {
// Configurar escutas de eventos se necessário
},
},
});
🧪 3. Escrevendo o Teste do Fluxo de Compras (compra.cy.ts)
Criaremos um cenário completo que testa o fluxo comercial principal do e-commerce.
Crie o arquivo de testes em cypress/e2e/compra.cy.ts:
describe('Fluxo de Compra E2E - TecLoja 02', () => {
beforeEach(() => {
// Limpar o localStorage de token JWT antes de cada teste
cy.clearLocalStorage();
// Visitar a página principal da loja
cy.visit('/');
});
it('Deve permitir navegar no catálogo, adicionar produto ao carrinho e falhar no checkout sem login', () => {
// 1. Validar carregamento do catálogo
cy.get('h1').should('contain', 'TecLoja 02');
cy.get('.grid-produtos').should('be.visible');
// 2. Adicionar o primeiro produto disponível ao carrinho
cy.get('.card-produto').first().within(() => {
cy.get('h2').then(($nome) => {
cy.wrap($nome.text()).as('produtoAdicionado');
});
cy.contains('Adicionar').click();
});
// 3. Validar se o contador do carrinho na Navbar foi incrementado
cy.get('.navbar-cart-badge').should('contain', '1');
// 4. Ir para a tela do carrinho
cy.get('.navbar-cart-link').click();
cy.url().should('include', '/carrinho');
// 5. Validar se o nome do produto no carrinho confere com o que foi adicionado
cy.get('@produtoAdicionado').then((nome) => {
cy.get('.carrinho-itens').should('contain', nome);
});
// 6. Tentar finalizar a compra sem estar logado
cy.contains('Finalizar Compra').click();
// 7. Esperado: Redirecionamento automático para a tela de login
cy.url().should('include', '/login');
});
it('Deve realizar login com sucesso e finalizar o pedido', () => {
// 1. Navegar diretamente para o login
cy.visit('/login');
// 2. Preencher formulário de credenciais
cy.get('input[type="email"]').type('maria@gmail.com');
cy.get('input[type="password"]').type('123456');
cy.get('button[type="submit"]').click();
// 3. Confirmar que o login foi realizado e redirecionado para a home
cy.url().should('eq', Cypress.config().baseUrl + '/');
cy.get('.usuario-perfil').should('contain', 'Maria');
// 4. Adicionar item ao carrinho
cy.get('.card-produto').first().within(() => {
cy.contains('Adicionar').click();
});
// 5. Ir para o carrinho e finalizar
cy.get('.navbar-cart-link').click();
cy.contains('Finalizar Compra').click();
// 6. Validar a exibição da mensagem de sucesso emitida pela API FastAPI
cy.get('.mensagem-sucesso').should('be.visible')
.and('contain', 'Pedido realizado com sucesso');
});
});
🚀 4. Executando os Testes E2E
Você pode rodar os testes de duas maneiras no terminal:
Modo Interativo (Interface Gráfica)
Útil durante o desenvolvimento para assistir ao Cypress digitando e clicando nas telas em tempo real:
npx cypress open
Modo Headless (Linha de Comando)
Útil para automação de CI/CD (GitHub Actions), rodando o navegador em segundo plano sem interface gráfica:
npx cypress run
✅ Pré-Requisitos deste Módulo
Antes de rodar a suíte de testes, certifique-se de que:
- A API FastAPI backend está rodando localmente (
uvicorn app.main:app --reloadna porta 8000). - O banco de dados SQLite local possui a usuária de teste
maria@gmail.comcadastrada (via seeders do Módulo 02). - O frontend Vue 3 está rodando localmente (
npm run devna porta 5173).
🤔 Por que fizemos assim?
- Por que testes E2E se já temos testes unitários no pytest? Testes unitários com mocks no backend garantem que a lógica interna do código de serviços funciona de forma isolada. Porém, eles não detectam se o desenvolvedor do frontend errou o nome do header de autorização JWT (
Authorization: Bearer <token>) ou se o CORS está bloqueando a comunicação real entre as duas portas. O teste E2E é o único capaz de certificar a integridade do ecossistema completo integrado. - Por que limpar o localStorage no
beforeEach? No desenvolvimento de testes E2E, o princípio do isolamento de estado é essencial. Se um teste anterior deixar o usuário logado no navegador, o teste subsequente de tentativa de compra sem login falhará porque a sessão continuará ativa. Garantir que cada caso de teste inicie em um navegador limpo elimina falsos-positivos na esteira de QA.
🔍 Checkpoint
- Execução de Testes E2E: Rode o comando
npx cypress runno terminal do frontend e valide se todos os casos de teste emcompra.cy.tspassam com o indicador verde de 100% de sucesso. - Geração de Vídeo: O Cypress gera automaticamente gravações em vídeo dos testes executados na pasta
cypress/videos/em modo headless. Abra a gravação e confirme o fluxo de cliques automatizado ocorrendo de forma limpa.
⚠️ Erros Comuns
| Erro | Causa | Solução |
|---|---|---|
Cypress could not connect to your server |
O servidor de desenvolvimento do frontend (localhost:5173) não está ligado ou a porta no cypress.config.ts está incorreta. |
Inicie o frontend com npm run dev antes de rodar o Cypress ou confira se a porta do Vite não foi deslocada para 5174. |
| O teste de login falha alegando que a usuária não existe no banco de dados | O banco local do backend FastAPI foi resetado ou o script data_seeder.py não foi executado. |
Rode o script de popular dados do backend para recuperar a massa padrão de testes (maria@gmail.com). |
AssertionError: Timed out retrying: Expected to find element... |
O Cypress tentou buscar um elemento na tela (ex: .card-produto ou .mensagem-sucesso) com nome de classe CSS diferente da que você codificou. |
Verifique as classes CSS em seus arquivos .vue e ajuste os seletores CSS do script de testes correspondentes. |