Introdução ao teste em Rust
Rust é uma linguagem de programação de sistemas conhecida por sua segurança e desempenho. No entanto, mesmo o código mais confiável precisa de verificação. O teste em Rust não é apenas uma opção, mas uma parte essencial do processo de desenvolvimento. Graças ao suporte integrado para testes no Cargo, você pode facilmente escrever e executar testes unit, integration e e2e. Neste artigo, vamos abordar todos os três níveis de teste com exemplos práticos.
Testes unitários em Rust: a base da confiabilidade
Testes unitários verificam funções e métodos individuais de forma isolada. Em Rust, eles são geralmente colocados diretamente no arquivo de código, em um módulo especial tests.
Estrutura de um teste unitário
Cada teste unitário é uma função marcada com o atributo #[test]. Dentro dela, você usa as macros assert!, assert_eq! e assert_ne! para verificar os resultados.
// src/math.rspub fn add(a: i32, b: i32) -> i32 { a + b}
pub fn divide(a: f64, b: f64) -> Result<f64, String> { if b == 0.0 { Err(String::from("Divisão por zero")) } else { Ok(a / b) }}
#[cfg(test)]mod tests { use super::*;
#[test] fn test_add() { assert_eq!(add(2, 3), 5); }
#[test] fn test_divide_success() { let result = divide(10.0, 2.0); assert!(result.is_ok()); assert_eq!(result.unwrap(), 5.0); }
#[test] fn test_divide_by_zero() { let result = divide(10.0, 0.0); assert!(result.is_err()); assert_eq!(result.unwrap_err(), "Divisão por zero"); }}Observe o atributo #[cfg(test)]. Ele instrui o compilador a incluir este módulo apenas durante a compilação dos testes. Isso economiza tempo de compilação do binário final.
Executando testes unitários
Para executar todos os testes no projeto, use o comando:
cargo testVocê também pode executar um teste específico pelo nome:
cargo test test_addOu filtrar testes por uma palavra-chave:
cargo test divideTestes de integração em Rust: verificando a interação
Testes de integração verificam como diferentes módulos da sua aplicação funcionam juntos. Ao contrário dos testes unitários, eles estão localizados em uma pasta separada tests/ no nível raiz do projeto.
Estrutura de um teste de integração
Crie um arquivo tests/integration_test.rs:
// tests/integration_test.rsuse my_project::math; // assumindo que a biblioteca se chama my_project
#[test]fn test_add_and_divide() { let sum = math::add(10, 5); let result = math::divide(sum as f64, 3.0).unwrap(); assert_eq!(result, 5.0);}
#[test]fn test_complex_calculation() { let a = math::add(100, 200); let b = math::add(50, 50); let result = math::divide(a as f64, b as f64).unwrap(); assert_eq!(result, 3.0);}Cada arquivo em tests/ é compilado como um crate separado. Isso significa que você pode ter vários arquivos de teste para diferentes cenários.
Módulo comum para testes de integração
Se você precisar de utilitários comuns para todos os testes de integração, crie uma subpasta tests/common/ com um arquivo mod.rs:
// tests/common/mod.rspub fn setup() { // Inicialização do ambiente de teste println!("Configurando ambiente de teste...");}E use-o nos testes:
// tests/integration_test.rsmod common;
#[test]fn test_with_setup() { common::setup(); // Seu teste}Testes E2E em Rust: imersão completa
Testes E2E (end-to-end) verificam o funcionamento de toda a aplicação do início ao fim. Em Rust, para isso, frequentemente se utiliza