/
gherkin-reference.md
536 lines (380 loc) · 20.1 KB
/
gherkin-reference.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# Gherkin Reference
Gherkin uses a set of special [keywords](#keywords) to give structure and meaning to
executable specifications. Each keyword is translated to many spoken languages;
in this reference we'll use English.
Most lines in a Gherkin document start with one of the [keywords](#keywords).
Comments are only permitted at the start of a new line, anywhere in the feature file. They begin with zero or more spaces,
followed by a hash sign (`#`) and some text.
Block comments are currently not supported by Gherkin.
Either spaces or tabs may be used for indentation. The recommended indentation
level is two spaces. Here is an example:
```{code-block} gherkin
:caption: GuessTheWord.feature
Feature: Guess the word
# The first example has two steps
Scenario: Maker starts a game
When the Maker starts a game
Then the Maker waits for a Breaker to join
# The second example has three steps
Scenario: Breaker joins a game
Given the Maker has started a game with the word "silky"
When the Breaker joins the Maker's game
Then the Breaker must guess a word with 5 characters
```
The trailing portion (after the keyword) of each step is matched to
a code block, called a [step definition](../automation/step-definitions).
{#keywords}
## Keywords
Each line that isn't a blank line has to start with a Gherkin *keyword*, followed by any text you like. The only exceptions are the feature and scenario descriptions.
The primary keywords are:
- `Feature`
- `Rule`
- `Example` (or `Scenario`)
- `Given`, `When`, `Then`, `And`, `But` for steps (or `*`)
- `Background`
- `Scenario Outline` (or `Scenario Template`)
- `Examples`
There are a few secondary keywords as well:
- `"""` (Doc Strings)
- `|` (Data Tables)
- `@` (Tags)
- `#` (Comments)
**Localization**
Gherkin is localized for many [spoken languages](#spoken-languages); each has their own localized equivalent of these keywords.
### Feature
The purpose of the `Feature` keyword is to provide a high-level description
of a software feature, and to group related scenarios.
The first primary keyword in a Gherkin document must always be `Feature`, followed
by a `:` and a short text that describes the feature.
You can add free-form text underneath `Feature` to add more description.
These description lines are ignored by Reqnroll at runtime, but are available for reporting (They are included by default in html reports).
```{code-block} gherkin
:caption: GuessTheWord.feature
Feature: Guess the word
The word guess game is a turn-based game for two players.
The Maker makes a word for the Breaker to guess. The game
is over when the Breaker guesses the Maker's word.
Scenario: Maker starts a game
```
The name and the optional description have no special meaning to Reqnroll. Their purpose is to provide
a place for you to document important aspects of the feature, such as a brief explanation
and a list of business rules (general acceptance criteria).
The free format description for `Feature` ends when you start a line with the keyword `Background`, `Rule`, `Example` or `Scenario Outline` (or their alias keywords).
You can place tags above `Feature` to group related features, independent of your file and directory structure.
### Tags
Tags are markers that can be assigned to features and scenarios. Assigning a tag to a feature is equivalent to assigning the tag to all scenarios in the feature file.
If supported by the [test execution framework](../installation/setup-project.md#choosing-your-test-execution-framework), Reqnroll generates categories from the tags. The generated category name is the same as the tag's name, but without the leading `@`. You can filter and group the tests to be executed using these unit test categories. For example, you can tag crucial tests with `@important`, and then execute these tests more frequently.
If your test execution framework does not support categories, you can still use tags to implement special logic for tagged scenarios in [bindings](../automation/bindings) by querying the `ScenarioContext.ScenarioInfo.Tags` property.
Scenario, Rule and Feature level tags are available by querying the `ScenarioInfo.CombinedTags` property.
Reqnroll treats the `@ignore` tag as a special tag. Reqnroll generates an [ignored test](../execution/test-results.md#ignored-tests) method from scenarios with this tag.
### Descriptions
Free-form descriptions (as described above for `Feature`) can also be placed underneath
`Example`/`Scenario`, `Background`, `Scenario Outline` and `Rule`.
You can write anything you like, as long as no line starts with a keyword.
### Rule
The purpose of the `Rule` keyword is to represent one *business rule* that should be implemented. It provides additional information for a feature. A `Rule` is used to group together several scenarios that belong to this *business rule*. A `Rule` should contain one or more scenarios that illustrate the particular rule.
You can also add tags on rules that will be inherited to all scenarios within that rule (like feature tags).
For example:
```{code-block} gherkin
:caption: Highlander.feature
Feature: Highlander
Rule: There can be only One
Scenario: Only One -- More than one alive
Given there are 3 ninjas
And there are more than one ninja alive
When 2 ninjas meet, they will fight
Then one ninja dies (but not me)
And there is one ninja less alive
Scenario: Only One -- One alive
Given there is only 1 ninja alive
Then he (or she) will live forever ;-)
@edge_case
Rule: There can be Two (in some cases)
Scenario: Two -- Dead and Reborn as Phoenix
...
```
### Scenario
This is a *concrete example* that *illustrates* a business rule. It consists of a list of [steps](#steps).
The keyword `Scenario` is a synonym of the keyword `Example`.
You can have as many steps as you like, but we recommend you keep the number at 3-5 per example. Having too many steps
in an example, will cause it to lose it's expressive power as specification and documentation.
In addition to being a specification and documentation, an example is also a *test*. As a whole, your examples are an
*executable specification* of the system.
Examples follow this same pattern:
- Describe an initial context (`Given` steps)
- Describe an event (`When` steps)
- Describe an expected outcome (`Then` steps)
{#steps}
### Steps
Each step starts with `Given`, `When`, `Then`, `And`, or `But`.
Reqnroll executes each step in a scenario one at a time, in the sequence you’ve written them in.
When Reqnroll tries to execute a step, it looks for a matching step definition to execute.
Keywords are not taken into account when looking for a step definition. This means you cannot have a
`Given`, `When`, `Then`, `And` or `But` step with the same text as another step.
Reqnroll considers the following steps duplicates:
```{code-block} gherkin
:caption: Feature File
Given there is money in my account
Then there is money in my account
```
This might seem like a limitation, but it forces you to come up with a less ambiguous, more clear
domain language:
```{code-block} gherkin
:caption: Feature File
Given my account has a balance of £430
Then my account should have a balance of £430
```
#### Given
`Given` steps are used to describe the initial context of the system - the *scene* of the scenario.
It is typically something that happened in the *past*.
When Reqnroll executes a `Given` step, it will configure the system to be in a well-defined state,
such as creating and configuring objects or adding data to a test database.
The purpose of `Given` steps is to **put the system in a known state** before the user (or external system) starts interacting with the system (in the `When` steps).
Avoid talking about user interaction in `Given`'s. If you were creating use cases, `Given`'s would be your preconditions.
It's okay to have several `Given` steps (use `And` or `But` for number 2 and upwards to make it more readable).
Examples:
- Mickey and Minnie have started a game
- I am logged in
- Joe has a balance of £42
#### When
`When` steps are used to describe an event, or an *action*. This can be a person interacting with the system, or it can be an event triggered by another system.
It's strongly recommended you only have a single `When` step per Scenario. If you feel compelled to add more, it's usually a sign that you should split the scenario up into multiple scenarios.
Examples:
- Guess a word
- Invite a friend
- Withdraw money
**Imagine it's 1922.** Most software does something people could do manually (just not as efficiently).
Try hard to come up with examples that don't make any assumptions about
technology or user interface. Imagine it's 1922, when there were no computers.
Implementation details should be hidden in the [step definitions](../automation/step-definitions).
#### Then
`Then` steps are used to describe an *expected* outcome, or result.
The [step definition](../automation/step-definitions) of a `Then` step should use an *assertion* to
compare the *actual* outcome (what the system actually does) to the *expected* outcome
(what the step says the system is supposed to do).
An outcome *should* be on an **observable** output. That is, something that comes *out* of the system (report, user interface, message), and not a behavior deeply buried inside the system (like a record in a database).
Examples:
- See that the guessed word was wrong
- Receive an invitation
- Card should be swallowed
While it might be tempting to implement `Then` steps to look in the database - resist that temptation!
You should only verify an outcome that is observable for the user (or external system), and changes to a database are usually not.
#### And, But
If you have successive `Given`'s, `When`'s, or `Then`'s, you *could* write:
```{code-block} gherkin
:caption: Feature File
Scenario: Multiple Givens
Given one thing
Given another thing
Given yet another thing
When I open my eyes
Then I should see something
Then I shouldn't see something else
```
Or, you could make the example more fluidly structured by replacing the successive `Given`'s, `When`'s, or `Then`'s with `And`'s and `But`'s:
```{code-block} gherkin
:caption: Feature File
Scenario: Multiple Givens
Given one thing
And another thing
And yet another thing
When I open my eyes
Then I should see something
But I shouldn't see something else
```
#### *
Gherkin also supports using an asterisk (`*`) in place of any of the normal step keywords. This can be helpful when you have some steps that are effectively a _list of things_, so you can express it more like bullet points where otherwise the natural language of `And` etc might not read so elegantly.
For example:
```{code-block} gherkin
:caption: Feature File
Scenario: All done
Given I am out shopping
And I have eggs
And I have milk
And I have butter
When I check my list
Then I don't need anything
```
Could be expressed as:
```{code-block} gherkin
:caption: Feature File
Scenario: All done
Given I am out shopping
* I have eggs
* I have milk
* I have butter
When I check my list
Then I don't need anything
```
### Background
Occasionally you'll find yourself repeating the same `Given` steps in all of the scenarios in a `Feature`.
Since it is repeated in every scenario, this is an indication that those steps
are not *essential* to describe the scenarios; they are *incidental details*. You can literally move such `Given` steps to the background, by grouping them under a `Background` section.
A `Background` allows you to add some context to the scenarios that follow it. It can contain one or more `Given` steps, which are run before *each* scenario, but after any [Before hooks](../automation/hooks).
A `Background` is placed before the first `Scenario`/`Example`, at the same level of indentation.
For example:
```{code-block} gherkin
:caption: MultipleSiteSupport.feature
Feature: Multiple site support
Only blog owners can post to a blog, except administrators,
who can post to all blogs.
Background:
Given a global administrator named "Greg"
And a blog named "Greg's anti-tax rants"
And a customer named "Dr. Bill"
And a blog named "Expensive Therapy" owned by "Dr. Bill"
Scenario: Dr. Bill posts to his own blog
Given I am logged in as Dr. Bill
When I try to post to "Expensive Therapy"
Then I should see "Your article was published."
Scenario: Dr. Bill tries to post to somebody else's blog, and fails
Given I am logged in as Dr. Bill
When I try to post to "Greg's anti-tax rants"
Then I should see "Hey! That's not your blog!"
Scenario: Greg posts to a client's blog
Given I am logged in as Greg
When I try to post to "Expensive Therapy"
Then I should see "Your article was published."
```
`Background` is also supported at the `Rule` level, for example:
```{code-block} gherkin
:caption: OverdueTasks.feature
Feature: Overdue tasks
Let users know when tasks are overdue, even when using other
features of the app
Rule: Users are notified about overdue tasks on first use of the day
Background:
Given I have overdue tasks
Scenario: First use of the day
Given I last used the app yesterday
When I use the app
Then I am notified about overdue tasks
Scenario: Already used today
Given I last used the app earlier today
When I use the app
Then I am not notified about overdue tasks
...
```
You can only have one set of `Background` steps per `Feature` or `Rule`. If you need different `Background` steps for different scenarios, consider breaking up your set of scenarios into more `Rule`s or more `Feature`s.
For a less explicit alternative to `Background`, check out [scoped step definitions](../automation/scoped-bindings).
### Tips for using Background
* Don't use `Background` to set up **complicated states**, unless that state is actually something the client needs to know.
* For example, if the user and site names don't matter to the client, use a higher-level step such as
`Given I am logged in as a site owner`.
* Keep your `Background` section **short**.
* The client needs to actually remember this stuff when reading the scenarios. If the `Background` is more than 4 lines long, consider moving some of the irrelevant details into higher-level steps.
* Make your `Background` section **vivid**.
* Use colorful names, and try to tell a story. The human brain keeps track of stories much better than it keeps track of names like `"User A"`, `"User B"`, `"Site 1"`, and so on.
* Keep your scenarios **short**, and don't have too many.
* If the `Background` section has scrolled off the screen, the reader no longer has a full overview of whats happening.
Think about using higher-level steps, or splitting the `*.feature` file.
{#scenario-outline}
### Scenario Outline
The `Scenario Outline` keyword can be used to run the same `Scenario` multiple times,
with different combinations of values.
The keyword `Scenario Template` is a synonym of the keyword `Scenario Outline`.
Copying and pasting scenarios to use different values quickly becomes tedious and repetitive:
```{code-block} gherkin
:caption: Feature File
Scenario: eat 5 out of 12
Given there are 12 cucumbers
When I eat 5 cucumbers
Then I should have 7 cucumbers
Scenario: eat 5 out of 20
Given there are 20 cucumbers
When I eat 5 cucumbers
Then I should have 15 cucumbers
```
We can collapse these two similar scenarios into a `Scenario Outline`.
Scenario outlines allow us to more concisely express these scenarios through the use
of a template with `< >`-delimited parameters:
```{code-block} gherkin
:caption: Feature File
Scenario Outline: eating
Given there are <start> cucumbers
When I eat <eat> cucumbers
Then I should have <left> cucumbers
Examples:
| start | eat | left |
| 12 | 5 | 7 |
| 20 | 5 | 15 |
```
A `Scenario Outline` must contain an `Examples` (or `Scenarios`) section. Its steps are interpreted as a template
which is never directly run. Instead, the `Scenario Outline` is run *once for each row* in
the `Examples` section beneath it (not counting the first header row).
The steps can use `<>` delimited *parameters* that reference headers in the examples table.
Reqnroll will replace these parameters with values from the table *before* it tries
to match the step against a step definition.
```{note}
Tables used in `Examples` must have **unique headers**. Using duplicate headers will result in errors.
```
```{hint}
In certain cases, when generating method names using the regular expression method, Reqnroll is unable to generate the correct parameter signatures for unit test logic methods without a little help. Placing single quotation marks (`'`) around placeholders (eg. `'<placeholder>'`)improves Reqnroll's ability to parse the scenario outline and generate more accurate regular expressions and test method signatures.
```
You can also use parameters in [multiline step arguments](#step-arguments).
{#step-arguments}
## Step Arguments
In some cases you might want to pass more data to a step than fits on a single line.
For this purpose Gherkin has `Doc Strings` and `Data Tables`.
### Doc Strings
`Doc Strings` are handy for passing a larger piece of text to a step definition.
The text should be offset by delimiters consisting of three double-quote marks on lines of their own:
```{code-block} gherkin
:caption: Feature File
Given a blog post named "Random" with Markdown body
"""
Some Title, Eh?
===============
Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
"""
```
In your step definition, there’s no need to find this text and match it in your pattern.
It will automatically be passed as the last argument in the step definition.
Indentation of the opening `"""` is unimportant, although common practice is two spaces in from the enclosing step.
The indentation inside the triple quotes, however, is significant. Each line of the Doc String will be dedented according to the opening `"""`. Indentation beyond the column of the opening """ will therefore be preserved.
### Data Tables
`Data Tables` are handy for passing a list of values to a step definition:
```{code-block} gherkin
:caption: Feature File
Given the following users exist:
| name | email | twitter |
| Aslak | aslak@cucumber.io | @aslak_hellesoy |
| Julien | julien@cucumber.io | @jbpros |
| Matt | matt@cucumber.io | @mattwynne |
```
Just like `Doc Strings`, `Data Tables` will be passed to the step definition as the first argument.
Reqnroll provides a rich API for manipulating tables from within step definitions.
See the [](../automation/datatable-helpers) reference for
more details.
{#spoken-languages}
## Spoken Languages
The language you choose for Gherkin should be the same language your users and
domain experts use when they talk about the domain. Translating between
two languages should be avoided.
This is why Gherkin has been translated to over 70 languages.
Here is a Gherkin scenario written in Norwegian:
```{code-block} gherkin
:caption: Feature File
# language: no
Funksjonalitet: Gjett et ord
Eksempel: Ordmaker starter et spill
Når Ordmaker starter et spill
Så må Ordmaker vente på at Gjetter blir med
Eksempel: Gjetter blir med
Gitt at Ordmaker har startet et spill med ordet "bløtt"
Når Gjetter blir med på Ordmakers spill
Så må Gjetter gjette et ord på 5 bokstaver
```
A `# language:` header on the first line of a feature file tells Reqnroll what
spoken language to use - for example `# language: fr` for French.
If you omit this header, Reqnroll will default to English (`en`).
You can also define the language in the [configuration file](../installation/configuration.md#language).
### Gherkin Dialects
In order to allow Gherkin to be written in a number of languages, the keywords have been translated into multiple languages. To improve readability and flow, some languages may have more than one translation for any given keyword.
#### Overview
You can find all translation of Gherkin in the [Cucumber documentation](https://cucumber.io/docs/gherkin/languages/).
This is also the place to add or update translations.
```{note}
Big parts of this page where taken over from [Cucumber Gherkin Reference](https://cucumber.io/docs/gherkin/reference/).
```