Skip to content

Commit 2b92742

Browse files
authored
[Testing 1/2] Revise testing chapters excluding the directives chapter (rust-lang#2088)
1 parent 0a9b996 commit 2b92742

16 files changed

+1406
-1043
lines changed

src/SUMMARY.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
- [Testing with Docker](./tests/docker.md)
2222
- [Testing with CI](./tests/ci.md)
2323
- [Adding new tests](./tests/adding.md)
24+
- [Best practices](./tests/best-practices.md)
2425
- [Compiletest](./tests/compiletest.md)
2526
- [UI tests](./tests/ui.md)
26-
- [Test headers](./tests/headers.md)
27-
- [Integration testing](./tests/integration.md)
27+
- [Test headers](./tests/directives.md)
28+
- [Ecosystem testing](./tests/ecosystem.md)
2829
- [Crater](./tests/crater.md)
2930
- [Fuchsia](./tests/fuchsia.md)
3031
- [Rust for Linux](./tests/rust-for-linux.md)

src/tests/adding.md

+96-91
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,62 @@
22

33
<!-- toc -->
44

5-
**In general, we expect every PR that fixes a bug in rustc to come
6-
accompanied by a regression test of some kind.** This test should fail
7-
in master but pass after the PR. These tests are really useful for
8-
preventing us from repeating the mistakes of the past.
5+
**In general, we expect every PR that fixes a bug in rustc to come accompanied
6+
by a regression test of some kind.** This test should fail in master but pass
7+
after the PR. These tests are really useful for preventing us from repeating the
8+
mistakes of the past.
99

10-
The first thing to decide is which kind of test to add.
11-
This will depend on the nature of the change and what you want to exercise.
12-
Here are some rough guidelines:
10+
The first thing to decide is which kind of test to add. This will depend on the
11+
nature of the change and what you want to exercise. Here are some rough
12+
guidelines:
1313

1414
- The majority of compiler tests are done with [compiletest].
15-
- The majority of compiletest tests are [UI](ui.md) tests in the [`tests/ui`] directory.
16-
- Changes to the standard library are usually tested within the standard library itself.
17-
- The majority of standard library tests are written as doctests,
18-
which illustrate and exercise typical API behavior.
15+
- The majority of compiletest tests are [UI](ui.md) tests in the [`tests/ui`]
16+
directory.
17+
- Changes to the standard library are usually tested within the standard library
18+
itself.
19+
- The majority of standard library tests are written as doctests, which
20+
illustrate and exercise typical API behavior.
1921
- Additional [unit tests](intro.md#package-tests) should go in
20-
`library/${crate}/tests` (where `${crate}` is usually `core`, `alloc`, or `std`).
21-
- If the code is part of an isolated system, and you are not testing compiler output,
22-
consider using a [unit or integration test](intro.md#package-tests).
23-
- Need to run rustdoc? Prefer a `rustdoc` or `rustdoc-ui` test.
24-
Occasionally you'll need `rustdoc-js` as well.
22+
`library/${crate}/tests` (where `${crate}` is usually `core`, `alloc`, or
23+
`std`).
24+
- If the code is part of an isolated system, and you are not testing compiler
25+
output, consider using a [unit or integration test](intro.md#package-tests).
26+
- Need to run rustdoc? Prefer a `rustdoc` or `rustdoc-ui` test. Occasionally
27+
you'll need `rustdoc-js` as well.
2528
- Other compiletest test suites are generally used for special purposes:
2629
- Need to run gdb or lldb? Use the `debuginfo` test suite.
27-
- Need to inspect LLVM IR or MIR IR? Use the `codegen` or `mir-opt` test suites.
28-
- Need to inspect the resulting binary in some way?
29-
Then use `run-make`.
30+
- Need to inspect LLVM IR or MIR IR? Use the `codegen` or `mir-opt` test
31+
suites.
32+
- Need to inspect the resulting binary in some way? Or if all the other test
33+
suites are too limited for your purposes? Then use `run-make`.
3034
- Check out the [compiletest] chapter for more specialized test suites.
3135

36+
After deciding on which kind of test to add, see [best
37+
practices](best-practices.md) for guidance on how to author tests that are easy
38+
to work with that stand the test of time (i.e. if a test fails or need to be
39+
modified several years later, how can we make it easier for them?).
40+
3241
[compiletest]: compiletest.md
3342
[`tests/ui`]: https://github.com/rust-lang/rust/tree/master/tests/ui/
3443

3544
## UI test walkthrough
3645

37-
The following is a basic guide for creating a [UI test](ui.md), which is one
38-
of the most common compiler tests.
39-
For this tutorial, we'll be adding a test for an async error message.
46+
The following is a basic guide for creating a [UI test](ui.md), which is one of
47+
the most common compiler tests. For this tutorial, we'll be adding a test for an
48+
async error message.
4049

41-
### Step 1. Add a test file
50+
### Step 1: Add a test file
4251

43-
The first step is to create a Rust source file somewhere in the
44-
[`tests/ui`] tree.
45-
When creating a test, do your best to find a good location and name (see [Test
46-
organization](ui.md#test-organization) for more).
47-
Since naming is the hardest part of development, everything should be downhill
48-
from here!
52+
The first step is to create a Rust source file somewhere in the [`tests/ui`]
53+
tree. When creating a test, do your best to find a good location and name (see
54+
[Test organization](ui.md#test-organization) for more). Since naming is the
55+
hardest part of development, everything should be downhill from here!
4956

5057
Let's place our async test at `tests/ui/async-await/await-without-async.rs`:
5158

5259
```rust,ignore
53-
// Check what happens when using await in a non-async fn.
60+
// Provide diagnostics when the user writes `await` in a non-`async` function.
5461
//@ edition:2018
5562
5663
async fn foo() {}
@@ -64,24 +71,22 @@ fn main() {}
6471

6572
A few things to notice about our test:
6673

67-
* The top should start with a short comment that [explains what the test is
74+
- The top should start with a short comment that [explains what the test is
6875
for](#explanatory_comment).
69-
* The `//@ edition:2018` comment is called a [header](headers.md) which provides
70-
instructions to compiletest on how to build the test.
71-
Here we need to set the edition for `async` to work (the default is 2015).
72-
* Following that is the source of the test.
73-
Try to keep it succinct and to the point.
74-
This may require some effort if you are trying to minimize an example from a
75-
bug report.
76-
* We end this test with an empty `fn main` function.
77-
This is because the default for UI tests is a `bin` crate-type,
78-
and we don't want the "main not found" error in our test.
79-
Alternatively, you could add `#![crate_type="lib"]`.
80-
81-
### Step 2. Generate the expected output
82-
83-
The next step is to create the expected output from the compiler.
84-
This can be done with the `--bless` option:
76+
- The `//@ edition:2018` comment is called a [directive](directives.md) which
77+
provides instructions to compiletest on how to build the test. Here we need to
78+
set the edition for `async` to work (the default is edition 2015).
79+
- Following that is the source of the test. Try to keep it succinct and to the
80+
point. This may require some effort if you are trying to minimize an example
81+
from a bug report.
82+
- We end this test with an empty `fn main` function. This is because the default
83+
for UI tests is a `bin` crate-type, and we don't want the "main not found"
84+
error in our test. Alternatively, you could add `#![crate_type="lib"]`.
85+
86+
### Step 2: Generate the expected output
87+
88+
The next step is to create the expected output snapshots from the compiler. This
89+
can be done with the `--bless` option:
8590

8691
```sh
8792
./x test tests/ui/async-await/await-without-async.rs --bless
@@ -91,28 +96,30 @@ This will build the compiler (if it hasn't already been built), compile the
9196
test, and place the output of the compiler in a file called
9297
`tests/ui/async-await/await-without-async.stderr`.
9398

94-
However, this step will fail!
95-
You should see an error message, something like this:
99+
However, this step will fail! You should see an error message, something like
100+
this:
96101

97102
> error: /rust/tests/ui/async-await/await-without-async.rs:7: unexpected
98103
> error: '7:10: 7:16: `await` is only allowed inside `async` functions and
99104
> blocks E0728'
100105
101-
### Step 3. Add error annotations
106+
This is because the stderr contains errors which were not matched by error
107+
annotations in the source file.
108+
109+
### Step 3: Add error annotations
102110

103-
Every error needs to be annotated with a comment in the source with the text
104-
of the error.
105-
In this case, we can add the following comment to our test file:
111+
Every error needs to be annotated with a comment in the source with the text of
112+
the error. In this case, we can add the following comment to our test file:
106113

107114
```rust,ignore
108115
fn bar() {
109116
foo().await
110-
//~^ ERROR `await` is only allowed inside `async` functions and blocks
117+
//~^ ERROR `await` is only allowed inside `async` functions and blocks
111118
}
112119
```
113120

114121
The `//~^` squiggle caret comment tells compiletest that the error belongs to
115-
the previous line (more on this in the [Error
122+
the *previous* line (more on this in the [Error
116123
annotations](ui.md#error-annotations) section).
117124

118125
Save that, and run the test again:
@@ -123,16 +130,15 @@ Save that, and run the test again:
123130

124131
It should now pass, yay!
125132

126-
### Step 4. Review the output
133+
### Step 4: Review the output
127134

128135
Somewhat hand-in-hand with the previous step, you should inspect the `.stderr`
129-
file that was created to see if it looks like how you expect.
130-
If you are adding a new diagnostic message, now would be a good time to
131-
also consider how readable the message looks overall, particularly for
132-
people new to Rust.
136+
file that was created to see if it looks like how you expect. If you are adding
137+
a new diagnostic message, now would be a good time to also consider how readable
138+
the message looks overall, particularly for people new to Rust.
133139

134-
Our example `tests/ui/async-await/await-without-async.stderr` file should
135-
look like this:
140+
Our example `tests/ui/async-await/await-without-async.stderr` file should look
141+
like this:
136142

137143
```text
138144
error[E0728]: `await` is only allowed inside `async` functions and blocks
@@ -148,48 +154,47 @@ error: aborting due to previous error
148154
For more information about this error, try `rustc --explain E0728`.
149155
```
150156

151-
You may notice some things look a little different than the regular
152-
compiler output.
153-
The `$DIR` removes the path information which will differ between systems.
154-
The `LL` values replace the line numbers.
155-
That helps avoid small changes in the source from triggering large diffs.
156-
See the [Normalization](ui.md#normalization) section for more.
157+
You may notice some things look a little different than the regular compiler
158+
output.
159+
160+
- The `$DIR` removes the path information which will differ between systems.
161+
- The `LL` values replace the line numbers. That helps avoid small changes in
162+
the source from triggering large diffs. See the
163+
[Normalization](ui.md#normalization) section for more.
157164

158165
Around this stage, you may need to iterate over the last few steps a few times
159166
to tweak your test, re-bless the test, and re-review the output.
160167

161-
### Step 5. Check other tests
168+
### Step 5: Check other tests
162169

163-
Sometimes when adding or changing a diagnostic message, this will affect
164-
other tests in the test suite.
165-
The final step before posting a PR is to check if you have affected anything else.
166-
Running the UI suite is usually a good start:
170+
Sometimes when adding or changing a diagnostic message, this will affect other
171+
tests in the test suite. The final step before posting a PR is to check if you
172+
have affected anything else. Running the UI suite is usually a good start:
167173

168174
```sh
169175
./x test tests/ui
170176
```
171177

172-
If other tests start failing, you may need to investigate what has changed
173-
and if the new output makes sense.
178+
If other tests start failing, you may need to investigate what has changed and
179+
if the new output makes sense.
180+
174181
You may also need to re-bless the output with the `--bless` flag.
175182

176183
<a name="explanatory_comment"></a>
177184

178185
## Comment explaining what the test is about
179186

180-
The first comment of a test file should **summarize the point
181-
of the test**, and highlight what is important about it.
182-
If there is an issue number associated with the test, include
183-
the issue number.
184-
185-
This comment doesn't have to be super extensive. Just something like
186-
"Regression test for #18060: match arms were matching in the wrong
187-
order." might already be enough.
188-
189-
These comments are very useful to others later on when your test
190-
breaks, since they often can highlight what the problem is. They are
191-
also useful if for some reason the tests need to be refactored, since
192-
they let others know which parts of the test were important (often a
193-
test must be rewritten because it no longer tests what is was meant to
194-
test, and then it's useful to know what it *was* meant to test
195-
exactly).
187+
The first comment of a test file should **summarize the point of the test**, and
188+
highlight what is important about it. If there is an issue number associated
189+
with the test, include the issue number.
190+
191+
This comment doesn't have to be super extensive. Just something like "Regression
192+
test for #18060: match arms were matching in the wrong order." might already be
193+
enough.
194+
195+
These comments are very useful to others later on when your test breaks, since
196+
they often can highlight what the problem is. They are also useful if for some
197+
reason the tests need to be refactored, since they let others know which parts
198+
of the test were important. Often a test must be rewritten because it no longer
199+
tests what is was meant to test, and then it's useful to know what it *was*
200+
meant to test exactly.

0 commit comments

Comments
 (0)