gurke 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2311a29357e984f6868342e33b6521a51c7697774155d061090b21484a446a8
4
- data.tar.gz: 314bc36b51bd2236407ea0489679edca0aaa78ce47a2870348557a73a66637d1
3
+ metadata.gz: 0dfc9f938d485d50f5e8ac6f3d7c978b2cb9266f478bf8a8e1a29d186e043164
4
+ data.tar.gz: 27ef19f2031a73e0cf4105b69587ee088f3bb17f8f74305dc2b5dad09e282d44
5
5
  SHA512:
6
- metadata.gz: d658e154b2d261d8b4a529f8f7d6b474e8519a042e15808cdc8492a2084c4d0ffa1020cf997ef4900c33a79200cc31886024905da3725038f217b6c362241372
7
- data.tar.gz: 2d2ec2d30909f5b6b3f2673cdb079ef2342c50f9cf7bdf9d9f40e62d022ab08d1570ec4f22212a7c337f9e8bcdef277dd4c862a701d923a4644e10d4cb68ed03
6
+ metadata.gz: 49a9f970050511d4946669c040dc37ba2d303a76184518a34ec7ecc74e2f129bbbff321e15bf167220cc4ec3542d13a4051fa95fa2bc3db74d8fc229b5a3fdf1
7
+ data.tar.gz: b46d5a895d606a0b772f96cd293ef27f2d62529516ffa5950036682eacb45882a3374bed01f4af41fd6d132386d1e6b8d69c53c715c3fd2f7c33fb388683eedf
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.2.0
4
+
5
+ * Add @flaky tag support for retrying flaky scenarios once
6
+
3
7
  ## 3.1.0
4
8
 
5
9
  * Update TeamCity formatter to extend default formatter
data/README.md CHANGED
@@ -162,6 +162,20 @@ If you append one or more line numbers - separated by colons - only the scenario
162
162
  gurke features/my_feature.feature:14:34
163
163
  ```
164
164
 
165
+ ### Flaky scenarios
166
+
167
+ If you have scenarios that might fail sometime, you can mark them as `@flaky`:
168
+
169
+ ```
170
+ Feature: F
171
+ @flaky
172
+ Scenario: I am flaky
173
+ Given I fail the first time
174
+ Then I will be retried a second time
175
+ ```
176
+
177
+ Gurke will retry a marked scenario only once if a step failed.
178
+
165
179
  ### DRb background server (experimental)
166
180
 
167
181
  You can run a DRb server in the background that has a running test environment (whatever that means to you) by running `gurke --drb-server`. This will load your test environment and execute all before `:system` hooks.
@@ -0,0 +1,70 @@
1
+ Feature: Pending Steps
2
+ In order to fail less often with flaky scenarios
3
+ As a CI administrator and tester
4
+ I want to have marked scenarios retried once
5
+
6
+ Background:
7
+ Given a file "features/support/steps/test_steps.rb" with the following content exists
8
+ """
9
+ $try = 0
10
+
11
+ module TestSteps
12
+ step("I fail the first time") do
13
+ fail 'first time' if ($try += 1) < 2
14
+ end
15
+
16
+ step("I fail always") do
17
+ fail 'always'
18
+ end
19
+
20
+ step("I do not fail") do
21
+ # noop
22
+ end
23
+ end
24
+
25
+ Gurke.configure{|c| c.include TestSteps }
26
+ """
27
+
28
+ Scenario: Run a flaky scenario
29
+ Given a file "features/test.feature" with the following content exists
30
+ """
31
+ Feature: F
32
+ @flaky
33
+ Scenario: Scenario Failure
34
+ Given I fail the first time
35
+ """
36
+ When I run the tests
37
+ Then the program exit code should be null
38
+ And the program output should include "Given I fail the first time (failure)"
39
+ And the program output should include "Given I fail the first time (passed)"
40
+ And the program output should include "Retry flaky scenario due to previous failure:"
41
+ And the program output should include "1 scenarios: 0 failing, 0 pending"
42
+
43
+ Scenario: Run a marked but always failing scenario
44
+ Given a file "features/test.feature" with the following content exists
45
+ """
46
+ Feature: F
47
+ @flaky
48
+ Scenario: Scenario Failure
49
+ Given I fail always
50
+ """
51
+ When I run the tests
52
+ Then the program exit code should be non-null
53
+ And the program output should include "Given I fail always (failure)"
54
+ And the program output should include "Retry flaky scenario due to previous failure:"
55
+ And the program output should not include "Given I fail always (passed)"
56
+ And the program output should include "1 scenarios: 1 failing, 0 pending"
57
+
58
+ Scenario: Run a marked but passing scenario
59
+ Given a file "features/test.feature" with the following content exists
60
+ """
61
+ Feature: F
62
+ @flaky
63
+ Scenario: Scenario Failure
64
+ Given I do not fail
65
+ """
66
+ When I run the tests
67
+ Then the program exit code should be null
68
+ And the program output should include "Given I do not fail (passed)"
69
+ And the program output should not include "Retry flaky scenario due to previous failure:"
70
+ And the program output should include "1 scenarios: 0 failing, 0 pending"
@@ -30,6 +30,8 @@ module Gurke
30
30
  after_feature
31
31
  after_scenario
32
32
  after_step
33
+
34
+ retry_scenario
33
35
  ].freeze
34
36
 
35
37
  # Called before the execution of any feature and before any
@@ -194,6 +196,17 @@ module Gurke
194
196
  "#{self.class.name}#end_scenario must be implemented in subclass."
195
197
  end
196
198
 
199
+ # Called when a flaky scenario is retried.
200
+ #
201
+ # @param scenario [Scenario] Current scenario.
202
+ #
203
+ # @api public
204
+ #
205
+ def retry_scenario(_scenario)
206
+ raise NotImplementedError.new \
207
+ "#{self.class.name}#retry_scenario must be implemented in subclass."
208
+ end
209
+
197
210
  # Called after each scenario and after all hooks.
198
211
  #
199
212
  # @param scenario [Scenario] Current scenario.
@@ -73,6 +73,10 @@ module Gurke::Reporters
73
73
  io.flush
74
74
  end
75
75
 
76
+ def retry_scenario(*)
77
+ io.print " Retry flaky scenario due to previous failure:\n"
78
+ end
79
+
76
80
  def after_scenario(*)
77
81
  io.puts
78
82
  end
@@ -14,12 +14,19 @@ module Gurke::Reporters
14
14
 
15
15
  def before_scenario(scenario)
16
16
  @status_reported = false
17
+ @retry = false
17
18
 
18
19
  publish :testStarted, name: scenario.name
19
20
 
20
21
  super
21
22
  end
22
23
 
24
+ def retry_scenario(scenario)
25
+ @retry = true
26
+
27
+ super
28
+ end
29
+
23
30
  def after_scenario(scenario)
24
31
  publish :testFinished, name: scenario.name
25
32
 
@@ -45,10 +52,13 @@ module Gurke::Reporters
45
52
  def step_failed(step, *args)
46
53
  super(step, *args, exception: false)
47
54
 
48
- report :testFailed,
49
- name: step.scenario.name,
50
- message: step.exception.inspect,
51
- backtrace: step.exception.backtrace.join('\n')
55
+ unless step.scenario.retryable? && !retry?
56
+ # do not report test as failed if it will be retries
57
+ report :testFailed,
58
+ name: step.scenario.name,
59
+ message: step.exception.inspect,
60
+ backtrace: step.exception.backtrace.join('\n')
61
+ end
52
62
 
53
63
  print_exception(step.exception)
54
64
  end
@@ -59,6 +69,10 @@ module Gurke::Reporters
59
69
  @status_reported
60
70
  end
61
71
 
72
+ def retry?
73
+ @retry
74
+ end
75
+
62
76
  def report(*args)
63
77
  return if status_reported?
64
78
 
@@ -136,6 +136,10 @@ module Gurke
136
136
  @state = :pending
137
137
  end
138
138
 
139
+ def retryable?
140
+ @tags.any? {|t| t.name == 'flaky' }
141
+ end
142
+
139
143
  # @api private
140
144
  #
141
145
  def passed!
@@ -158,12 +162,26 @@ module Gurke
158
162
  runner.hook :scenario, self, world do
159
163
  run_scenario runner, reporter
160
164
  end
165
+
166
+ if failed? && retryable?
167
+ reporter.invoke :retry_scenario, self
168
+ reset!
169
+
170
+ runner.hook :scenario, self, world do
171
+ run_scenario runner, reporter
172
+ end
173
+ end
161
174
  ensure
162
175
  reporter.invoke :after_scenario, self
163
176
  end
164
177
 
165
178
  private
166
179
 
180
+ def reset!
181
+ @state = nil
182
+ @exception = nil
183
+ end
184
+
167
185
  def run_scenario(runner, reporter)
168
186
  reporter.invoke :start_scenario, self
169
187
 
@@ -3,7 +3,7 @@
3
3
  module Gurke
4
4
  module VERSION
5
5
  MAJOR = 3
6
- MINOR = 1
6
+ MINOR = 2
7
7
  PATCH = 0
8
8
  STAGE = nil
9
9
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.').freeze
@@ -159,6 +159,19 @@ RSpec.describe Gurke::Reporters::DefaultReporter do
159
159
  end
160
160
  end
161
161
 
162
+ describe '#retry_scenario' do
163
+ let(:scenario) { double('scenario') }
164
+
165
+ subject { reporter.retry_scenario(scenario); super() }
166
+
167
+ it do
168
+ is_expected.to eq unindent <<~TEXT
169
+ . Retry flaky scenario due to previous failure:
170
+ .
171
+ TEXT
172
+ end
173
+ end
174
+
162
175
  describe '#after_scenario' do
163
176
  let(:scenario) { double('scenario') }
164
177
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gurke
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-26 00:00:00.000000000 Z
11
+ date: 2018-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -86,6 +86,7 @@ files:
86
86
  - features/gurke/include_by_tags.feature
87
87
  - features/gurke/other_reporter.feature
88
88
  - features/gurke/pending_steps.feature
89
+ - features/gurke/retry_scenario.feature
89
90
  - features/gurke/run_specific_directories.feature
90
91
  - features/gurke/run_specific_scenarios.feature
91
92
  - features/gurke/step_specific_definitions.feature
@@ -154,6 +155,7 @@ test_files:
154
155
  - features/gurke/include_by_tags.feature
155
156
  - features/gurke/other_reporter.feature
156
157
  - features/gurke/pending_steps.feature
158
+ - features/gurke/retry_scenario.feature
157
159
  - features/gurke/run_specific_directories.feature
158
160
  - features/gurke/run_specific_scenarios.feature
159
161
  - features/gurke/step_specific_definitions.feature