Skip to content

Commit

Permalink
Stop Quke from returning 0 exit status despite passing tests (#112)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/RUBY-1373

The default behaviour here is for Cucumber to exit as soon as a single test fails. We prefer to run the full suite each time, so these errors were being rescued.

However, this meant that if a test did fail, the exit status of the job would still be 0, which isn't what we want for our CI.

This PR changes the behaviour of Quke to record if a test fails, allow the test suite to proceed, and then throw the error at the end instead.

Cucumber will also call a SystemExit when the suite has finished running, or if there is some other problem with the suite. We don't want to consider the successful runs as errors or the suite will be considered "failed" every single time.
  • Loading branch information
irisfaraway authored Apr 26, 2021
1 parent 5f8ca23 commit 1f25016
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
7 changes: 6 additions & 1 deletion lib/quke.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

module Quke #:nodoc:

class QukeError < StandardError; end

# The main Quke class. It is not intended to be instantiated and instead
# just need to call its +execute+ method.
class Quke
Expand All @@ -28,7 +30,10 @@ class << self
# The entry point for Quke, it is the one call made by +exe/quke+.
def self.execute(args = [])
cuke = CukeRunner.new(args)
cuke.run
errors = cuke.run
return if errors.empty?

raise QukeError.new, "Number of failures or errors: #{errors.count}"
end

end
Expand Down
19 changes: 13 additions & 6 deletions lib/quke/cuke_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,19 @@ def initialize(passed_in_args = [])
# Executes Cucumber passing in the arguments array, which was set when the
# instance of CukeRunner was initialized.
def run
Cucumber::Cli::Main.new(@args).execute!
rescue SystemExit
# Cucumber calls @kernel.exit() killing your script unless you rescue
# If any tests fail cucumber will exit with an error code however this
# is expected and normal behaviour. We capture the exit to prevent it
# bubbling up to our app and closing it.
errors = []

begin
Cucumber::Cli::Main.new(@args).execute!
rescue SystemExit => e
# Cucumber calls @kernel.exit() whenever a test fails, or when the test
# suite has finished running. We prefer to run the full test suite every
# time, and then fail at the end. However if the SystemExit is a
# successful one, we don't want to log it as an error.
errors << e unless e.success?
end

errors
end

end
Expand Down
15 changes: 15 additions & 0 deletions spec/quke/quke_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,20 @@
end
end

context "when one of the tests throws a SystemError with status 1" do
before { expect(Cucumber::Cli::Main).to receive(:new).and_raise(SystemExit, 1) }

it "holds onto the errors and raises them at the end" do
expect { Quke::Quke.execute }.to raise_error(Quke::QukeError, "Number of failures or errors: 1")
end
end

context "when one of the tests throws a SystemError with status 0" do
before { expect(Cucumber::Cli::Main).to receive(:new).and_raise(SystemExit, 0) }

it "does not raise an error" do
expect { Quke::Quke.execute }.not_to raise_error
end
end
end
end

0 comments on commit 1f25016

Please sign in to comment.