You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* add export of cli --help
* dont need note about sync
* update world docs
* document retry
* document profiles
* start to trim stuff from cli
* more on profiles
* document parallel
* add linsk to readmr
Copy file name to clipboardExpand all lines: docs/cli.md
+4-25
Original file line number
Diff line number
Diff line change
@@ -122,25 +122,11 @@ Note that the rerun file parser can only work with the default separator for now
122
122
123
123
## Parallel
124
124
125
-
You can run your scenarios in parallel with `--parallel <NUMBER_OF_WORKERS>`. Each worker is run in a separate Node process and receives the following env variables (as well as a copy of `process.env` from the coordinator process):
126
-
127
-
*`CUCUMBER_PARALLEL` - set to 'true'
128
-
*`CUCUMBER_TOTAL_WORKERS` - set to the number of workers
129
-
*`CUCUMBER_WORKER_ID` - ID for worker ('0', '1', '2', etc.)
130
-
131
-
### Timing
132
-
133
-
When using parallel mode, the last line of the summary output differentiates between real time elapsed during the test run and aggregate time spent actually running steps:
134
-
135
-
```
136
-
73 scenarios (73 passed)
137
-
512 steps (512 passed)
138
-
0m51.627s (executing steps: 4m51.228s)
139
-
```
125
+
See [Parallel](./parallel.md).
140
126
141
127
## Profiles
142
128
143
-
In order to store and reuse commonly used CLI options, you can add a `cucumber.js` file to your project root directory. The file should export an object where the key is the profile name and the value is a string of CLI options. The profile can be applied with `-p <NAME>` or `--profile <NAME>`. This will prepend the profile's CLI options to the ones provided by the command line. Multiple profiles can be specified at a time. If no profile is specified and a profile named `default` exists, it will be applied.
129
+
See [Profiles](./profiles.md).
144
130
145
131
## Tags
146
132
@@ -157,8 +143,7 @@ A note on using in conjunction with `--retry`: we consider a test case to have f
157
143
158
144
## Retry failing tests
159
145
160
-
Use `--retry <int>` to rerun tests that have been failing. This can be very helpful for flaky tests.
161
-
To only retry failing tests in a subset of test use `--retry-tag-filter <EXPRESSION>` (use the same as in Use [Tags](#tags))
146
+
See [Retry](./retry.md)
162
147
163
148
## Transpilation
164
149
@@ -228,10 +213,4 @@ Note that the first `--require tests.setup.js` overrides the default require glo
228
213
229
214
## World Parameters
230
215
231
-
You can pass in parameters to pass to the world constructor with `--world-parameters <JSON>`. The JSON string must define an object. The parsed object will be passed as the `parameters` to the the world constructor. This option is repeatable and the objects will be merged with the last instance taking precedence.
Cucumber supports running scenarios in parallel. The main process becomes a "coordinator" and spins up several separate Node processes to be the "workers". You can enable this with the `--parallel <NUMBER_OF_WORKERS>` CLI option:
4
+
5
+
```shell
6
+
$ cucumber-js --parallel 3
7
+
```
8
+
9
+
The number you provide is the number of workers that will run scenarios in parallel.
10
+
11
+
Each worker receives the following env variables (as well as a copy of `process.env` from the coordinator process):
12
+
13
+
*`CUCUMBER_PARALLEL` - set to 'true'
14
+
*`CUCUMBER_TOTAL_WORKERS` - set to the number of workers
15
+
*`CUCUMBER_WORKER_ID` - ID for worker ('0', '1', '2', etc.)
16
+
17
+
### Timing
18
+
19
+
When using parallel mode, the last line of the summary output differentiates between real time elapsed during the test run and aggregate time spent actually running steps:
20
+
21
+
```
22
+
73 scenarios (73 passed)
23
+
512 steps (512 passed)
24
+
0m51.627s (executing steps: 4m51.228s)
25
+
```
26
+
27
+
### Hooks
28
+
29
+
When using parallel mode, any `BeforeAll` and `AfterAll` hooks you have defined will run _once per worker_.
If you have several permutations of running Cucumber with different CLI options in your project, it might be a bit cumbersome to manage. *Profiles* enable you to declare bundles of configuration and reference them with a single CLI option.
4
+
5
+
Let's take the common case of having some things a bit different locally vs in CI. Here's the command we've been running locally:
For argument's sake, we'll want these changes in CI:
12
+
13
+
- The URL for the app (maybe dynamically provisioned?)
14
+
- The formatters we want to use
15
+
16
+
To start using Profiles, we just need to create a `cucumber.js` file in our project's root. It's a simple JavaScript module that exports an object with profile names as keys and CLI options as values. We can lean on JavaScript to reduce duplication and grab things dynamically as needed. Here's what we might write to address the needs described above:
If you have a flaky scenario (e.g. failing 10% of the time for some reason), you can use *Retry* to have Cucumber attempt it multiple times until either it passes or the maximum number of attempts is reached. You enable this via the `--retry <MAXIMUM_RETRIES>` CLI option, like this:
4
+
5
+
```shell
6
+
$ cucumber-js --retry 1
7
+
```
8
+
9
+
The number you provide is the number of retries that will be allowed after an initial failure.
10
+
11
+
*Note:* Retry isn't recommended for routine use, but can be a good trade-off in some situations where you have a scenario that's too valuable to remove, but it's either not possible or not worth the effort to fix the flakiness.
12
+
13
+
Some notes on how Retry works:
14
+
15
+
- Only relevant failing scenarios are retried, not the whole test run.
16
+
- When a scenario is retried, it runs all hooks and steps again from the start with a fresh [World](./support_files/world.md) - nothing is retained from the failed attempt.
17
+
- When a scenario passes on a retry, it's treated as a pass overall in the results, although the details of each attempt are emitted so formatters can access them.
18
+
19
+
20
+
## Targeting scenarios
21
+
22
+
Using the `--retry` option alone would mean every scenario would be allowed multiple attempts - this almost certainly isn't what you want, assuming you have a small set of flaky scenarios. To target just the relevant scenarios, you can provide a [tag expression](https://cucumber.io/docs/cucumber/api/#tag-expressions) via the `--retry-tag-filter <TAG_EXPRESSION>` CLI option, like this:
Copy file name to clipboardExpand all lines: docs/support_files/world.md
+32-15
Original file line number
Diff line number
Diff line change
@@ -1,23 +1,41 @@
1
1
# World
2
2
3
-
*World* is an isolated context for each scenario, exposed to the hooks and steps as `this`.
4
-
The default world constructor is:
3
+
*World* is an isolated context for each scenario, exposed to the hooks and steps as `this`, enabling you to set and recall some state across the lifecycle of your scenario. A simple example:
5
4
6
5
```javascript
7
-
classWorld {
8
-
constructor({ attach, log, parameters }) {
9
-
this.attach= attach
10
-
this.log= log
11
-
this.parameters= parameters
12
-
}
13
-
}
6
+
const { When } =require('@cucumber/cucumber')
7
+
8
+
When('something happens', asyncfunction() {
9
+
this.foo='bar'
10
+
})
11
+
```
12
+
13
+
As well as being able to have arbitrary state, you get some helpers preset on the World for you:
14
+
15
+
*`this.attach`: function used for adding [attachments](./attachments.md) to hooks/steps
16
+
*`this.log`: function used for [logging](./attachments.md#logging) information from hooks/steps
17
+
*`this.parameters`: object of parameters passed in via the [CLI](../cli.md#world-parameters)
18
+
19
+
Some notes on the scope of World:
20
+
21
+
- It's scoped to a single scenario only - not shared globally between scenarios. This reinforces a Cucumber principle: that scenarios should work entirely independently of one another.
22
+
- If you're using [Retry](../retry.md), you'll get a fresh World for every attempt at your scenario, so state isn't retained between attempts.
23
+
24
+
## World Parameters
25
+
26
+
You might want to provide some configuration/environmental data to your World at runtime. You can provide this data as a JSON literal via the `--world-parameters` CLI option, like this:
*`attach`: function used for adding [attachments](./attachments.md) to hooks/steps
17
-
*`log`: function used for [logging](./attachments.md#logging) information from hooks/steps
18
-
*`parameters`: object of parameters passed in via the [CLI](../cli.md#world-parameters)
32
+
This option is repeatable, so you can use it multiple times and the objects will be merged with the later ones taking precedence.
19
33
20
-
You can provide your own World class with its own properties and methods that help with your instrumentation. You can extend the built-in `World` with your own class and then call `setWorldConstructor` with it:
34
+
This data is then available on `this.parameters` from your hooks and steps.
35
+
36
+
## Custom World
37
+
38
+
You might also want to have methods on your World that hooks and steps can access to keep their own code simple. To do this, you can provide your own World class with its own properties and methods that help with your instrumentation, and then call `setWorldConstructor` to tell Cucumber about it. You should extend the built-in `World` class:
21
39
22
40
```javascript
23
41
const { setWorldConstructor, World } =require('@cucumber/cucumber')
@@ -29,6 +47,7 @@ class CustomWorld extends World {
29
47
.build()
30
48
31
49
constructor(options) {
50
+
// needed so `attach`, `log` and `parameters` are properly set
32
51
super(options)
33
52
}
34
53
@@ -41,5 +60,3 @@ class CustomWorld extends World {
41
60
42
61
setWorldConstructor(CustomWorld)
43
62
```
44
-
45
-
**Note:** The World constructor was made strictly synchronous in *[v0.8.0](https://github.com/cucumber/cucumber-js/releases/tag/v0.8.0)*.
0 commit comments