From e2e1a1fd801758e245ef4f238eaaf1205aba1178 Mon Sep 17 00:00:00 2001 From: makicamel Date: Wed, 10 Jul 2024 08:53:58 +0900 Subject: [PATCH] Omit redandunt execution with rspec --bisect Since bisect is a command that finds minimum repro that fails depending on the order, examples after the last failure example doesn't need to be executed. --- lib/rspec/core/bisect/example_minimizer.rb | 5 +- spec/rspec/core/bisect/coordinator_spec.rb | 53 +++++++--------------- 2 files changed, 20 insertions(+), 38 deletions(-) diff --git a/lib/rspec/core/bisect/example_minimizer.rb b/lib/rspec/core/bisect/example_minimizer.rb index e53ca82db8..67102cd2c6 100644 --- a/lib/rspec/core/bisect/example_minimizer.rb +++ b/lib/rspec/core/bisect/example_minimizer.rb @@ -132,7 +132,10 @@ def prep end def non_failing_example_ids - @non_failing_example_ids ||= all_example_ids - failed_example_ids + return @non_failing_example_ids if defined?(@non_failing_example_ids) + + last_failed_example_id_index = all_example_ids.rindex(failed_example_ids.last) + @non_failing_example_ids = all_example_ids[0..last_failed_example_id_index] - failed_example_ids end def get_expected_failures_for?(ids) diff --git a/spec/rspec/core/bisect/coordinator_spec.rb b/spec/rspec/core/bisect/coordinator_spec.rb index 3a678c12d8..3e002c85cb 100644 --- a/spec/rspec/core/bisect/coordinator_spec.rb +++ b/spec/rspec/core/bisect/coordinator_spec.rb @@ -29,13 +29,12 @@ def find_minimal_repro(output, formatter=Formatters::BisectProgressFormatter, bi expect(output).to eq(<<-EOS.gsub(/^\s+\|/, '')) |Bisect started using options: "" |Running suite to find failures... (n.nnnn seconds) - |Starting bisect with 2 failing examples and 6 non-failing examples. + |Starting bisect with 2 failing examples and 3 non-failing examples. |Checking that failure(s) are order-dependent... failure appears to be order-dependent | - |Round 1: bisecting over non-failing examples 1-6 .. ignoring examples 4-6 (n.nnnn seconds) - |Round 2: bisecting over non-failing examples 1-3 .. multiple culprits detected - splitting candidates (n.nnnn seconds) - |Round 3: bisecting over non-failing examples 1-2 .. ignoring example 2 (n.nnnn seconds) - |Bisect complete! Reduced necessary non-failing examples from 6 to 2 in n.nnnn seconds. + |Round 1: bisecting over non-failing examples 1-3 .. multiple culprits detected - splitting candidates (n.nnnn seconds) + |Round 2: bisecting over non-failing examples 1-2 .. ignoring example 2 (n.nnnn seconds) + |Bisect complete! Reduced necessary non-failing examples from 3 to 2 in n.nnnn seconds. | |The minimal reproduction command is: | rspec 1.rb[1:1] 2.rb[1:1] 4.rb[1:1] 5.rb[1:1] @@ -54,32 +53,18 @@ def find_minimal_repro(output, formatter=Formatters::BisectProgressFormatter, bi | - Failing examples (2): | - 2.rb[1:1] | - 5.rb[1:1] - | - Non-failing examples (6): + | - Non-failing examples (3): | - 1.rb[1:1] | - 3.rb[1:1] | - 4.rb[1:1] - | - 6.rb[1:1] - | - 7.rb[1:1] - | - 8.rb[1:1] |Checking that failure(s) are order-dependent.. | - Running: rspec 2.rb[1:1] 5.rb[1:1] (n.nnnn seconds) | - Failure appears to be order-dependent - |Round 1: bisecting over non-failing examples 1-6 - | - Running: rspec 2.rb[1:1] 5.rb[1:1] 6.rb[1:1] 7.rb[1:1] 8.rb[1:1] (n.nnnn seconds) - | - Running: rspec 1.rb[1:1] 2.rb[1:1] 3.rb[1:1] 4.rb[1:1] 5.rb[1:1] (n.nnnn seconds) - | - Examples we can safely ignore (3): - | - 6.rb[1:1] - | - 7.rb[1:1] - | - 8.rb[1:1] - | - Remaining non-failing examples (3): - | - 1.rb[1:1] - | - 3.rb[1:1] - | - 4.rb[1:1] - |Round 2: bisecting over non-failing examples 1-3 + |Round 1: bisecting over non-failing examples 1-3 | - Running: rspec 2.rb[1:1] 4.rb[1:1] 5.rb[1:1] (n.nnnn seconds) | - Running: rspec 1.rb[1:1] 2.rb[1:1] 3.rb[1:1] 5.rb[1:1] (n.nnnn seconds) | - Multiple culprits detected - splitting candidates - |Round 3: bisecting over non-failing examples 1-2 + |Round 2: bisecting over non-failing examples 1-2 | - Running: rspec 2.rb[1:1] 3.rb[1:1] 4.rb[1:1] 5.rb[1:1] (n.nnnn seconds) | - Running: rspec 1.rb[1:1] 2.rb[1:1] 4.rb[1:1] 5.rb[1:1] (n.nnnn seconds) | - Examples we can safely ignore (1): @@ -87,7 +72,7 @@ def find_minimal_repro(output, formatter=Formatters::BisectProgressFormatter, bi | - Remaining non-failing examples (2): | - 1.rb[1:1] | - 4.rb[1:1] - |Bisect complete! Reduced necessary non-failing examples from 6 to 2 in n.nnnn seconds. + |Bisect complete! Reduced necessary non-failing examples from 3 to 2 in n.nnnn seconds. | |The minimal reproduction command is: | rspec 1.rb[1:1] 2.rb[1:1] 4.rb[1:1] 5.rb[1:1] @@ -105,10 +90,10 @@ def find_minimal_repro(output, formatter=Formatters::BisectProgressFormatter, bi expect(output).to eq(<<-EOS.gsub(/^\s+\|/, '')) |Bisect started using options: "" |Running suite to find failures... (n.nnnn seconds) - |Starting bisect with 1 failing example and 7 non-failing examples. + |Starting bisect with 1 failing example and 1 non-failing example. |Checking that failure(s) are order-dependent... failure(s) do not require any non-failures to run first | - |Bisect complete! Reduced necessary non-failing examples from 7 to 0 in n.nnnn seconds. + |Bisect complete! Reduced necessary non-failing examples from 1 to 0 in n.nnnn seconds. | |The minimal reproduction command is: | rspec 2.rb[1:1] @@ -125,7 +110,7 @@ def find_minimal_repro(output, formatter=Formatters::BisectProgressFormatter, bi expect(output).to eq(<<-EOS.gsub(/^\s+\|/, '')) |Bisect started using options: "" |Running suite to find failures... (n.nnnn seconds) - |Starting bisect with 1 failing example and 7 non-failing examples. + |Starting bisect with 1 failing example and 1 non-failing example. |Checking that failure(s) are order-dependent... failure(s) do not require any non-failures to run first | |================================================================================ @@ -135,7 +120,7 @@ def find_minimal_repro(output, formatter=Formatters::BisectProgressFormatter, bi |is unexpected, consider setting `config.bisect_runner = :shell` and trying again. |================================================================================ | - |Bisect complete! Reduced necessary non-failing examples from 7 to 0 in n.nnnn seconds. + |Bisect complete! Reduced necessary non-failing examples from 1 to 0 in n.nnnn seconds. | |The minimal reproduction command is: | rspec 2.rb[1:1] @@ -154,18 +139,12 @@ def find_minimal_repro(output, formatter=Formatters::BisectProgressFormatter, bi |Running suite to find failures... (n.nnnn seconds) | - Failing examples (1): | - 2.rb[1:1] - | - Non-failing examples (7): + | - Non-failing examples (1): | - 1.rb[1:1] - | - 3.rb[1:1] - | - 4.rb[1:1] - | - 5.rb[1:1] - | - 6.rb[1:1] - | - 7.rb[1:1] - | - 8.rb[1:1] |Checking that failure(s) are order-dependent.. | - Running: rspec 2.rb[1:1] (n.nnnn seconds) | - Failure is not order-dependent - |Bisect complete! Reduced necessary non-failing examples from 7 to 0 in n.nnnn seconds. + |Bisect complete! Reduced necessary non-failing examples from 1 to 0 in n.nnnn seconds. | |The minimal reproduction command is: | rspec 2.rb[1:1] @@ -207,10 +186,10 @@ def bisect_round_started(notification) expect(output).to eq(<<-EOS.gsub(/^\s+\|/, '')) |Bisect started using options: "" |Running suite to find failures... (n.nnnn seconds) - |Starting bisect with 2 failing examples and 6 non-failing examples. + |Starting bisect with 2 failing examples and 3 non-failing examples. |Checking that failure(s) are order-dependent... failure appears to be order-dependent | - |Round 1: bisecting over non-failing examples 1-6 .. ignoring examples 4-6 (n.nnnn seconds) + |Round 1: bisecting over non-failing examples 1-3 .. multiple culprits detected - splitting candidates (n.nnnn seconds) | |Bisect aborted! |