#test-harness #async-test #teardown #async-context #setup #test

test-context

A library for providing custom setup/teardown for Rust tests without needing a test harness

10 releases

0.4.1 Jan 27, 2025
0.4.0 Jan 27, 2025
0.3.0 Feb 27, 2024
0.2.0 Feb 26, 2024
0.1.1 Jan 18, 2021

#28 in Testing

Download history 12843/week @ 2024-10-22 12413/week @ 2024-10-29 11070/week @ 2024-11-05 12730/week @ 2024-11-12 12407/week @ 2024-11-19 14158/week @ 2024-11-26 15824/week @ 2024-12-03 23751/week @ 2024-12-10 24762/week @ 2024-12-17 7661/week @ 2024-12-24 12295/week @ 2024-12-31 28150/week @ 2025-01-07 25836/week @ 2025-01-14 28399/week @ 2025-01-21 28029/week @ 2025-01-28 28341/week @ 2025-02-04

115,895 downloads per month
Used in 278 crates (25 directly)

MIT license

10KB

crates.io Documentation License Github

test-context

A library for providing custom setup/teardown for Rust tests without needing a test harness.

use test_context::{test_context, TestContext};

struct MyContext {
    value: String
}

impl TestContext for MyContext {
    fn setup() -> MyContext {
        MyContext {  value: "Hello, World!".to_string() }
    }

    fn teardown(self) {
        // Perform any teardown you wish.
    }
}

#[test_context(MyContext)]
#[test]
fn test_works(ctx: &mut MyContext) {
    assert_eq!(ctx.value, "Hello, World!");
}

struct MyGenericContext<T> {
    value: T
}

impl TestContext for MyGenericContext<u32> {
    fn setup() -> MyGenericContext<u32> {
        MyGenericContext { value: 1 }
    }
}

#[test_context(MyGenericContext<u32>)]
#[test]
fn test_generic_type(ctx: &mut MyGenericContext<u32>) {
    assert_eq!(ctx.value, 1);
}

Alternatively, you can use async functions in your test context by using the AsyncTestContext.

use test_context::{test_context, AsyncTestContext};

struct MyAsyncContext {
    value: String
}

impl AsyncTestContext for MyAsyncContext {
    async fn setup() -> MyAsyncContext {
        MyAsyncContext { value: "Hello, World!".to_string() }
    }

    async fn teardown(self) {
        // Perform any teardown you wish.
    }
}

#[test_context(MyAsyncContext)]
fn test_works(ctx: &mut MyAsyncContext) {
    assert_eq!(ctx.value, "Hello, World!");
}

The AsyncTestContext works well with async test wrappers like actix_rt::test or tokio::test.

#[test_context(MyAsyncContext)]
#[tokio::test]
async fn test_works(ctx: &mut MyAsyncContext) {
    assert_eq!(ctx.value, "Hello, World!");
}

Skipping the teardown execution

If what you need is to take full ownership of the context and don't care about the teardown execution for a specific test, you can use the skip_teardown keyword on the macro like this:

 use test_context::{test_context, TestContext};

 struct MyContext {}

 impl TestContext for MyContext {
     fn setup() -> MyContext {
         MyContext {}
     }
 }

#[test_context(MyContext, skip_teardown)]
#[test]
fn test_without_teardown(ctx: MyContext) {
  // Perform any operations that require full ownership of your context
}

License: MIT

Dependencies

~0.8–1.5MB
~30K SLoC