Rust 学习笔记:控制测试的运行方式
Rust 学习笔记:控制测试的运行方式
cargo test 生成的二进制文件的默认行为是并行运行所有测试,并捕获测试运行期间生成的输出,从而防止显示输出,并使读取与测试结果相关的输出变得更容易。但是,可以指定命令行选项来更改此默认行为。
列出用于测试二进制文件的参数:
cargo test --help
Execute all unit and integration tests and build examples of a local package
Usage: cargo.exe test [OPTIONS] [TESTNAME] [-- [ARGS]...]
Arguments:
[TESTNAME] If specified, only run tests containing this string in their names
[ARGS]... Arguments for the test binary
Options:
--no-run Compile, but don't run tests
--no-fail-fast Run all tests regardless of failure
--future-incompat-report Outputs a future incompatibility report at the end of the build
--message-format <FMT> Error format
-q, --quiet Display one character per test instead of one line
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
--config <KEY=VALUE|PATH> Override a configuration value
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
-h, --help Print help
Package Selection:
-p, --package [<SPEC>] Package to run tests for
--workspace Test all packages in the workspace
--exclude <SPEC> Exclude packages from the test
--all Alias for --workspace (deprecated)
Target Selection:
--lib Test only this package's library
--bins Test all binaries
--bin [<NAME>] Test only the specified binary
--examples Test all examples
--example [<NAME>] Test only the specified example
--tests Test all targets that have `test = true` set
--test [<NAME>] Test only the specified test target
--benches Test all targets that have `bench = true` set
--bench [<NAME>] Test only the specified bench target
--all-targets Test all targets (does not include doctests)
--doc Test only this library's documentation
Feature Selection:
-F, --features <FEATURES> Space or comma separated list of features to activate
--all-features Activate all available features
--no-default-features Do not activate the `default` feature
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
--target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
Manifest Options:
--manifest-path <PATH> Path to Cargo.toml
--lockfile-path <PATH> Path to Cargo.lock (unstable)
--ignore-rust-version Ignore `rust-version` specification in packages
--locked Assert that `Cargo.lock` will remain unchanged
--offline Run without accessing the network
--frozen Equivalent to specifying both --locked and --offline
Run `cargo help test` for more detailed information.
Run `cargo test -- --help` for test binary options.
列出用于测试二进制文件的选项:
cargo test -- --help
Usage: C:\Users\81228\Documents\Program\Rust Project\adder\target\debug\deps\adder-ca62dcededf22ef1.exe [OPTIONS] [FILTERS...]
Options:
--include-ignored
Run ignored and not ignored tests
--ignored Run only ignored tests
--force-run-in-process
Forces tests to run in-process when panic=abort
--exclude-should-panic
Excludes tests marked as should_panic
--test Run tests and not benchmarks
--bench Run benchmarks instead of tests
--list List all tests and benchmarks
-h, --help Display this message
--logfile PATH Write logs to the specified file (deprecated)
--nocapture don't capture stdout/stderr of each task, allow
printing directly
--test-threads n_threads
Number of threads used for running tests in parallel
--skip FILTER Skip tests whose names contain FILTER (this flag can
be used multiple times)
-q, --quiet Display one character per test instead of one line.
Alias to --format=terse
--exact Exactly match filters rather than by substring
--color auto|always|never
Configure coloring of output:
auto = colorize if stdout is a tty and tests are run
on serially (default);
always = always colorize output;
never = never colorize output;
--format pretty|terse|json|junit
Configure formatting of output:
pretty = Print verbose output;
terse = Display one character per test;
json = Output a json document;
junit = Output a JUnit document
--show-output Show captured stdout of successful tests
-Z unstable-options Enable nightly-only flags:
unstable-options = Allow use of experimental features
--report-time Show execution time of each test.
Threshold values for colorized output can be
configured via
`RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
and
`RUST_TEST_TIME_DOCTEST` environment variables.
Expected format of environment variable is
`VARIABLE=WARN_TIME,CRITICAL_TIME`.
Durations must be specified in milliseconds, e.g.
`500,2000` means that the warn time
is 0.5 seconds, and the critical time is 2 seconds.
Not available for --format=terse
--ensure-time Treat excess of the test execution time limit as
error.
Threshold values for this option can be configured via
`RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
and
`RUST_TEST_TIME_DOCTEST` environment variables.
Expected format of environment variable is
`VARIABLE=WARN_TIME,CRITICAL_TIME`.
`CRITICAL_TIME` here means the limit that should not
be exceeded by test.
--shuffle Run tests in random order
--shuffle-seed SEED
Run tests in random order; seed the random number
generator with SEED
The FILTER string is tested against the name of all tests, and only those
tests whose names contain the filter are run. Multiple filter strings may
be passed, which will run all tests matching any of the filters.
By default, all tests are run in parallel. This can be altered with the
--test-threads flag or the RUST_TEST_THREADS environment variable when running
tests (set it to 1).
By default, the tests are run in alphabetical order. Use --shuffle or set
RUST_TEST_SHUFFLE to run the tests in random order. Pass the generated
"shuffle seed" to --shuffle-seed (or set RUST_TEST_SHUFFLE_SEED) to run the
tests in the same order again. Note that --shuffle and --shuffle-seed do not
affect whether the tests are run in parallel.
All tests have their standard output and standard error captured by default.
This can be overridden with the --nocapture flag or setting RUST_TEST_NOCAPTURE
environment variable to a value other than "0". Logging is not captured by default.
Test Attributes:
`#[test]` - Indicates a function is a test to be run. This function
takes no arguments.
`#[bench]` - Indicates a function is a benchmark to be run. This
function takes one argument (test::Bencher).
`#[should_panic]` - This function (also labeled with `#[test]`) will only pass if
the code causes a panic (an assertion failure or panic!)
A message may be provided, which the failure string must
contain: #[should_panic(expected = "foo")].
`#[ignore]` - When applied to a function which is already attributed as a
test, then the test runner will ignore these tests during
normal test runs. Running with --ignored or --include-ignored will run
these tests.
Doc-tests adder
Usage: rustdoctest [OPTIONS] [FILTERS...]
Options:
--include-ignored
Run ignored and not ignored tests
--ignored Run only ignored tests
--force-run-in-process
Forces tests to run in-process when panic=abort
--exclude-should-panic
Excludes tests marked as should_panic
--test Run tests and not benchmarks
--bench Run benchmarks instead of tests
--list List all tests and benchmarks
-h, --help Display this message
--logfile PATH Write logs to the specified file (deprecated)
--nocapture don't capture stdout/stderr of each task, allow
printing directly
--test-threads n_threads
Number of threads used for running tests in parallel
--skip FILTER Skip tests whose names contain FILTER (this flag can
be used multiple times)
-q, --quiet Display one character per test instead of one line.
Alias to --format=terse
--exact Exactly match filters rather than by substring
--color auto|always|never
Configure coloring of output:
auto = colorize if stdout is a tty and tests are run
on serially (default);
always = always colorize output;
never = never colorize output;
--format pretty|terse|json|junit
Configure formatting of output:
pretty = Print verbose output;
terse = Display one character per test;
json = Output a json document;
junit = Output a JUnit document
--show-output Show captured stdout of successful tests
-Z unstable-options Enable nightly-only flags:
unstable-options = Allow use of experimental features
--report-time Show execution time of each test.
Threshold values for colorized output can be
configured via
`RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
and
`RUST_TEST_TIME_DOCTEST` environment variables.
Expected format of environment variable is
`VARIABLE=WARN_TIME,CRITICAL_TIME`.
Durations must be specified in milliseconds, e.g.
`500,2000` means that the warn time
is 0.5 seconds, and the critical time is 2 seconds.
Not available for --format=terse
--ensure-time Treat excess of the test execution time limit as
error.
Threshold values for this option can be configured via
`RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
and
`RUST_TEST_TIME_DOCTEST` environment variables.
Expected format of environment variable is
`VARIABLE=WARN_TIME,CRITICAL_TIME`.
`CRITICAL_TIME` here means the limit that should not
be exceeded by test.
--shuffle Run tests in random order
--shuffle-seed SEED
Run tests in random order; seed the random number
generator with SEED
The FILTER string is tested against the name of all tests, and only those
tests whose names contain the filter are run. Multiple filter strings may
be passed, which will run all tests matching any of the filters.
By default, all tests are run in parallel. This can be altered with the
--test-threads flag or the RUST_TEST_THREADS environment variable when running
tests (set it to 1).
By default, the tests are run in alphabetical order. Use --shuffle or set
RUST_TEST_SHUFFLE to run the tests in random order. Pass the generated
"shuffle seed" to --shuffle-seed (or set RUST_TEST_SHUFFLE_SEED) to run the
tests in the same order again. Note that --shuffle and --shuffle-seed do not
affect whether the tests are run in parallel.
All tests have their standard output and standard error captured by default.
This can be overridden with the --nocapture flag or setting RUST_TEST_NOCAPTURE
environment variable to a value other than "0". Logging is not captured by default.
Test Attributes:
`#[test]` - Indicates a function is a test to be run. This function
takes no arguments.
`#[bench]` - Indicates a function is a benchmark to be run. This
function takes one argument (test::Bencher).
`#[should_panic]` - This function (also labeled with `#[test]`) will only pass if
the code causes a panic (an assertion failure or panic!)
A message may be provided, which the failure string must
contain: #[should_panic(expected = "foo")].
`#[ignore]` - When applied to a function which is already attributed as a
test, then the test runner will ignore these tests during
normal test runs. Running with --ignored or --include-ignored will run
these tests.
并行或连续运行测试
默认情况下测试使用线程并行运行,因此必须确保测试不依赖于彼此或任何共享状态。
如果不希望并行运行测试,或者希望对所使用的线程数进行更细粒度的控制,则可以将 --test-threads 标志和想要使用的线程数发送到测试二进制文件。请看下面的例子:
cargo test -- --test-threads=1
我们将测试线程的数量设置为 1,测试变成串行运行。
显示函数输出
默认情况下,如果测试通过,Rust 的测试库将捕获打印到标准输出的所有内容。
如果我们在测试中调用 println!,测试通过了,我们将只看到表示测试通过的那一行,不会看到输出。如果测试失败,我们将看到打印到标准输出的内容以及失败消息的其余部分。
示例:
fn prints_and_returns_10(a: i32) -> i32 {
println!("I got the value {a}");
10
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn this_test_will_pass() {
let value = prints_and_returns_10(4);
assert_eq!(value, 10);
}
#[test]
fn this_test_will_fail() {
let value = prints_and_returns_10(8);
assert_eq!(value, 5);
}
}
运行 cargo test,我们看到只有在测试失败时,才会打印 prints_and_returns_10 函数中的输出。在测试成功时,输出被测试捕获,不打印。
如果我们也想看到通过测试的打印值,我们可以告诉 Rust 也显示成功测试的输出,使用 --show-output:
cargo test -- --show-output
按名称运行测试的子集
将要运行的测试的名称传递给 cargo test 作为参数,可以指定测试函数。
示例:
pub fn add_two(a: usize) -> usize {
a + 2
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_two_and_two() {
let result = add_two(2);
assert_eq!(result, 4);
}
#[test]
fn add_three_and_two() {
let result = add_two(3);
assert_eq!(result, 5);
}
#[test]
fn one_hundred() {
let result = add_two(100);
assert_eq!(result, 102);
}
}
我们可以将任何一个测试函数的名称传递给 cargo test,只运行该测试:
我们不能以这种方式指定多个测试的名称,但可以指定测试名称的一部分,并且任何名称与该值匹配的测试都将运行。例如,由于我们的两个测试的名称包含 add,我们可以通过运行 cargo test add 来运行这两个测试:
示例:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
#[test]
#[ignore]
fn expensive_test() {
// code that takes an hour to run
}
}
除非特别要求,否则忽略某些测试
有时,执行一些特定的测试可能非常耗时,可以使用 ignore 属性进行注释以排除它们,如下所示:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
#[test]
#[ignore]
fn expensive_test() {
// code that takes an hour to run
}
}
在 #[test] 之后,向想要排除的测试添加 #[ignore] 行。
如果我们只想运行被忽略的测试,可以使用:
cargo test -- --ignored
如果要运行所有测试,无论它们是否被忽略,可以运行:
cargo test -- --include-ignored