proptest Rust: guia completo com exemplos práticos

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

proptest para Rust: guia completo de property-based testing

1. O que é e para que serve

A biblioteca proptest é um poderoso framework para property-based testing (testes baseados em propriedades) na linguagem Rust. Diferente dos testes unitários tradicionais, onde você define manualmente dados de entrada específicos e o resultado esperado, o property-based testing propõe descrever propriedades (invariantes) que devem ser verdadeiras para quaisquer dados de entrada válidos. Em seguida, a biblioteca gera automaticamente uma grande quantidade de casos de teste aleatórios e verifica se a propriedade especificada é violada.

Por que isso é importante? Primeiro, permite encontrar "casos de borda" (edge cases) que o desenvolvedor nem imaginava: strings vazias, números negativos, valores muito grandes, estados nulos. Segundo, os testes baseados em propriedades são autodocumentáveis: eles descrevem o contrato da função ("para qualquer número x, a função f(x) retorna um número maior que 0"), e não um exemplo específico. Terceiro, ao modificar o código, esses testes geralmente continuam funcionando sem alterações, pois verificam propriedades gerais, não valores concretos.

proptest é o equivalente das bibliotecas QuickCheck (Haskell), Hypothesis (Python) e FsCheck (.NET). Ela oferece um rico conjunto de estratégias de geração de dados (de números simples a estruturas complexas), um mecanismo de redução (shrinkage) para minimizar exemplos de falha e integração com o framework de testes principal do Rust — cargo test.

2. Instalação

Para usar o proptest, adicione-o na seção [dev-dependencies] do seu arquivo Cargo.toml:

[dev-dependencies]
proptest = "1.4"

Em seguida, execute o comando:

cargo build

A biblioteca será baixada e compilada. Agora você pode usá-la nos seus módulos de teste.

3. Início rápido — exemplo mínimo funcional

Vamos escrever um teste simples que verifica se a função reverse (inverter string) é uma involução: se aplicada duas vezes, obtemos a string original.

// src/lib.rs
pub fn reverse(s: &str) -> String {
    s.chars().rev().collect()
}

#[cfg(test)]
mod tests {
    use super::*;
    use proptest::prelude::*;

    proptest! {
        #[test]
        fn test_reverse_involution(s in ".*") {
            let reversed = reverse(&s);
            let double_reversed = reverse(&reversed);
            assert_eq!(s, double_reversed);
        }
    }
}

Execute o teste com o comando cargo test. O proptest gerará 256 strings aleatórias (valor padrão) e verificará se a propriedade é válida. Se o teste falhar, a biblioteca tentará encontrar o menor exemplo que reproduza o erro.

4. Métodos e funções principais

Abaixo estão os principais componentes da biblioteca proptest. Todos os exemplos assumem que use proptest::prelude::*; foi adicionado no início do módulo de teste.

4.1. Macro proptest!

Assinatura: proptest! { ... }

O que faz: Macro principal que define um bloco de testes baseados em propriedades. Dentro dele, você pode declarar funções de teste com geração automática de dados.

proptest! {
    #[test]
    fn test_addition_commutative(a in 0..100i32, b in 0..100i32) {
        assert_eq!(a + b, b + a);
    }
}

4.2. Estratégia any::<T>()

Recommendations