-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add BeforeAll and AfterAll hooks (#1569)
* Add a feature for BeforeAll hook * Add BeforeAll hook * Add an AfterAll_hook feature * Add AfterAll hook * Move all hook related features into a dedicated sub-folder * Add a scenario for AfterAll to make sure it is invoked even after failed scenario * [skip ci] Update CHANGELOG.md * Draft a documentation for hooks * Add some sugar to hooks README * Adlinks to new hooks documentation in CHANGELOG.md * Do not execute BeforeAll and AfterAll hooks in dry-run mode
- Loading branch information
1 parent
ce1ba5f
commit 1ecac46
Showing
14 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Cucumber Hooks | ||
|
||
Cucumber proposes several hooks to let you specify some code to be executed at | ||
different stages of test execution, like before or after the execution of a | ||
scenario. | ||
|
||
Hooks are part of your support code. | ||
|
||
They are executed in the following order: | ||
|
||
- [AfterConfiguration](#afterconfiguration-and-installplugin) | ||
- [InstallPlugin](#afterconfiguration-and-installplugin) | ||
- [BeforeAll](#beforeall-and-afterall) | ||
- Per scenario: | ||
- [Around](#around) | ||
- [Before](#before-and-after) | ||
- Per step: | ||
- [AfterStep](#afterstep) | ||
- [After](#before-and-after) | ||
- [AfterAll](#beforeall-and-afterall) | ||
|
||
You can define as many hooks as you want. If you have several hooks of the same | ||
types - for example, several `BeforeAll` hooks - they will be all executed once. | ||
|
||
Multiple hooks of the same type are executed in the order that they were defined. | ||
If you wish to control this order, use manual requires in `env.rb` - This file is | ||
loaded first - or migrate them all to one `hooks.rb` file. | ||
|
||
## AfterConfiguration and InstallPlugin | ||
|
||
[`AfterConfiguration`](#afterconfiguration) and [`InstallPlugin`](#installplugin) | ||
hooks are dedicated to plugins and are meant to extend Cucumber. For example, | ||
[`AfterConfiguration`](#afterconfiguration) allows you to dynamically change the | ||
configuration before the execution of the tests, and [`InstallPlugin`](#installplugin) | ||
allows to have some code that would have deeper impact on the execution. | ||
|
||
### AfterConfiguration | ||
|
||
**Note:** this is a legacy hook. You may consider using [`InstallPlugin`](#installplugin) instead. | ||
|
||
```ruby | ||
AfterConfiguration do |configuration| | ||
# configuration is an instance of Cucumber::Configuration defined in | ||
# lib/cucumber/configuration.rb. | ||
end | ||
``` | ||
|
||
### InstallPlugin | ||
|
||
In addition to the configuration, `InstallPlugin` also has access to some of Cucumber | ||
internals through a `RegistryWrapper`, defined in | ||
[lib/cucumber/glue/registry_wrapper.rb](../../../../lib/cucumber/glue/registry_wrapper.rb). | ||
|
||
```ruby | ||
InstallPlugin do |configuration, registry| | ||
# configuration is an instance of Cucumber::Configuration defined in | ||
# lib/cucumber/configuration.rb | ||
# | ||
# registry is an instance of Cucumber::Glue::RegistryWrapper defined in | ||
# lib/cucumber/glue/registry_wrapper.rb | ||
end | ||
``` | ||
|
||
You can see an example in the [Cucumber Wire plugin](https://github.com/cucumber/cucumber-ruby-wire). | ||
|
||
## BeforeAll and AfterAll | ||
|
||
`BeforeAll` is executed once before the execution of the first scenario. `AfterAll` | ||
is executed once after the execution of the last scenario. | ||
|
||
These two types of hooks have no parameters. Their purpose is to set-up and/or clean-up | ||
your environment not related to Cucumber, like a database or a browser. | ||
|
||
```ruby | ||
BeforeAll do | ||
# snip | ||
end | ||
|
||
AfterAll do | ||
# snip | ||
end | ||
``` | ||
|
||
## Around | ||
|
||
**Note:** `Around` is a legacy hook and its usage is discouraged in favor of | ||
[`Before` and `After`](#before-and-after) hooks. | ||
|
||
`Around` is a special hook which allows you to have a block syntax. Its original | ||
purpose was to support some databases with only block syntax for transactions. | ||
|
||
```ruby | ||
Around do |scenario, block| | ||
SomeDatabase::begin_transaction do # this is just for illustration | ||
block.call | ||
end | ||
end | ||
``` | ||
|
||
## Before and After | ||
|
||
`Before` is executed before each test case. `After` is executed after each test case. | ||
They both have the test case being executed as a parameter. Within the `After` hook, | ||
the status of the test case is also available. | ||
|
||
```ruby | ||
Before do |test_case| | ||
log test_case.name | ||
end | ||
|
||
After do |test_case| | ||
log test_case.failed? | ||
log test_case.status | ||
end | ||
``` | ||
|
||
## AfterStep | ||
|
||
`AfterStep` is executed after each step of a test. If steps are not executed due | ||
to a previous failure, `AfterStep` won't be executed either. | ||
|
||
```ruby | ||
AfterStep do |result, test_step| | ||
log test_step.inspect # test_step is a Cucumber::Core::Test::Step | ||
log result.inspect # result is a Cucumber::Core::Test::Result | ||
end | ||
``` |
80 changes: 80 additions & 0 deletions
80
features/docs/writing_support_code/hooks/after_all_hook.feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
Feature: AfterAll Hooks | ||
|
||
AfterAll hooks can be used if you have some clean-up to be done after all | ||
scenarios have been executed. | ||
|
||
Scenario: A single AfterAll hook | ||
|
||
An AfterAll hook will be invoked a single time after all the scenarios have | ||
been executed. | ||
|
||
Given a file named "features/f.feature" with: | ||
""" | ||
Feature: AfterAll hook | ||
Scenario: #1 | ||
Then the AfterAll hook has not been called yet | ||
Scenario: #2 | ||
Then the AfterAll hook has not been called yet | ||
""" | ||
And a file named "features/step_definitions/steps.rb" with: | ||
""" | ||
hookCalled = 0 | ||
AfterAll do | ||
hookCalled += 1 | ||
raise "AfterAll hook error has been raised" | ||
end | ||
Then /^the AfterAll hook has not been called yet$/ do | ||
expect(hookCalled).to eq 0 | ||
end | ||
""" | ||
When I run `cucumber features/f.feature --publish-quiet` | ||
Then it should fail with: | ||
""" | ||
Feature: AfterAll hook | ||
Scenario: #1 # features/f.feature:2 | ||
Then the AfterAll hook has not been called yet # features/step_definitions/steps.rb:9 | ||
Scenario: #2 # features/f.feature:5 | ||
Then the AfterAll hook has not been called yet # features/step_definitions/steps.rb:9 | ||
2 scenarios (2 passed) | ||
2 steps (2 passed) | ||
""" | ||
And the output should contain: | ||
""" | ||
AfterAll hook error has been raised (RuntimeError) | ||
""" | ||
|
||
Scenario: It is invoked also when scenario has failed | ||
|
||
Given a file named "features/f.feature" with: | ||
""" | ||
Feature: AfterAll hook | ||
Scenario: failed | ||
Given a failed step | ||
""" | ||
And a file named "features/step_definitions/steps.rb" with: | ||
""" | ||
AfterAll do | ||
raise "AfterAll hook error has been raised" | ||
end | ||
Given /^a failed step$/ do | ||
expect(0).to eq 1 | ||
end | ||
""" | ||
When I run `cucumber features/f.feature --publish-quiet` | ||
Then it should fail with: | ||
""" | ||
1 scenario (1 failed) | ||
1 step (1 failed) | ||
""" | ||
And the output should contain: | ||
""" | ||
AfterAll hook error has been raised (RuntimeError) | ||
""" |
File renamed without changes.
File renamed without changes.
File renamed without changes.
49 changes: 49 additions & 0 deletions
49
features/docs/writing_support_code/hooks/before_all_hook.feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
Feature: BeforeAll Hooks | ||
|
||
BeforeAll hooks can be used if you have some set-up to be done before all | ||
scenarios are executed. | ||
|
||
BeforeAll hooks are not aware of your configuration. Use AfterConfiguration if | ||
you need it. | ||
|
||
Scenario: A single BeforeAll hook | ||
|
||
A BeforeAll hook will be invoked a single time before all the scenarios are | ||
executed. | ||
|
||
Given a file named "features/f.feature" with: | ||
""" | ||
Feature: BeforeAll hook | ||
Scenario: #1 | ||
Then the BeforeAll hook has been called | ||
Scenario: #2 | ||
Then the BeforeAll hook has been called | ||
""" | ||
And a file named "features/step_definitions/steps.rb" with: | ||
""" | ||
hookCalled = 0 | ||
BeforeAll do | ||
hookCalled += 1 | ||
end | ||
Then /^the BeforeAll hook has been called$/ do | ||
expect(hookCalled).to eq 1 | ||
end | ||
""" | ||
When I run `cucumber features/f.feature` | ||
Then it should pass with: | ||
""" | ||
Feature: BeforeAll hook | ||
Scenario: #1 # features/f.feature:2 | ||
Then the BeforeAll hook has been called # features/step_definitions/steps.rb:7 | ||
Scenario: #2 # features/f.feature:5 | ||
Then the BeforeAll hook has been called # features/step_definitions/steps.rb:7 | ||
2 scenarios (2 passed) | ||
2 steps (2 passed) | ||
""" |
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters