08 Dez 2022
12 min

Testes Automatizados para Front-end

Testes
Jest
Testing Library
Testes Automatizados para Front-end
Lucas Medeiros
Lucas Medeiros
Desenvolvedor Front-end Sênior

Testes automatizados são essenciais para garantir a qualidade e a confiabilidade de aplicações front-end. Neste artigo, vamos explorar estratégias para implementar diferentes tipos de testes.

Testes Unitários com Jest e Testing Library

Testes unitários verificam o comportamento de unidades individuais de código:


      import { render, screen, fireEvent } from '@testing-library/react';
      import Counter from './Counter';
      
      test('incrementa o contador quando o botão é clicado', () => {
        render(<Counter />);
        
        const button = screen.getByRole('button', { name: /incrementar/i });
        // const counter = screen.getByText(/contador: 0/i); // This line might be problematic if text changes
        
        fireEvent.click(button);
        
        expect(screen.getByText(/contador: 1/i)).toBeInTheDocument();
      });
      

Testes de Integração

Testes de integração verificam como diferentes partes da aplicação funcionam juntas:


      import { render, screen, fireEvent, waitFor } from '@testing-library/react';
      import UserProfile from './UserProfile';
      import { fetchUserData } from './api'; // Assuming api.js exists
      
      jest.mock('./api');
      
      test('exibe os dados do usuário após o carregamento', async () => {
        fetchUserData.mockResolvedValue({ name: 'John Doe', email: 'john@example.com' });
        
        render(<UserProfile userId="123" />);
        
        expect(screen.getByText(/carregando.../i)).toBeInTheDocument();
        
        await waitFor(() => {
          expect(screen.getByText(/john doe/i)).toBeInTheDocument();
          expect(screen.getByText(/john@example.com/i)).toBeInTheDocument();
        });
        
        expect(fetchUserData).toHaveBeenCalledWith('123');
      });
      

Testes End-to-End com Cypress

Testes end-to-end simulam o comportamento do usuário em um ambiente real:


      describe('Formulário de Login', () => {
        it('permite que um usuário faça login', () => {
          cy.visit('/login');
          
          cy.get('input[name="email"]').type('user@example.com');
          cy.get('input[name="password"]').type('password123');
          cy.get('button[type="submit"]').click();
          
          cy.url().should('include', '/dashboard');
          cy.contains('Bem-vindo, Usuário!').should('be.visible');
        });
        
        it('exibe uma mensagem de erro para credenciais inválidas', () => {
          cy.visit('/login');
          
          cy.get('input[name="email"]').type('user@example.com');
          cy.get('input[name="password"]').type('senha_errada');
          cy.get('button[type="submit"]').click();
          
          cy.contains('Email ou senha inválidos').should('be.visible');
          cy.url().should('include', '/login');
        });
      });
      

Estratégias de Teste

Algumas estratégias para implementar testes de forma eficiente:

  • Pirâmide de Testes: Mais testes unitários, menos testes de integração, ainda menos testes end-to-end.
  • Testes Baseados em Comportamento: Teste o comportamento, não a implementação.
  • Mocks e Stubs: Use mocks para isolar o código que está sendo testado.
  • Continuous Integration: Execute os testes automaticamente em cada commit.

Conclusão

Implementar uma estratégia de testes abrangente ajuda a identificar problemas cedo, facilita refatorações e aumenta a confiança no código.