From 3ad01b100fefbc3c6ef37ddba204008fb7119779 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 14 Aug 2025 16:36:58 -0500 Subject: [PATCH 1/2] test: Show behavior without --fail-fast --- .../tests/testsuite/mixed_bag.rs | 186 ++++++++++++++++++ crates/libtest2/tests/testsuite/mixed_bag.rs | 186 ++++++++++++++++++ 2 files changed, 372 insertions(+) diff --git a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs index ffce1f1..fcbcd84 100644 --- a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs @@ -1012,6 +1012,192 @@ failures: test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in [..]s +"#]], + ); +} + +#[test] +fn fail_fast() { + check( + &[], + 101, + str![[r#" + +running 8 tests +test bear ... ignored +test bunny ... ignored +test cat ... ok +test dog ... FAILED +test fly ... ignored +test fox ... ok +test frog ... ignored +test owl ... ignored + +failures: + +---- dog ---- +was not a good boy + + +failures: + dog + +test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in [..]s + + +"#]], + str![[r#" +... + +"#]], + ); +} + +#[test] +#[cfg(feature = "json")] +fn fail_fast_json() { + check( + &["-Zunstable-options", "--format=json"], + 101, + str![[r#" +[ + { + "event": "discover_start" + }, + { + "event": "discover_case", + "name": "bear" + }, + { + "event": "discover_case", + "name": "bunny" + }, + { + "event": "discover_case", + "name": "cat" + }, + { + "event": "discover_case", + "name": "dog" + }, + { + "event": "discover_case", + "name": "fly" + }, + { + "event": "discover_case", + "name": "fox" + }, + { + "event": "discover_case", + "name": "frog" + }, + { + "event": "discover_case", + "name": "owl" + }, + { + "elapsed_s": "[..]", + "event": "discover_complete" + }, + { + "event": "suite_start" + }, + { + "event": "case_start", + "name": "bear" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "bear", + "status": "ignored" + }, + { + "event": "case_start", + "name": "bunny" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "bunny", + "status": "ignored" + }, + { + "event": "case_start", + "name": "cat" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "name": "cat" + }, + { + "event": "case_start", + "name": "dog" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "was not a good boy", + "name": "dog", + "status": "failed" + }, + { + "event": "case_start", + "name": "fly" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "fly", + "status": "ignored" + }, + { + "event": "case_start", + "name": "fox" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "name": "fox" + }, + { + "event": "case_start", + "name": "frog" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "slow", + "name": "frog", + "status": "ignored" + }, + { + "event": "case_start", + "name": "owl" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "owl", + "status": "ignored" + }, + { + "elapsed_s": "[..]", + "event": "suite_complete" + } +] +"#]] + .is_json() + .against_jsonlines(), + str![[r#" +... + "#]], ); } diff --git a/crates/libtest2/tests/testsuite/mixed_bag.rs b/crates/libtest2/tests/testsuite/mixed_bag.rs index 89e8c17..2ab0255 100644 --- a/crates/libtest2/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2/tests/testsuite/mixed_bag.rs @@ -1019,6 +1019,192 @@ failures: test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in [..]s +"#]], + ); +} + +#[test] +fn fail_fast() { + check( + &[], + 101, + str![[r#" + +running 8 tests +test bear ... ignored +test bunny ... ignored +test cat ... ok +test dog ... FAILED +test fly ... ignored +test fox ... ok +test frog ... ignored +test owl ... ignored + +failures: + +---- dog ---- +was not a good boy + + +failures: + dog + +test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in [..]s + + +"#]], + str![[r#" +... + +"#]], + ); +} + +#[test] +#[cfg(feature = "json")] +fn fail_fast_json() { + check( + &["-Zunstable-options", "--format=json"], + 101, + str![[r#" +[ + { + "event": "discover_start" + }, + { + "event": "discover_case", + "name": "bear" + }, + { + "event": "discover_case", + "name": "bunny" + }, + { + "event": "discover_case", + "name": "cat" + }, + { + "event": "discover_case", + "name": "dog" + }, + { + "event": "discover_case", + "name": "fly" + }, + { + "event": "discover_case", + "name": "fox" + }, + { + "event": "discover_case", + "name": "frog" + }, + { + "event": "discover_case", + "name": "owl" + }, + { + "elapsed_s": "[..]", + "event": "discover_complete" + }, + { + "event": "suite_start" + }, + { + "event": "case_start", + "name": "bear" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "bear", + "status": "ignored" + }, + { + "event": "case_start", + "name": "bunny" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "bunny", + "status": "ignored" + }, + { + "event": "case_start", + "name": "cat" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "name": "cat" + }, + { + "event": "case_start", + "name": "dog" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "was not a good boy", + "name": "dog", + "status": "failed" + }, + { + "event": "case_start", + "name": "fly" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "fly", + "status": "ignored" + }, + { + "event": "case_start", + "name": "fox" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "name": "fox" + }, + { + "event": "case_start", + "name": "frog" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "slow", + "name": "frog", + "status": "ignored" + }, + { + "event": "case_start", + "name": "owl" + }, + { + "elapsed_s": "[..]", + "event": "case_complete", + "message": "fails", + "name": "owl", + "status": "ignored" + }, + { + "elapsed_s": "[..]", + "event": "suite_complete" + } +] +"#]] + .is_json() + .against_jsonlines(), + str![[r#" +... + "#]], ); } From b3f435a196f06ac2f40c963b5913ebb28d1e27ce Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 14 Aug 2025 16:25:44 -0500 Subject: [PATCH 2/2] feat(lexarg): Add --fail-fast flag See rust-lang/rust#142859 --- crates/libtest-lexarg/src/lib.rs | 4 ++ .../tests/testsuite/mixed_bag.rs | 52 ++----------------- crates/libtest2/tests/testsuite/mixed_bag.rs | 52 ++----------------- 3 files changed, 10 insertions(+), 98 deletions(-) diff --git a/crates/libtest-lexarg/src/lib.rs b/crates/libtest-lexarg/src/lib.rs index aeffd1e..3a402e4 100644 --- a/crates/libtest-lexarg/src/lib.rs +++ b/crates/libtest-lexarg/src/lib.rs @@ -108,6 +108,7 @@ Options: --ignored Run only ignored tests --include-ignored Run ignored and not ignored tests + --fail-fast Don't start new tests after the first failure --no-capture don't capture stdout/stderr of each task, allow printing directly --show-output Show captured stdout of successful tests @@ -221,6 +222,9 @@ impl TestOptsBuilder { Long("exact") => { self.opts.filter_exact = true; } + Long("fail-fast") => { + self.opts.fail_fast = true; + } Long("color") => { let color = parser .next_flag_value() diff --git a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs index fcbcd84..dc74494 100644 --- a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs @@ -1019,7 +1019,7 @@ test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in #[test] fn fail_fast() { check( - &[], + &["--fail-fast"], 101, str![[r#" @@ -1028,10 +1028,6 @@ test bear ... ignored test bunny ... ignored test cat ... ok test dog ... FAILED -test fly ... ignored -test fox ... ok -test frog ... ignored -test owl ... ignored failures: @@ -1042,7 +1038,7 @@ was not a good boy failures: dog -test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in [..]s +test result: FAILED. 1 passed; 1 failed; 2 ignored; 0 filtered out; finished in [..]s "#]], @@ -1057,7 +1053,7 @@ test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in #[cfg(feature = "json")] fn fail_fast_json() { check( - &["-Zunstable-options", "--format=json"], + &["-Zunstable-options", "--format=json", "--fail-fast"], 101, str![[r#" [ @@ -1145,48 +1141,6 @@ fn fail_fast_json() { "name": "dog", "status": "failed" }, - { - "event": "case_start", - "name": "fly" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "message": "fails", - "name": "fly", - "status": "ignored" - }, - { - "event": "case_start", - "name": "fox" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "name": "fox" - }, - { - "event": "case_start", - "name": "frog" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "message": "slow", - "name": "frog", - "status": "ignored" - }, - { - "event": "case_start", - "name": "owl" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "message": "fails", - "name": "owl", - "status": "ignored" - }, { "elapsed_s": "[..]", "event": "suite_complete" diff --git a/crates/libtest2/tests/testsuite/mixed_bag.rs b/crates/libtest2/tests/testsuite/mixed_bag.rs index 2ab0255..2f9cf64 100644 --- a/crates/libtest2/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2/tests/testsuite/mixed_bag.rs @@ -1026,7 +1026,7 @@ test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in #[test] fn fail_fast() { check( - &[], + &["--fail-fast"], 101, str![[r#" @@ -1035,10 +1035,6 @@ test bear ... ignored test bunny ... ignored test cat ... ok test dog ... FAILED -test fly ... ignored -test fox ... ok -test frog ... ignored -test owl ... ignored failures: @@ -1049,7 +1045,7 @@ was not a good boy failures: dog -test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in [..]s +test result: FAILED. 1 passed; 1 failed; 2 ignored; 0 filtered out; finished in [..]s "#]], @@ -1064,7 +1060,7 @@ test result: FAILED. 2 passed; 1 failed; 5 ignored; 0 filtered out; finished in #[cfg(feature = "json")] fn fail_fast_json() { check( - &["-Zunstable-options", "--format=json"], + &["-Zunstable-options", "--format=json", "--fail-fast"], 101, str![[r#" [ @@ -1152,48 +1148,6 @@ fn fail_fast_json() { "name": "dog", "status": "failed" }, - { - "event": "case_start", - "name": "fly" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "message": "fails", - "name": "fly", - "status": "ignored" - }, - { - "event": "case_start", - "name": "fox" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "name": "fox" - }, - { - "event": "case_start", - "name": "frog" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "message": "slow", - "name": "frog", - "status": "ignored" - }, - { - "event": "case_start", - "name": "owl" - }, - { - "elapsed_s": "[..]", - "event": "case_complete", - "message": "fails", - "name": "owl", - "status": "ignored" - }, { "elapsed_s": "[..]", "event": "suite_complete"