BioErrorLog Tech Blog

試行錯誤の記録

cargo testでprintを表示する | Rust

cargo testでprint結果を表示する方法を整理します。

はじめに

こんにちは、@bioerrorlogです。

cargo testは、デフォルトではprintln!等のprint結果が表示されません。

今回は、cargo testでprint結果を表示する方法の備忘録を書きます。

# 作業環境
$ cargo --version
cargo 1.59.0 (49d8809dc 2022-02-10)

cargo testでprint結果を表示する

やり方

cargo test -- --nocapture

上記のように、-- --nocaptureを付与することでprint結果を表示することができます。

ここで--nocaptureの前には--が必要です。 一見奇妙なオプションの渡し方ですね。

少し読み解いてみます。

コマンド読み解き

まずこの--が何者なのか、--helpから調べてみます。

$ cargo test --help
cargo-test 
Execute all unit and integration tests and build examples of a local package

USAGE:
    cargo test [OPTIONS] [TESTNAME] [-- <args>...]

OPTIONS:
    -q, --quiet                      Display one character per test instead of one line
        --lib                        Test only this package's library unit tests
        --bin <NAME>...              Test only the specified binary
        --bins                       Test all binaries
        --example <NAME>...          Test only the specified example
        --examples                   Test all examples
        --test <NAME>...             Test only the specified test target
        --tests                      Test all tests
        --bench <NAME>...            Test only the specified bench target
        --benches                    Test all benches
        --all-targets                Test all targets
        --doc                        Test only this library's documentation
        --no-run                     Compile, but don't run tests
        --no-fail-fast               Run all tests regardless of failure
    -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)
    -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
        --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
        --target <TRIPLE>...         Build for the target triple
        --target-dir <DIRECTORY>     Directory for all generated artifacts
        --manifest-path <PATH>       Path to Cargo.toml
        --ignore-rust-version        Ignore `rust-version` specification in packages
        --message-format <FMT>...    Error format
        --unit-graph                 Output build graph in JSON (unstable)
        --future-incompat-report     Outputs a future incompatibility report at the end of the build
    -v, --verbose                    Use verbose output (-vv very verbose/build.rs output)
        --color <WHEN>               Coloring: auto, always, never
        --frozen                     Require Cargo.lock and cache are up to date
        --locked                     Require Cargo.lock is up to date
        --offline                    Run without accessing the network
        --config <KEY=VALUE>...      Override a configuration value (unstable)
    -Z <FLAG>...                     Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
    -h, --help                       Prints help information

ARGS:
    <TESTNAME>    If specified, only run tests containing this string in their names
    <args>...     Arguments for the test binary

Run `cargo help test` for more detailed information.
Run `cargo test -- --help` for test binary options.

重要な部分を抜粋します。

USAGE:
    cargo test [OPTIONS] [TESTNAME] [-- <args>...]
# 中略
ARGS:
    <TESTNAME>    If specified, only run tests containing this string in their names
    <args>...     Arguments for the test binary

--の後に続く文字列は、Arguments for the test binaryテストバイナリへの引数として渡される、と書いてありますね。

では次に、テストバイナリのオプションを見てみましょう。

上記のhelp末尾にRun cargo test -- --help for test binary options.とあるので、これに従います。

$ cargo test -- --help
# 中略
Usage: --help [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
        --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 [plain|colored]
                        Show execution time of each test. Available values:
                        plain = do not colorize the execution time (default);
                        colored = colorize output according to the `color`
                        parameter value;
                        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
# 以下略

--nocaptureの記述を見つけました。 抜粋します。

        --nocapture     don't capture stdout/stderr of each task, allow
                        printing directly

stdout/stderrをキャプチャせずに表示させる、とあります。 これこそまさに今回やりたいことです。

以上、まとめます。

  • --の後に続く値はテストバイナリへの引数として渡される
  • テストバイナリオプション--nocaptureは、stdout/stderrをキャプチャせずに表示させるオプション

おわりに

今回はcargo testでprint結果を表示する方法を整理し、その独特なコマンドオプションの渡し方を読み解きました。

Testでprint結果を表示したい、というちょっとした要望から、なかなか面白いコマンドオプションの渡し方に触れることが出来ました。

日頃の小さな課題も、深堀ってみるとなかなかに面白いものです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

参考

Why doesn't println! work in Rust unit tests? - Stack Overflow

`cargo test --nocapture` no longer works after docopts landing · Issue #296 · rust-lang/cargo · GitHub