DEV Community

William Moreira da Silva
William Moreira da Silva

Posted on

Elevando a Qualidade: Guia Prático de Testes em Cypress para Componentes e E2E em Aplicações React

Os testes desempenham um papel fundamental no desenvolvimento de aplicações, garantindo a estabilidade, confiabilidade e qualidade do código. Neste artigo, vamos explorar a importância dos testes de componentes e os end-to-end (E2E) usando Cypress em aplicações React.

Um pouco sobre Cypress

O Cypress é uma poderosa ferramenta de automação de testes end-to-end (E2E) projetada para facilitar o processo de teste em aplicações web. Com um foco especial na simplicidade de uso e eficácia, o Cypress ganhou popularidade entre desenvolvedores e equipes de QA devido às suas características distintivas. Seu design intuitivo e capacidades abrangentes tornam-no uma peça fundamental no processo de garantia de qualidade para aplicações web modernas.

Principais Características:

  1. Integração Simples: A instalação do Cypress é direta, e a integração com projetos existentes é fácil
  2. Testes em Tempo Real: Ao contrário de muitas ferramentas de automação, o Cypress executa testes em tempo real enquanto interage com a aplicação, fornecendo feedback instantâneo e facilitando a depuração.
  3. Comandos Simples e Intuitivos: A sintaxe dos comandos Cypress é clara e intuitiva. Operações comuns, como clicar em elementos, preencher formulários e verificar resultados, são expressas de maneira concisa.
  4. Execução em Navegadores Reais: O Cypress executa testes diretamente em navegadores reais, o que significa que os desenvolvedores podem confiar na precisão dos resultados e na consistência com a experiência do usuário real.
  5. Conceito de "Subjects" e Encadeamento de Comandos (chains of commands): O Cypress gerencia um conceito de "subject" que permite o encadeamento natural de comandos, simplificando a construção de testes complexos.
  6. Ampla Gama de Assertivas (Assertions): A capacidade de verificar o estado do DOM e dos elementos usando assertivas robustas simplifica a validação de resultados esperados.
  7. Visual Regression Testing Integrado: O Cypress pode integrar facilmente testes de regressão visual, comparando capturas de tela para identificar alterações visuais não intencionais.
  8. API Mocking e Testes de API: A capacidade de simular chamadas de API e realizar testes de integração com facilidade contribui para uma cobertura de teste mais abrangente.
  9. Timeouts Configuráveis: O Cypress gerencia timeouts automaticamente, mas oferece controle configurável para adaptar a execução dos testes conforme necessário.
  10. Comunidade Ativa e Suporte Contínuo: O Cypress possui uma comunidade ativa, com suporte constante e atualizações frequentes, garantindo que a ferramenta permaneça relevante e eficiente.

Definindo algumas bases

Segue aqui alguns pontos importantes para utilizar o cypress com maestria.

Esse e vários outros pontos podemos encontrar na própria documentação do cypress:

1. Como o Cypress consulta o DOM:

O Cypress possui comandos específicos para interagir com elementos no DOM. Veja um exemplo de como você pode usar o comando cy.get para consultar e interagir com um elemento:

// Consulta e interação com um botão usando seu seletor
cy.get('button').click();

// Consulta e interação com um input usando um atributo específico
cy.get('[data-cy=username-input]').type('nome de usuário');
Enter fullscreen mode Exit fullscreen mode

2. Como o Cypress gerencia subjects e chains of commands:

O Cypress mantém uma referência ao elemento alvo como um "subject". Cada comando retorna um novo "subject", permitindo a encadeamento de comandos. Veja um exemplo:

// Cada comando retorna um novo "subject"
cy.get('ul')
  .find('li')   // O subject agora é a lista de itens dentro da ul
  .first()      // O subject agora é o primeiro item da lista
  .click();     // Clicando no primeiro item

Enter fullscreen mode Exit fullscreen mode

3. Como as assertivas (assertions) funcionam:

As assertivas no Cypress são usadas para verificar se o estado do DOM ou de outros elementos é como esperado. Exemplo:

cy.get('.status-message').should('be.visible'); // Verifica se o elemento está visível

cy.get('input[name="username"]').should('have.value', 'nome de usuário'); // Verifica o valor do input

Enter fullscreen mode Exit fullscreen mode

4. Como os timeouts são aplicados aos comandos:

O Cypress gerencia timeouts automaticamente, mas você pode personalizá-los conforme necessário. Exemplo:

// Configuração de um timeout específico para um comando
cy.get('elemento').click({ timeout: 10000 }); // Timeout de 10 segundos para o clique
Enter fullscreen mode Exit fullscreen mode

Esses exemplos demonstram como os conceitos fundamentais do Cypress são aplicados no contexto de consultas ao DOM, manipulação de "subjects", execução de assertivas e controle de timeouts. O Cypress é uma ferramenta poderosa que oferece controle detalhado sobre interações com o DOM e facilita a criação de testes E2E robustos.

Conceitos que irão parecer por aqui

Subjects:

No contexto do Cypress, "subjects" referem-se aos elementos HTML ou objetos que são o foco de uma cadeia de comandos. Cada comando no Cypress gera um novo "subject", e os comandos subsequentes são executados em cima desse "subject". Isso cria uma forma natural de encadear comandos, simplificando a escrita de testes e a interação com o DOM. Por exemplo:

cy.get('button')   // "get" retorna um novo "subject" representando o botão
  .click()        // "click" é executado no "subject" do botão
  .should('be.visible');  // "should" é executado no "subject" após o clique

Enter fullscreen mode Exit fullscreen mode

Chains of Commands:

As "chains of commands" (cadeias de comandos) referem-se à sequência de comandos encadeados que são executados em Cypress. Cada comando gera um novo "subject" que é passado para o próximo comando na cadeia. Isso cria uma forma clara e concisa de expressar interações e verificações em testes E2E. Exemplo:

cy.get('.menu')
  .should('be.visible')
  .contains('Item de Menu')
  .click()
  .should('have.class', 'ativo');
Enter fullscreen mode Exit fullscreen mode

Assertions:

As assertivas em Cypress são usadas para verificar se o estado de um "subject" ou de um elemento DOM corresponde às expectativas definidas no teste. Elas ajudam a garantir que a aplicação está se comportando conforme o esperado. Um exemplo comum usando a assertiva should:

cy.get('.elemento').should('be.visible');
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, a assertiva verifica se o elemento com a classe ".elemento" está visível.

Visual Regression Testing Integrado:

O Visual Regression Testing é uma técnica que compara imagens ou capturas de tela da aplicação em diferentes momentos para detectar alterações visuais inesperadas. O Cypress oferece integração nativa com esse tipo de teste, permitindo comparar automaticamente capturas de tela durante a execução do teste. Isso ajuda a identificar alterações visuais que podem ocorrer inadvertidamente ao longo do desenvolvimento.

cy.visit('/pagina');
cy.matchImageSnapshot();  // Compara a página atual com uma referência anterior
Enter fullscreen mode Exit fullscreen mode

esse exemplo é bem simplório, veja a documentação do cypress para aprofundar no assunto. https://docs.cypress.io/guides/tooling/visual-testing

API Mocking:

API Mocking refere-se à capacidade de simular chamadas de API durante os testes. Isso permite isolar o frontend do backend, garantindo que os testes se concentrem apenas no comportamento do frontend. O comando cy.intercept é comumente utilizado para definir respostas simuladas para solicitações de API. Exemplo:

cy.intercept('GET', '/api/dados', { fixture: 'dados.json' }).as('getDados');
cy.visit('/dashboard');
cy.wait('@getDados').its('response.statusCode').should('eq', 200);
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, a chamada de API é interceptada e substituída por uma resposta simulada, garantindo que os testes não dependam da disponibilidade do backend real durante a execução.

Testes de Componentes em React:

Os testes de componentes em React visam verificar se os componentes individuais funcionam conforme o esperado. Isso pode incluir testes de renderização, manipulação de estados, interações do usuário e muito mais. A biblioteca de testes mais comum para React é o Jest, frequentemente combinado com React Testing Library para testes centrados no usuário.

Exemplo de teste de renderização com Jest:

import { render, screen } from '@testing-library/react';
import Component from './Component';

test('renderiza o componente corretamente', () => {
  render(<Component />);
  const elemento = screen.getByText(/texto do component/i);
  expect(elemento).toBeInTheDocument();
});

Enter fullscreen mode Exit fullscreen mode

Exemplo com Cypress

import React from "react";
import ErrorMessage from "./ErrorMessage";

function ErrorMessage({ message }) {
  return <div className="error-message">{message}</div>;
}

describe("<ErrorMessage />", () => {
  it("renders", () => {
        // instancia do componente
    cy.mount(<ErrorMessage message="Mensagem de erro" />);
        // validação se a div com a class error-message contém a mensagem "Mensagem de erro"
    cy.get(".error-message").should(`have.text`, "Mensagem de erro");

        // ... Outros possíveis testes
  });
});
Enter fullscreen mode Exit fullscreen mode

Para rodar o teste basta executar o seguinte comando:

$ yarn cypress run --component
Enter fullscreen mode Exit fullscreen mode

ou ainda via interface

$ yarn cypress open
Enter fullscreen mode Exit fullscreen mode

Testes E2E com Cypress:

Os testes E2E simulam interações do usuário em uma aplicação completa. O Cypress é uma ferramenta poderosa para isso, permitindo simular cliques, preenchimento de formulários, navegação entre páginas e mais, enquanto monitora visualmente o comportamento da aplicação.

Exemplo de teste E2E com Cypress:

describe('Teste E2E em React com Cypress', () => {
  it('Deve fazer login corretamente', () => {
    cy.visit('/login');
    cy.get('input[name="username"]').type('usuario');
    cy.get('input[name="password"]').type('senha');
    cy.get('button[type="submit"]').click();
    cy.url().should('include', '/dashboard');
// ...
// podemos continuar esse teste fazendo diversas outras assertations em /dashboard para garantir o o bom funionanmento do workflow
  });
});
Enter fullscreen mode Exit fullscreen mode

Outros exemplos de testes

Vamos explorar exemplos específicos para testes mais avançados em Cypress, abordando pontos como API Mocking, Visual Regression Testing e Testes em Diferentes Dispositivos e Resoluções.

Exemplo 1: API Mocking

Suponha que você tenha um componente React que faz uma solicitação a uma API para recuperar dados. Aqui está um exemplo de como você pode usar o Cypress para simular essa chamada de API:

// cypress/integration/apiMocking.spec.js
describe('Teste E2E com API Mocking', () => {
  it('Deve simular a resposta da API', () => {
    cy.intercept('GET', '/api/data', { fixture: 'data.json' }).as('getData');
    cy.visit('/dashboard');
    cy.wait('@getData').its('response.statusCode').should('eq', 200);
    cy.get('.data-item').should('have.length', 5);
  });
});
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, o cy.intercept é usado para interceptar a chamada de API e fornecer uma resposta simulada a partir de um arquivo de fixture.

Exemplo 2: Visual Regression Testing

O Cypress suporta visual regression testing usando a biblioteca cypress-plugin-snapshots. Aqui está um exemplo básico:

// cypress/integration/visualRegression.spec.js
describe('Teste de Regressão Visual', () => {
  it('Deve garantir a consistência visual', () => {
    cy.visit('/dashboard');
    cy.matchImageSnapshot();
  });
});
Enter fullscreen mode Exit fullscreen mode

No exemplo acima, cy.matchImageSnapshot() tira um print da página e a compara com uma referência anterior, alertando sobre qualquer diferença visual.

Exemplo 3: Testes em Diferentes Dispositivos e Resoluções

Cypress permite a simulação de diferentes dispositivos e resoluções. Veja um exemplo:

// cypress/integration/responsiveTesting.spec.js
describe('Teste de Responsividade', () => {
  it('Deve garantir layout responsivo', () => {
    cy.viewport('iphone-6');
    cy.get('.mobile-menu').should('be.visible');

    cy.viewport('macbook-15');
    cy.get('.desktop-menu').should('be.visible');
  });
});
Enter fullscreen mode Exit fullscreen mode

No exemplo acima, cy.viewport é usado para simular diferentes tamanhos de tela e garantir que os elementos responsivos estejam visíveis conforme o esperado.

Estes são exemplos básicos, e a complexidade pode aumentar com a necessidade do seu projeto. Lembre-se de ajustar conforme necessário para atender aos requisitos específicos da sua aplicação.

Benefícios de Testes Abordados

Os principais benefícios dos testes incluem Garantia de Qualidade, Detecção Precoce de Problemas e Facilidade de Manutenção. A Garantia de Qualidade é assegurada através dos testes de componentes que verificam a funcionalidade individual de partes da aplicação. A Detecção Precoce de Problemas é obtida através dos testes E2E que identificam falhas em fluxos reais de usuário, permitindo a identificação e correção de problemas antes do lançamento. Por último, a Facilidade de Manutenção é conseguida por meio de testes automatizados que diminuem a necessidade de testes manuais repetitivos, permitindo uma maior precisão e eficiência.

A Garantia de Qualidade é um dos principais benefícios de realizar testes. Especificamente, os testes de componentes ajudam a assegurar que as partes individuais da aplicação funcionem corretamente. Isso é vital porque cada componente de uma aplicação é como um tijolo na construção de uma casa - se um tijolo é fraco ou defeituoso, pode comprometer a estrutura inteira. Portanto, garantir que cada componente funcione corretamente contribui para a construção de um produto final mais robusto e de alta qualidade, o que, por sua vez, traduz-se em uma melhor experiência para o usuário.

Outro benefício importante é a Detecção Precoce de Problemas. Aqui, os testes E2E desempenham um papel crucial. E2E, ou End-to-End, refere-se a testes que verificam o fluxo de uma aplicação, desde o início até o final. Estes testes identificam falhas em fluxos de usuário reais, permitindo que os desenvolvedores detectem e corrijam problemas antes do lançamento. Isso é extremamente valioso porque, sem esses testes, problemas podem passar despercebidos até o lançamento do produto, quando são mais difíceis e custosos de corrigir. A detecção precoce de problemas, portanto, evita problemas futuros e melhora a experiência do usuário.

Por último, mas não menos importante, os testes automatizados proporcionam Facilidade de Manutenção. Eles reduzem a necessidade de testes manuais repetitivos, o que não só economiza tempo, mas também garante uma maior precisão dos testes. Isso ocorre porque os testes manuais são propensos a erros humanos, enquanto os testes automatizados realizam as mesmas operações da mesma maneira todas as vezes. Além disso, os testes automatizados podem ser executados a qualquer momento, o que significa que os desenvolvedores podem verificar a qualidade do código constantemente, tornando a manutenção do código mais eficiente.

Conclusão

Investir em testes de componentes e E2E para aplicações React é crucial para o sucesso do desenvolvimento. O uso de ferramentas como Jest para testes de componentes e Cypress para testes E2E pode melhorar significativamente a qualidade e confiabilidade das aplicações, proporcionando uma experiência consistente para os usuários finais.

Este artigo oferece apenas uma visão geral, mas a prática constante e a adaptação às necessidades específicas do projeto são essenciais para garantir a eficácia dos testes em sua aplicação React.

Referências

Visual Testing | Cypress Documentation

Introduction to Cypress | Cypress Documentation

React Component Testing | Cypress Documentation

Repositório de pesquisa | GitHub

Top comments (0)

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started