Skip to content

Update test to use the attribute template #1880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 1, 2025
Merged
67 changes: 46 additions & 21 deletions src/attributes/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,43 @@ r[attributes.testing.test]
## The `test` attribute

r[attributes.testing.test.intro]
The *`test` attribute* marks a function to be executed as a test.

r[attributes.testing.test.enabled]
These functions are only compiled when in test mode.
The *`test` [attribute][attributes]* marks a function to be executed as a test.

> [!EXAMPLE]
> ```rust
> # pub fn add(left: u64, right: u64) -> u64 { left + right }
>
> #[test]
> fn it_works() {
> let result = add(2, 2);
> assert_eq!(result, 4);
> }
> ```

r[attributes.testing.test.syntax]
The `test` attribute uses the [MetaWord] syntax and thus does not take any inputs.

r[attributes.testing.test.allowed-positions]
Test functions must be free, monomorphic functions that take no arguments, and the return type must implement the [`Termination`] trait, for example:
The `test` attribute may only be applied to [free functions] that are monomorphic, that take no arguments, and where the return type implements the [`Termination`] trait.

* `()`
* `Result<T, E> where T: Termination, E: Debug`
* `!`
> [!NOTE]
> Some of types that implement the [`Termination`] trait include:
> * `()`
> * `Result<T, E> where T: Termination, E: Debug`

<!-- If the previous section needs updating (from "must take no arguments"
onwards, also update it in the crates-and-source-files.md file -->
r[attributes.testing.test.duplicates]
Only the first instance of `test` on a function is honored.

> [!NOTE]
> Subsequent `test` attributes are currently ignored and `rustc` warns about these.

<!-- TODO: This is a minor lie. Currently rustc warns that duplicates are ignored, but it then generates multiple test entries with the same name. I would vote for rejecting this in the future. -->

r[attributes.testing.test.stdlib]
The `test` attribute is exported from the standard library prelude as [`std::prelude::v1::test`].

r[attributes.testing.test.enabled]
These functions are only compiled when in test mode.

> [!NOTE]
> The test mode is enabled by passing the `--test` argument to `rustc` or using `cargo test`.
Expand All @@ -36,17 +59,18 @@ In particular:
* Tests that return `ExitCode::SUCCESS` pass, and tests that return `ExitCode::FAILURE` fail.
* Tests that do not terminate neither pass nor fail.

```rust
# use std::io;
# fn setup_the_thing() -> io::Result<i32> { Ok(1) }
# fn do_the_thing(s: &i32) -> io::Result<()> { Ok(()) }
#[test]
fn test_the_thing() -> io::Result<()> {
let state = setup_the_thing()?; // expected to succeed
do_the_thing(&state)?; // expected to succeed
Ok(())
}
```
> [!EXAMPLE]
> ```rust
> # use std::io;
> # fn setup_the_thing() -> io::Result<i32> { Ok(1) }
> # fn do_the_thing(s: &i32) -> io::Result<()> { Ok(()) }
> #[test]
> fn test_the_thing() -> io::Result<()> {
> let state = setup_the_thing()?; // expected to succeed
> do_the_thing(&state)?; // expected to succeed
> Ok(())
> }
> ```

r[attributes.testing.ignore]
## The `ignore` attribute
Expand Down Expand Up @@ -102,3 +126,4 @@ fn mytest() {
[`test` conditional compilation option]: ../conditional-compilation.md#test
[attributes]: ../attributes.md
[`ExitCode`]: std::process::ExitCode
[free functions]: ../glossary.md#free-item