Testes E2E em Rust: Guia completo para projetos reais

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que testes E2E em Rust não são um luxo, mas uma necessidade

\n\n

Você já iniciou uma aplicação Rust em produção e, uma hora depois, recebeu pânico dos usuários? "Tudo funciona perfeitamente na minha máquina!" — frase familiar? O problema é que os testes unitários verificam apenas partes isoladas do código, e os testes de integração verificam a interação entre componentes. Mas o verdadeiro inferno começa quando todo o pipeline, desde a requisição HTTP até o banco de dados, falha devido a uma combinação não óbvia.

\n\n

Testes E2E de aplicações Rust (End-to-End) são a única maneira de garantir que sua API, utilitário CLI ou serviço web funcionem como um todo coeso. Neste artigo, não vamos apenas falar sobre teoria, mas escrever testes reais que podem ser imediatamente implementados em CI/CD. Sem enrolação — apenas Rust e uma abordagem pronta para produção.

\n\n

O que são testes E2E no contexto do Rust?

\n\n

Ao contrário dos testes unitários (que testam funções) e dos testes de integração (que testam módulos), os testes end-to-end Rust verificam o ciclo completo de funcionamento da aplicação: da entrada à saída. Para um serviço web, isso se parece com:

\n\n
    \n
  • Iniciar um servidor real (ou sua imagem Docker).
  • \n
  • Enviar uma requisição HTTP através de um cliente (por exemplo, reqwest).
  • \n
  • Verificar a resposta: status, corpo, cabeçalhos.
  • \n
  • Validar o estado do banco de dados (se houver).
  • \n
\n\n

Para aplicações CLI — é executar o binário com argumentos e verificar stdout/stderr. Para aplicações desktop — simular ações do usuário através do WebDriver (Selenium).

\n\n

Quando os testes E2E são obrigatórios?

\n
    \n
  • Você está desenvolvendo uma API pública.
  • \n
  • Você tem uma arquitetura de microsserviços.
  • \n
  • A aplicação interage com serviços externos (bancos de dados, filas, S3).
  • \n
  • Você deseja evitar regressões a cada commit.
  • \n
\n\n

Ferramentas para testes E2E em Rust

\n\n

O ecossistema Rust é rico, mas para E2E precisamos apenas de algumas bibliotecas-chave:

\n\n\n\n\n\n\n\n\n
BibliotecaFinalidade
reqwestCliente HTTP para enviar requisições ao servidor em teste.
tokioRuntime assíncrono — base para executar testes e o servidor.
wiremockServidor Mock para simular APIs externas.
assert_cmd + predicatesPara testar aplicações CLI.
fantocciniCliente WebDriver (se precisar testar o navegador).
\n\n

Usaremos o Rust testing framework nativo (módulo test), mas adicionaremos assincronicidade através de tokio::test.

\n\n

Prática: Escrevendo testes E2E para um serviço web em Actix-Web

\n\n

Suponha que temos uma aplicação web Rust simples em Actix-Web com o endpoint /api/users, que retorna uma lista de usuários do PostgreSQL. Queremos garantir que, em execução real, tudo funcione.

\n\n

Passo 1: Preparação do ambiente de teste

\n\n

Criaremos um arquivo separado tests/e2e.rs (o Rust automaticamente trata arquivos na pasta tests/ como testes de integração).

\n\n
// tests/e2e.rs\nuse std::process::{Command, Stdio};\nuse std::time::Duration;\nuse tokio::time::sleep;\n\n// Função auxiliar: inicia o servidor em segundo plano\nasync fn start_server() -> std::process::Child {\n    let child = Command::new("cargo")\n        .args(&["run", "--bin", "my_app"])\n        .stdout(Stdio::null())\n        .stderr(Stdio::null())\n        .spawn()\n        .expect("Falha ao iniciar o servidor");\n\n    // Dá tempo ao servidor para iniciar\n    sleep(Duration::from_secs(5)).await;\n    child\n}
\n\n

Importante: Em um projeto real, use Docker ou uma configuração de banco de dados separada para testes, para não poluir a produção.

\n\n

Passo 2: Escrevendo testes assíncronos

Blogs

Book Recommendations