You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/testing.md
+29-20Lines changed: 29 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
### The `#[test]` attribute
2
-
Today, rust programmers rely on a built in attribute called `#[test]`.
3
-
All you have to do is mark a function as a test and include some asserts like so:
2
+
Today, rust programmers rely on a built in attribute called `#[test]`. All
3
+
you have to do is mark a function as a test and include some asserts like so:
4
4
5
5
```rust,ignore
6
6
#[test]
@@ -36,10 +36,11 @@ rewrites the crate in 3 steps:
36
36
37
37
#### Step 1: Re-Exporting
38
38
39
-
As mentioned earlier, tests can exist inside private modules, so we need a way of
40
-
exposing them to the main function, without breaking any existing code. To that end,
41
-
`libsyntax` will create local modules called `__test_reexports` that recursively reexport tests.
42
-
This expansion translates the above example into:
39
+
As mentioned earlier, tests can exist inside private modules, so we need a
40
+
way of exposing them to the main function, without breaking any existing
41
+
code. To that end, `libsyntax` will create local modules called
42
+
`__test_reexports` that recursively reexport tests. This expansion translates
43
+
the above example into:
43
44
44
45
```rust,ignore
45
46
mod my_priv_mod {
@@ -76,8 +77,8 @@ collision during code generation and is the foundation of Rust's macro
76
77
hygiene.
77
78
78
79
#### Step 2: Harness Generation
79
-
Now that our tests are accessible from the root of our crate, we need to do something with them.
80
-
`libsyntax` generates a module like so:
80
+
Now that our tests are accessible from the root of our crate, we need to do
81
+
something with them. `libsyntax` generates a module like so:
81
82
82
83
```rust,ignore
83
84
pub mod __test {
@@ -91,15 +92,19 @@ pub mod __test {
91
92
}
92
93
```
93
94
94
-
While this transformation is simple, it gives us a lot of insight into how tests are actually run.
95
-
The tests are aggregated into an array and passed to a test runner called `test_static_main`.
96
-
We'll come back to exactly what `TestDescAndFn` is, but for now, the key takeaway is that there is a crate
97
-
called [`test`][test] that is part of Rust core, that implements all of the runtime for testing. `test`'s interface is unstable,
98
-
so the only stable way to interact with it is through the `#[test]` macro.
95
+
While this transformation is simple, it gives us a lot of insight into how
96
+
tests are actually run. The tests are aggregated into an array and passed to
97
+
a test runner called `test_static_main`. We'll come back to exactly what
98
+
`TestDescAndFn` is, but for now, the key takeaway is that there is a crate
99
+
called [`test`][test] that is part of Rust core, that implements all of the
100
+
runtime for testing. `test`'s interface is unstable, so the only stable way
101
+
to interact with it is through the `#[test]` macro.
99
102
100
103
#### Step 3: Test Object Generation
101
-
If you've written tests in Rust before, you may be familiar with some of the optional attributes available on test functions.
102
-
For example, a test can be annotated with `#[should_panic]` if we expect the test to cause a panic. It looks something like this:
104
+
If you've written tests in Rust before, you may be familiar with some of the
105
+
optional attributes available on test functions. For example, a test can be
106
+
annotated with `#[should_panic]` if we expect the test to cause a panic. It
107
+
looks something like this:
103
108
104
109
```rust,ignore
105
110
#[test]
@@ -109,10 +114,13 @@ fn foo() {
109
114
}
110
115
```
111
116
112
-
This means our tests are more than just simple functions, they have configuration information as well. `test` encodes this configuration
113
-
data into a struct called [`TestDesc`][TestDesc]. For each test function in a crate, `libsyntax` will parse its attributes and generate a `TestDesc` instance.
114
-
It then combines the `TestDesc` and test function into the predictably named `TestDescAndFn` struct, that `test_static_main` operates on.
115
-
For a given test, the generated `TestDescAndFn` instance looks like so:
117
+
This means our tests are more than just simple functions, they have
118
+
configuration information as well. `test` encodes this configuration data
119
+
into a struct called [`TestDesc`][TestDesc]. For each test function in a
120
+
crate, `libsyntax` will parse its attributes and generate a `TestDesc`
121
+
instance. It then combines the `TestDesc` and test function into the
122
+
predictably named `TestDescAndFn` struct, that `test_static_main` operates
123
+
on. For a given test, the generated `TestDescAndFn` instance looks like so:
116
124
117
125
```rust,ignore
118
126
self::test::TestDescAndFn{
@@ -131,7 +139,8 @@ Once we've constructed an array of these test objects, they're passed to the
131
139
test runner via the harness generated in step 2.
132
140
133
141
### Inspecting the generated code
134
-
On nightly rust, there's an unstable flag called `unpretty` that you can use to print out the module source after macro expansion:
142
+
On nightly rust, there's an unstable flag called `unpretty` that you can use
143
+
to print out the module source after macro expansion:
0 commit comments