Crate test_gen

source ·
Expand description

A comprehensive function-like macro, for concisely defining parameterized tests.

When writing automated tests, it’s generally done with two key goals:

  1. Comprehensive code coverage
  2. Debuggability

Out of the box, the design of Rusts standard testing framework, can make comfortably achieving both, a challenge…

For most effective debuggability, the design of Rusts testing framework encorages writing separate test functions for every case, as these are each tracked separately against the name of the test function. Unfortunately, this results in the need for a significant deal of boilerplate, to achieved comprehensive code coverage.

By constrast, comprehensive code coverage can be achieved easily and concisely, via the use of iteration, but sacrifices clarity and debuggability, by using the same named case, to test potentially many values.

test_gen is designed to address both goals, by enabling the concise definition of batches of named tests, using a parameterized argument format to minimise the boilerplate otherwise required for specifying batches of tests.

Examples

Fruits:

use test_gen::*;

enum Fruit<T> {
    Apple,
    Pear,
    Other(T),
}

enum BrambleFruit {
    BlackBerry,
}

trait NameOf {
    fn name_of(&self) -> &str;
}

impl<T: NameOf> NameOf for Fruit<T> {
    fn name_of(&self) -> &str {
        use Fruit::*;

        match self {
            Apple => "apple",
            Pear => "pear",
            Other(fruit) => fruit.name_of(),
        }
    }
}

impl NameOf for BrambleFruit {
    fn name_of(&self) -> &str {
        use BrambleFruit::*;

        match self {
            BlackBerry => "blackberry",
        }
    }
}

// Helper function
fn assert_fruit<T: NameOf>(fruit: Fruit<T>, name: &str) {
    assert_eq!(fruit.name_of(), name);
}

// Test specification
test_gen! {
    // Normal turbofish syntax can be used,
    // when concrete type specification is required
    fn assert_fruit::<BrambleFruit> => {
        apple: {
            (Fruit::Apple, "apple")
        },
        // Applying case specific attributes
        pear: {
            #[ignore]
            (Fruit::Pear, "pear")
        },
        isnt_pear: {
            #[should_panic]
            (Fruit::Pear, "apple")
        },
        blackberry: {
            (Fruit::Other(BrambleFruit::BlackBerry), "blackberry")
        },
    }
}

License

test_gen is licensed under the BSD 3-Clause license.

See LICENSE for details.

Macros

Generates unique, named test cases, based on parameterized inputs.