Por Victor Oliveira - QA Senior com mais de 13 anos de experiencia
O Cypress e uma ferramenta de automacao de testes open-source para testes de ponta a ponta (E2E), testes de componentes e testes de API. Diferente do Selenium, que executa fora do navegador, o Cypress roda dentro do mesmo processo do navegador, o que permite um controle total sobre a aplicacao. Neste tutorial, voce vai aprender como configurar um projeto do zero, desde a instalacao ate a execucao do primeiro teste.
1. O que e Cypress?
Cypress foi lancado em 2017 por Brian Mann e rapidamente se tornou uma das ferramentas mais populares para automacao de testes E2E. Sua arquitetura unica — rodando dentro do mesmo loop de eventos do navegador — elimina muitos problemas classicos de automacao, como races conditions e flaky tests.
Principais vantagens:
- Arquitetura no mesmo processo — acesso direto ao DOM, localStorage, sessionStorage e rede
- Time Travel — veja screenshots de cada passo do teste ao passar o mouse no Command Log
- Auto-wait inteligente — nunca use
sleep()ouwait()manuais - Debugging excepcional — erros com stack traces legiveis e screenshots automaticas
- Interceptacao de rede — stub e mock de requisicoes HTTP sem ferramentas externas
- Real-time reload — alterou o teste? O Cypress recarrega automaticamente
- Screenshots e videos — gravacao automatica em execucao headless
- Dashboard service — gravacao de resultados, analise de flaky, paralelizacao
2. Pre-requisitos
Antes de comecar, voce precisa ter instalado:
- Node.js 18+ — nodejs.org
- npm — ja vem com Node.js
- Git (opcional, mas recomendado) — para versionamento
- VS Code (ou qualquer editor de sua preferencia)
Verifique se o Node.js esta instalado corretamente:
node --version
npm --version
3. Instalacao do Cypress
Crie uma pasta para o projeto e instale o Cypress:
mkdir meu-projeto-cypress
cd meu-projeto-cypress
npm init -y
npm install cypress --save-dev
Apos a instalacao, abra o Cypress pela primeira vez:
npx cypress open
Na primeira execucao, o Cypress cria automaticamente a estrutura de pastas recomendada e arquivos de exemplo. Voce vera uma interface grafica com os testes de exemplo prontos para executar.
Verifique a instalacao:
npx cypress --version
4. Estrutura de Diretorios
Apos abrir o Cypress, a estrutura gerada e:
meu-projeto-cypress/
├── cypress/
│ ├── e2e/
│ │ ├── exemplo.cy.js
│ │ └── login.cy.js
│ ├── fixtures/
│ │ └── example.json
│ ├── support/
│ │ ├── commands.js
│ │ └── e2e.js
│ └── downloads/
├── cypress.config.js
├── package.json
└── node_modules/
- cypress/e2e/ — arquivos de teste com extensao .cy.js
- cypress/fixtures/ — dados estaticos para mock (JSON, imagens, etc.)
- cypress/support/commands.js — custom commands reutilizaveis
- cypress/support/e2e.js — configuracao global executada antes de cada teste
- cypress.config.js — configuracao central do Cypress
5. Criando o Primeiro Teste
Crie o arquivo cypress/e2e/primeiro_teste.cy.js:
describe('Meu primeiro teste', () => {
it('deve acessar o Google e verificar o titulo', () => {
cy.visit('https://google.com');
cy.title().should('eq', 'Google');
});
});
Vamos entender cada parte:
- describe() — agrupa testes relacionados (suite)
- it() — define um caso de teste individual
- cy.visit() — navega para uma URL
- cy.title() — obtem o titulo da pagina
- .should() — assertiva do Cypress (BDD-style, encadeavel)
5.1. Teste com interacao
Vamos criar um teste mais completo que interage com elementos na pagina:
describe('Login', () => {
it('deve fazer login com sucesso', () => {
cy.visit('https://example.com/login');
cy.get('#username').type('admin');
cy.get('#password').type('senha123');
cy.get('button[type="submit"]').click();
cy.get('.welcome-message').should('have.text', 'Bem-vindo, admin!');
});
});
6. Localizadores e Interacoes
O Cypress usa seletores CSS para localizar elementos. Recomenda-se usar atributos data-cy ou data-testid para maior resiliencia:
cy.get('[data-cy="submit-button"]').click();
cy.get('[data-testid="user-email"]').should('be.visible');
cy.contains('Bem-vindo').click();
cy.get('button').contains('Enviar').click();
cy.get('.form').find('input').first().type('texto');
6.1. Interacoes principais
cy.get('.botao').click();
cy.get('.botao').dblclick();
cy.get('input').type('texto', { delay: 100 });
cy.get('input').clear();
cy.get('select').select('opcao-1');
cy.get('input[type="checkbox"]').check();
cy.get('.dropdown').trigger('mouseover');
cy.get('.footer').scrollIntoView();
cy.get('input[type="file"]').selectFile('caminho/arquivo.pdf');
7. Assertivas (Assertions)
O Cypress usa chai como biblioteca de assertivas, com sintaxe encadeavel e auto-retry:
cy.get('.mensagem').should('be.visible');
cy.get('.spinner').should('not.be.visible');
cy.get('input').should('be.disabled');
cy.get('.checkbox').should('be.checked');
cy.get('.titulo').should('have.text', 'Bem-vindo');
cy.get('.titulo').should('contain', 'Bem');
cy.get('input').should('have.value', 'admin');
cy.get('.erro').should('have.css', 'color', 'rgb(255, 0, 0)');
cy.get('.item').should('have.length', 5);
cy.url().should('include', '/dashboard');
cy.get('.erro').should('not.exist');
cy.get('.card')
.should('be.visible')
.and('have.class', 'active')
.and('contain', 'Bem-vindo');
8. Testando APIs com cy.request e cy.intercept
8.1. Testando APIs diretamente
describe('API Testing', () => {
it('deve listar usuarios', () => {
cy.request('GET', 'https://api.example.com/users')
.then((response) => {
expect(response.status).to.eq(200);
expect(response.body).to.have.length(10);
});
});
it('deve criar um novo usuario', () => {
cy.request({
method: 'POST',
url: 'https://api.example.com/users',
body: { name: 'Victor', email: 'victor@email.com' }
}).then((response) => {
expect(response.status).to.eq(201);
expect(response.body).to.have.property('id');
});
});
});
8.2. Interceptacao de rede
describe('Interceptacao', () => {
it('deve mostrar dados mockados', () => {
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [{ id: 1, name: 'Usuario Mock' }]
}).as('getUsers');
cy.visit('/usuarios');
cy.wait('@getUsers');
cy.get('.usuario').should('have.length', 1);
});
it('deve testar erro de rede', () => {
cy.intercept('GET', '/api/users', {
statusCode: 500,
body: { error: 'Erro interno' }
}).as('getUsersError');
cy.visit('/usuarios');
cy.wait('@getUsersError');
cy.get('.erro-api').should('be.visible');
});
});
9. Custom Commands
Custom commands permitem reutilizar acoes comuns em todos os testes. Defina em cypress/support/commands.js:
Cypress.Commands.add('login', (email, senha) => {
cy.visit('/login');
cy.get('[data-cy="email"]').type(email);
cy.get('[data-cy="senha"]').type(senha);
cy.get('[data-cy="submit"]').click();
cy.url().should('include', '/dashboard');
});
Cypress.Commands.add('criarUsuario', (dados) => {
cy.request({
method: 'POST',
url: '/api/users',
body: dados
}).then((response) => {
expect(response.status).to.eq(201);
cy.wrap(response.body).as('novoUsuario');
});
});
E nos testes, use os custom commands diretamente:
describe('Com custom commands', () => {
it('deve fazer login', () => {
cy.login('victor@email.com', 'senha123');
cy.get('.boas-vindas').should('contain', 'Victor');
});
});
10. Executando os Testes
10.1. Modo Interativo
npx cypress open
Abre o Cypress Test Runner com interface grafica: selecione testes, veja o Command Log com Time Travel, debug cada passo.
10.2. Modo Headless
npx cypress run
npx cypress run --browser chrome
npx cypress run --browser firefox
npx cypress run --spec "cypress/e2e/login.cy.js"
npx cypress run --record --key SUA_CHAVE
10.3. Configuracao (cypress.config.js)
const { defineConfig } = require('cypress');
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
viewportWidth: 1280,
viewportHeight: 720,
defaultCommandTimeout: 10000,
screenshotOnRunFailure: true,
video: true,
retries: {
runMode: 1,
openMode: 0
},
},
});
11. CI/CD com GitHub Actions
# .github/workflows/cypress.yml
name: Cypress Tests
on: [push]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npx cypress run --browser chrome
- uses: actions/upload-artifact@v4
if: failure()
with:
name: cypress-screenshots
path: cypress/screenshots/
- uses: actions/upload-artifact@v4
if: always()
with:
name: cypress-videos
path: cypress/videos/
12. Dicas e Boas Praticas
- Use data-cy em vez de classes CSS — seletores mais resilientes
- Evite cy.wait() com tempos fixos — confie no auto-wait e use
cy.intercept() - Use fixtures para dados de teste — mantenha dados mockados separados
- Custom commands para acoes repetitivas — login, criacao de dados
- Limpe o estado antes de cada teste — use
beforeEach()via API - Nao use cy.wait() para rede — prefira
cy.intercept()+cy.wait('@alias') - Teste fluxos criticos — foque no que realmente importa para o negocio
- Mantenha testes independentes — cada teste deve rodar sozinho em qualquer ordem
beforeEach(() => {
cy.request('POST', '/api/test/reset');
cy.fixture('usuario').as('userData');
});
describe('Fluxo de compra', () => {
it('deve completar uma compra', function () {
cy.login(this.userData.email, this.userData.senha);
cy.intercept('POST', '/api/checkout').as('checkout');
cy.get('[data-cy="produto-1"]').click();
cy.get('[data-cy="finalizar-compra"]').click();
cy.wait('@checkout').its('response.statusCode').should('eq', 200);
cy.get('[data-cy="confirmacao"]').should('be.visible');
});
});
13. Cypress vs Playwright vs Selenium
- Cypress — melhor debug com Time Travel, ideal para apps React/Angular/Vue, limitado a Chromium/Firefox/Edge
- Playwright — suporte nativo a Chromium + Firefox + WebKit, auto-wait, melhor para cross-browser
- Selenium — suporte a todos os navegadores, mais lento, maior ecossistema legado
14. Proximos Passos
Agora que voce ja sabe iniciar um projeto com Cypress, explore:
- Cypress Component Testing — teste componentes React/Vue/Angular
- Cypress Dashboard — gravacao de resultados e analise de flaky
- Visual Regression — cypress-image-snapshot
- Cucumber + Cypress — BDD com Gherkin
- Cypress com Docker — ambientes isolados para CI
Continue acompanhando o QA Overflow para mais tutoriais praticos sobre automacao de testes!