|
1 | | -//! A library for providing custom setup/teardown for Rust tests without needing a test harness. |
2 | | -//! |
3 | | -//! ```no_run |
4 | | -//! use test_context::{test_context, TestContext}; |
5 | | -//! |
6 | | -//! struct MyContext { |
7 | | -//! value: String |
8 | | -//! } |
9 | | -//! |
10 | | -//! impl TestContext for MyContext { |
11 | | -//! fn setup() -> MyContext { |
12 | | -//! MyContext { value: "Hello, world!".to_string() } |
13 | | -//! } |
14 | | -//! |
15 | | -//! fn teardown(self) { |
16 | | -//! // Perform any teardown you wish. |
17 | | -//! } |
18 | | -//! } |
19 | | -//! |
20 | | -//! #[test_context(MyContext)] |
21 | | -//! #[test] |
22 | | -//! fn test_works(ctx: &mut MyContext) { |
23 | | -//! assert_eq!(ctx.value, "Hello, world!"); |
24 | | -//! } |
25 | | -//! ``` |
26 | | -//! |
27 | | -//! Alternatively, you can use `async` functions in your test context by using the |
28 | | -//! `AsyncTestContext`. |
29 | | -//! |
30 | | -//! ```no_run |
31 | | -//! use test_context::{test_context, AsyncTestContext}; |
32 | | -//! |
33 | | -//! struct MyAsyncContext { |
34 | | -//! value: String |
35 | | -//! } |
36 | | -//! |
37 | | -//! impl AsyncTestContext for MyAsyncContext { |
38 | | -//! async fn setup() -> MyAsyncContext { |
39 | | -//! MyAsyncContext { value: "Hello, world!".to_string() } |
40 | | -//! } |
41 | | -//! |
42 | | -//! async fn teardown(self) { |
43 | | -//! // Perform any teardown you wish. |
44 | | -//! } |
45 | | -//! } |
46 | | -//! |
47 | | -//! #[test_context(MyAsyncContext)] |
48 | | -//! #[test] |
49 | | -//! fn test_works(ctx: &mut MyAsyncContext) { |
50 | | -//! assert_eq!(ctx.value, "Hello, World!"); |
51 | | -//! } |
52 | | -//! ``` |
53 | | -//! |
54 | | -//! The `AsyncTestContext` works well with async test wrappers like |
55 | | -//! [`actix_rt::test`](https://docs.rs/actix-rt/1.1.1/actix_rt/attr.test.html) or |
56 | | -//! [`tokio::test`](https://docs.rs/tokio/1.0.2/tokio/attr.test.html). |
57 | | -//! |
58 | | -//! ```no_run |
59 | | -//! use test_context::{test_context, AsyncTestContext}; |
60 | | -//! |
61 | | -//! struct MyAsyncContext { |
62 | | -//! value: String |
63 | | -//! } |
64 | | -//! |
65 | | -//! impl AsyncTestContext for MyAsyncContext { |
66 | | -//! async fn setup() -> MyAsyncContext { |
67 | | -//! MyAsyncContext { value: "Hello, world!".to_string() } |
68 | | -//! } |
69 | | -//! async fn teardown(self) { |
70 | | -//! // Perform any teardown you wish. |
71 | | -//! } |
72 | | -//! } |
73 | | -//! |
74 | | -//! #[test_context(MyAsyncContext)] |
75 | | -//! #[tokio::test] |
76 | | -//! async fn test_async_works(ctx: &mut MyAsyncContext) { |
77 | | -//! assert_eq!(ctx.value, "Hello, World!"); |
78 | | -//! } |
79 | | -//! ``` |
80 | | -//! |
81 | | -//! # Attribute order |
82 | | -//! |
83 | | -//! Attribute order matters. Always place `#[test_context(...)]` before other test attributes |
84 | | -//! like `#[tokio::test]` or `#[test]`. |
85 | | -//! |
86 | | -//! Why: Rust expands attributes in source order. `#[test_context]` wraps your function and |
87 | | -//! re-attaches the remaining attributes to the wrapper; it must run first so the test attributes |
88 | | -//! apply to the wrapper that performs setup/teardown. |
89 | | -//! |
90 | | -//! Valid: |
91 | | -//! ```ignore |
92 | | -//! #[test_context(MyAsyncContext)] |
93 | | -//! #[tokio::test] |
94 | | -//! async fn my_test(ctx: &mut MyAsyncContext) {} |
95 | | -//! ``` |
96 | | -//! |
97 | | -//! Invalid: |
98 | | -//! ```ignore |
99 | | -//! #[tokio::test] |
100 | | -//! #[test_context(MyAsyncContext)] |
101 | | -//! async fn my_test(ctx: &mut MyAsyncContext) {} |
102 | | -//! ``` |
103 | | -//! |
104 | | -//! # Skipping the teardown execution |
105 | | -//! |
106 | | -//! Also, if you don't care about the teardown execution for a specific test, |
107 | | -//! you can use the `skip_teardown` keyword on the macro like this: |
108 | | -//! |
109 | | -//! ```no_run |
110 | | -//! use test_context::{test_context, TestContext}; |
111 | | -//! |
112 | | -//! struct MyContext {} |
113 | | -//! |
114 | | -//! impl TestContext for MyContext { |
115 | | -//! fn setup() -> MyContext { |
116 | | -//! MyContext {} |
117 | | -//! } |
118 | | -//! } |
119 | | -//! |
120 | | -//! #[test_context(MyContext, skip_teardown)] |
121 | | -//! #[test] |
122 | | -//! fn test_without_teardown(ctx: &mut MyContext) { |
123 | | -//! // Perform any operations that require full ownership of your context |
124 | | -//! } |
125 | | -//! ``` |
| 1 | +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../README.md"))] |
126 | 2 |
|
127 | 3 | // Reimported to allow for use in the macro. |
128 | 4 | pub use futures; |
|
0 commit comments