Skip to main content

nextest_runner/config/elements/
report_skip_policy.rs

1// Copyright (c) The nextest Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use nextest_metadata::MismatchReason;
5use serde::{Deserialize, Serialize};
6
7/// Controls which skipped tests are emitted as `<testcase>` elements with a
8/// `<skipped>` child in machine-readable reports such as JUnit XML output.
9///
10/// Skipped tests are not emitted by default to keep machine-readable output
11/// stable. This setting opts in to reporting some or all of them.
12#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
13#[cfg_attr(feature = "config-schema", derive(schemars::JsonSchema))]
14#[serde(rename_all = "kebab-case")]
15#[cfg_attr(test, derive(test_strategy::Arbitrary))]
16pub enum ReportSkipPolicy {
17    /// Do not emit any skipped tests. This is the default and keeps
18    /// machine-readable output stable.
19    #[default]
20    None,
21
22    /// Only emit tests whose ignore status did not match the run's run-ignored
23    /// selection. In a default run these are the tests marked `#[ignore]`;
24    /// under `--run-ignored only` these are the tests that are not ignored.
25    Ignored,
26
27    /// Emit all skipped tests, regardless of why they were skipped, except
28    /// tests skipped because they are not benchmarks.
29    ///
30    /// Note: because filtered-out tests (for example, tests in a different
31    /// partition) are reported as skipped, using `all` with partitioned runs
32    /// causes each partition's report to contain the tests skipped in that
33    /// partition. Merging those reports will produce duplicate skipped entries.
34    All,
35}
36
37impl ReportSkipPolicy {
38    /// Returns true if a test skipped for the given reason should be reported
39    /// as a skipped test under this policy.
40    ///
41    /// Tests skipped because they are not benchmarks
42    /// ([`MismatchReason::NotBenchmark`]) are never reported.
43    pub fn should_report(self, reason: MismatchReason) -> bool {
44        match self {
45            ReportSkipPolicy::None => false,
46            ReportSkipPolicy::Ignored => reason.is_ignore_mismatch(),
47            ReportSkipPolicy::All => reason.is_substantive_skip(),
48        }
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn should_report_policy_behavior() {
58        assert!(!ReportSkipPolicy::None.should_report(MismatchReason::Ignored));
59        assert!(!ReportSkipPolicy::None.should_report(MismatchReason::DefaultFilter));
60        assert!(!ReportSkipPolicy::None.should_report(MismatchReason::NotBenchmark));
61
62        assert!(ReportSkipPolicy::Ignored.should_report(MismatchReason::Ignored));
63        assert!(!ReportSkipPolicy::Ignored.should_report(MismatchReason::DefaultFilter));
64        assert!(!ReportSkipPolicy::Ignored.should_report(MismatchReason::NotBenchmark));
65
66        assert!(ReportSkipPolicy::All.should_report(MismatchReason::Ignored));
67        assert!(ReportSkipPolicy::All.should_report(MismatchReason::DefaultFilter));
68        assert!(!ReportSkipPolicy::All.should_report(MismatchReason::NotBenchmark));
69    }
70
71    #[test]
72    fn should_report_mirrors_reason_predicates() {
73        for &reason in MismatchReason::ALL_VARIANTS {
74            assert!(
75                !ReportSkipPolicy::None.should_report(reason),
76                "None never reports {reason:?}"
77            );
78            assert_eq!(
79                ReportSkipPolicy::Ignored.should_report(reason),
80                reason.is_ignore_mismatch(),
81                "Ignored policy must mirror is_ignore_mismatch for {reason:?}"
82            );
83            assert_eq!(
84                ReportSkipPolicy::All.should_report(reason),
85                reason.is_substantive_skip(),
86                "All policy must mirror is_substantive_skip for {reason:?}"
87            );
88        }
89    }
90}