End-to-End Testing

Cypress

O Cypress executa testes dentro do navegador com um runner interativo, retentativas automáticas e um depurador de 'viagem no tempo' que torna os testes end-to-end excepcionalmente acessíveis.

intermediate13 min readUpdated 15 de set. de 2026
login.cy.js
js
// cypress/e2e/login.cy.js
describe("login", () => {
  it("signs the user in", () => {
    cy.visit("/login");

    cy.get('[data-cy="email"]').type("[email protected]");
    cy.get('[data-cy="password"]').type("secret");
    cy.get('[data-cy="submit"]').click();

    cy.contains("h1", "Dashboard").should("be.visible");
  });
});
Executa em
O navegador
Retentativas
Automáticas
Depuração
Time-travel runner
Rede
cy.intercept
Linguagem
JavaScript ou TypeScript
Navegadores
Chrome, Firefox, Edge, WebKit

Por que importa

Por que desenvolvedores gostam do Cypress

Runner interativo

Acompanhe a execução dos comandos no app em tempo real, inspecione o DOM em cada etapa e volte no tempo para qualquer ponto do teste.

Retentativas automáticas

Comandos e asserções são repetidos até passarem ou expirarem o tempo limite, eliminando a maioria das esperas manuais.

Stubbing de rede

Intercepte e simule requisições com cy.intercept para testar estados de erro e casos extremos de forma determinística.

O panorama completo

As três ideias por trás do Cypress

Os testes rodam dentro do navegador, os comandos são enfileirados automaticamente e as asserções são repetidas até passarem.

Comandos

Agir

Uma API encadeável para visitar páginas, consultar elementos e interagir com eles.

Asserções

Verificar

Asserções should e expect que repetem a verificação contra o DOM em tempo real.

O runner

Executar

Um processo Node controla o navegador e serve o runner de testes interativo.

Cypress em resumo

O núcleo do Cypress

cy.visit

Abre uma página e inicia um teste.

cy.get e cy.contains

Consulta elementos por seletor, texto ou helpers no estilo testing-library.

should

Asserções que repetem a verificação até que a condição seja verdadeira.

Interações

type, click, select, trigger e mais, todos enfileirados e com retentativas.

cy.intercept

Faz stub, espiona e modifica requisições e respostas de rede.

Comandos personalizados

Encapsula fluxos repetitivos em comandos reutilizáveis.

Uma breve historia

De uma ferramenta de dev a uma plataforma de testes

  1. 2015

    Lançamento do Cypress

    Uma ferramenta de testes baseada em navegador com um runner interativo é introduzida.

    15
  2. 2018

    Cypress 3 e open source

    Adoção mais ampla e um ecossistema de plugins crescente seguem o lançamento em código aberto.

    18
  3. 2020

    cy.intercept

    Uma nova API de rede substitui o cy.route e melhora o stubbing e spying.

    20
  4. 2022

    Cypress 10 e 12

    Um novo formato de configuração e melhorias em testes de componentes são lançados.

    22
  5. Hoje

    Uma escolha popular de e2e

    Amado por sua experiência de desenvolvedor, com testes de componentes e relatórios em nuvem.

    Hoje

O guia completo

Cypress: Tudo que voce precisa saber

O que é Cypress?

Cypress é uma ferramenta de testes end-to-end que roda dentro do navegador junto com a sua aplicação. Essa escolha arquitetural proporciona uma experiência de desenvolvedor excepcionalmente boa: um runner interativo onde você acompanha a execução dos comandos, a capacidade de inspecionar o DOM em cada etapa e um debugger de “viagem no tempo” que reproduz cada ação.

É uma das ferramentas de teste de navegador mais populares e é especialmente querida por ser acessível. Os comandos são enfileirados automaticamente, as assertions tentam novamente até passarem e o runner deixa claro o que aconteceu quando um teste falha.

Escrevendo um teste

Os testes do Cypress utilizam uma API de comandos encadeáveis e uma estrutura describe/it.

// cypress/e2e/todos.cy.js
describe("todos", () => {
  beforeEach(() => {
    cy.visit("/todos");
  });

  it("adds a todo", () => {
    cy.get('[data-cy="new-todo"]').type("Write tests");
    cy.get('[data-cy="add"]').click();

    cy.get('[data-cy="todo"]').should("have.length", 1);
    cy.contains("Write tests").should("be.visible");
  });
});

Os comandos do Cypress são enfileirados e executados em ordem, embora retornem imediatamente. É por isso que você encadeia .then ou utiliza aliases em vez de atribuir o resultado de um comando a uma variável.

Comandos e asserções

Os comandos principais abrangem navegação, consultas e interação:

  • cy.visit(url) abre uma página.
  • cy.get(selector) realiza consultas via seletor CSS.
  • cy.contains(text) encontra um elemento pelo seu texto.
  • .type(), .click(), .select(), .check() interagem com elementos.
  • .should() realiza asserções e tentativas de repetição (retries).
// assertions.cy.js
cy.get("form").should("be.visible");
cy.get('[data-cy="count"]').should("have.text", "3");
cy.get("button").should("be.disabled");
cy.get('[data-cy="row"]').should("have.length", 5);

Como o .should() tenta novamente até passar ou atingir o tempo limite (timeout), raramente você precisará aguardar explicitamente. Esta é a mesma abordagem baseada em retries que torna os testes do Playwright resilientes, aplicada a uma API encadeada.

Stubbing de rede com cy.intercept

cy.intercept é a maneira de tornar seus testes determinísticos. Ele pode fazer o stub de respostas, espionar o tráfego real, modificar requisições e controlar o timing.

// intercept.cy.js
cy.intercept("GET", "/api/users", {
  statusCode: 500,
  body: { message: "Server error" },
}).as("users");

cy.visit("/users");
cy.wait("@users");

cy.contains("Something went wrong").should("be.visible");

Usar um alias com cy.wait("@users") permite que você faça asserções na requisição e aguarde a resposta sem precisar adivinhar o tempo de execução. Fazer o stub de estados de erro dessa forma é muito mais confiável do que tentar provocá-los a partir de um backend real.

Comandos personalizados e fixtures

Fluxos repetitivos devem ser movidos para um comando personalizado, o que mantém os testes legíveis.

// cypress/support/commands.js
Cypress.Commands.add("login", (email, password) => {
  cy.visit("/login");
  cy.get('[data-cy="email"]').type(email);
  cy.get('[data-cy="password"]').type(password);
  cy.get('[data-cy="submit"]').click();
});
// usage
cy.login("[email protected]", "secret");

Fixtures carregam dados estáticos de cypress/fixtures, e cy.fixture("users.json").then(...) fornece entradas previsíveis para os testes. Combinadas com cy.intercept, as fixtures são a maneira padrão de testar sem um backend ativo.

Selecionando elementos

O Cypress trabalha com seletores CSS, então a tentação de vincular os testes à estilização é real. Evite isso. Prefira, nesta ordem:

  1. Consultas acessíveis via @testing-library/cypress (findByRole, findByLabelText).
  2. cy.contains para texto visível.
  3. Um atributo data-cy dedicado quando não houver uma identidade visível para o usuário.

Um atributo data-cy é explícito e estável, portanto os testes sobrevivem a redesigns. Seletores baseados em classes não sobrevivem.

Onde o Cypress se encaixa

O Cypress é a camada de end-to-end. Mantenha a pirâmide equilibrada: testes unitários rápidos com Vitest ou Jest, testes de componentes com Testing Library e um conjunto focado de jornadas end-to-end no Cypress ou Playwright. Empurre os casos de borda (edge cases) para as camadas mais baratas e reserve o e2e para os fluxos que obrigatoriamente devem funcionar de ponta a ponta.

Melhores práticas

  • Faça o stub da rede com cy.intercept para garantir testes determinísticos.
  • Use data-cy ou queries acessíveis em vez de seletores de estilo.
  • Mantenha os testes independentes para que possam ser executados em paralelo.
  • Encapsule fluxos repetitivos em comandos customizados.
  • Faça o login através de um comando customizado ou chamada de API, em vez de usar a UI todas as vezes.
  • Faça asserções em resultados visíveis para o usuário, não no estado interno.
  • Execute em modo headless no CI e mantenha o runner interativo para depuração local.

Erros comuns

  • Aguardar com cy.wait(milliseconds) em vez de usar um alias de rede ou uma asserção.
  • Acoplar seletores a classes CSS e à estrutura do HTML.
  • Compartilhar estado entre testes, causando falhas dependentes da ordem de execução.
  • Tentar armazenar resultados de comandos em variáveis sem usar .then ou aliases.
  • Testar tudo end-to-end em vez de testar na camada correta.
  • Fazer login pela UI antes de cada teste, tornando a suíte de testes mais lenta.

Próximos passos

O Cypress é uma forma amigável e poderosa de testar jornadas reais de usuários. Compare-o com o Playwright para ter uma alternativa cross-browser, e construa as camadas inferiores com Vitest e Testing Library. Em seguida, adicione um comando de login personalizado e um fluxo crítico, e expanda sua suíte de testes a partir daí.

Lidando com a rede

Faça stub da requisição para que o teste seja determinístico e rápido. Esperar por um backend real torna os testes lentos e instáveis (flaky).

Preferir
cy.intercept("GET", "/api/users", {
  statusCode: 500,
  body: { message: "Server error" },
}).as("users");

cy.visit("/users");
cy.wait("@users");
cy.contains("Something went wrong");
Evitar
cy.visit("/users");
cy.wait(3000);
cy.contains("Something went wrong");

Selecionando elementos

Um atributo de teste dedicado é estável mesmo com mudanças de estilo e estrutura.

Preferir
cy.get('[data-cy="submit"]').click();
Evitar
cy.get(".btn.btn-primary > span")
  .click();

Perguntas frequentes

Perguntas frequentes

Keep learning

Related topics from the roadmap.

$ comecar a aprender

Pronto para aprender Cypress?

Nosso tutorial interativo te guia por Cypress passo a passo — com quizzes e codigo real que voce pode executar no navegador.