Attribute Macro test_casing::decorate

source ·
#[decorate]
Expand description

Wraps a tested function to add retries, timeouts etc.

§Inputs

This attribute must be placed on a test function (i.e., one decorated with #[test], #[tokio::test], etc.). The attribute must be invoked with a comma-separated list of one or more test decorators. Each decorator must be a constant expression (i.e., it should be usable as a definition of a static variable).

§Examples

§Basic usage

use test_casing::{decorate, decorators::Timeout};

#[test]
#[decorate(Timeout::secs(1))]
fn test_with_timeout() {
    // test logic
}

§Tests returning Results

Decorators can be used on tests returning Results, too:

use test_casing::{decorate, decorators::{Retry, Timeout}};
use std::error::Error;

#[test]
#[decorate(Timeout::millis(200), Retry::times(2))]
// ^ Decorators are applied in the order of their mention. In this case,
// if the test times out, errors or panics, it will be retried up to 2 times.
fn test_with_retries() -> Result<(), Box<dyn Error + Send>> {
    // test logic
}

§Multiple decorate attributes

Multiple decorate attributes are allowed. Thus, the test above is equivalent to

#[test]
#[decorate(Timeout::millis(200))]
#[decorate(Retry::times(2))]
fn test_with_retries() -> Result<(), Box<dyn Error + Send>> {
    // test logic
}

§Async tests

Decorators work on async tests as well, as long as the decorate macro is applied after the test macro:

#[async_std::test]
#[decorate(Retry::times(3))]
async fn async_test() {
    // test logic
}

§Composability and reuse

Decorators can be extracted to a constant or a static for readability, composability and/or reuse:

const RETRY: RetryErrors<String> = Retry::times(2)
    .with_delay(Duration::from_secs(1))
    .on_error(|s| s.contains("oops"));

static SEQUENCE: Sequence = Sequence::new().abort_on_failure();

#[test]
#[decorate(RETRY, &SEQUENCE)]
fn test_with_error_retries() -> Result<(), String> {
    // test logic
}

#[test]
#[decorate(&SEQUENCE)]
fn other_test() {
    // test logic
}

§Use with test_casing

When used together with the test_casing macro, the decorators will apply to each generated case.

use test_casing::{decorate, test_casing, decorators::Timeout};

#[test_casing(3, [3, 5, 42])]
#[decorate(Timeout::secs(1))]
fn parameterized_test_with_timeout(input: u64) {
    // test logic
}