-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcucumber-website-a2557b8d5a9637c8.txt
More file actions
9217 lines (6779 loc) · 343 KB
/
Copy pathcucumber-website-a2557b8d5a9637c8.txt
File metadata and controls
9217 lines (6779 loc) · 343 KB
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
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Directory structure:
└── docs/
├── contributing.md
├── faq.md
├── index.md
├── ztest-polyglot-once.mdx
├── bdd/
│ ├── _category_.json
│ ├── better-gherkin.md
│ ├── discovery-workshop.md
│ ├── example-mapping.md
│ ├── examples.md
│ ├── history.md
│ ├── index.md
│ ├── myths.md
│ └── who-does-what.md
├── cucumber/
│ ├── _category_.json
│ ├── api.mdx
│ ├── checking-assertions.md
│ ├── configuration.mdx
│ ├── cucumber-expressions.md
│ ├── debugging.mdx
│ ├── environment-variables.md
│ ├── index.mdx
│ ├── mocking-and-stubbing-with-cucumber.md
│ ├── reporting.md
│ ├── state.mdx
│ └── step-definitions.mdx
├── gherkin/
│ ├── _category_.json
│ ├── index.mdx
│ ├── languages.mdx
│ ├── reference.md
│ └── step-organization.mdx
├── guides/
│ ├── 10-minute-tutorial.mdx
│ ├── _category_.json
│ ├── anti-patterns.mdx
│ ├── api-automation.md
│ ├── browser-automation.mdx
│ ├── continuous-integration.md
│ ├── index.mdx
│ ├── parallel-execution.mdx
│ ├── testable-architecture.md
│ └── upgrading.md
├── installation/
│ ├── _category_.json
│ ├── amp-cucumber-cpp-runner.md
│ ├── android.md
│ ├── clojure.md
│ ├── cplusplus.md
│ ├── cwt-cucumber.md
│ ├── d.md
│ ├── gobdd.md
│ ├── gocuke.md
│ ├── golang.md
│ ├── gosu.md
│ ├── groovy.md
│ ├── index.mdx
│ ├── ios.md
│ ├── java.md
│ ├── javascript.md
│ ├── jruby.md
│ ├── jython.md
│ ├── kotlin.md
│ ├── lua.md
│ ├── ocaml.md
│ ├── perl.md
│ ├── php.md
│ ├── pytest-bdd.md
│ ├── python.md
│ ├── r.md
│ ├── reqnroll.md
│ ├── ruby.md
│ ├── rust.md
│ ├── scala.md
│ ├── tcl.md
│ └── xunit-gherkin-quick.md
├── terms/
│ ├── _category_.json
│ ├── index.mdx
│ └── user-story.md
└── tools/
├── _category_.json
├── index.mdx
├── java.md
├── javascript.md
├── related-tools.md
└── ruby.md
================================================
FILE: docs/contributing.md
================================================
---
description: Help us make Cucumber better
---
# Contributing
You want to contribute to Cucumber, great!
## You have a question
You can [get in touch](/community) via Discord or GitHub Discussions, or try Stack Overflow.
## You found a bug
There are several different flavours of Cucumber for different programming languages. Try to file your issue in the repo for the Cucumber flavour you're using:
* [Cucumber JVM](https://github.com/cucumber/cucumber-jvm/issues/new)
* [Cucumber JS](https://github.com/cucumber/cucumber-js/issues/new)
* [Cucumber Ruby](https://github.com/cucumber/cucumber-ruby/issues/new)
* [Godog](https://github.com/cucumber/godog/issues/new)
If you're not sure, open an issue in the [common](https://github.com/cucumber/common/issues/new/choose) repo, and we'll take it from there.
## You want to update the documentation
Improvements to documentation are really valuable! See the [contribution guidelines](https://github.com/cucumber/website/blob/main/CONTRIBUTING.md) for the repo that drives this site for details.
## You want to contribute but don't know how
If you enjoy using Cucumber, consider [sponsoring us](/sponsors).
================================================
FILE: docs/faq.md
================================================
---
description: Frequently-asked questions
---
# FAQs
## Getting started and help
### How do I get started with Cucumber?
To get started from scratch, try the [10-minute tutorial](./guides/10-minute-tutorial.mdx).
You can read these docs to learn more about [Gherkin](./gherkin/reference.md), [Cucumber](./cucumber/api.mdx) and [BDD](./bdd/index.md).
### Where can I get more in-depth information?
If you'd like to go more in-depth, try one of the following:
- [Books](/learn)
- [Cucumber School (online training)](https://school.cucumber.io)
### Where can I get help?
For questions, you can [get in touch](/community) with the community.
## Installing and running Cucumber
### How do I install Cucumber?
How to install Cucumber, depends on which programming language you are using.
You can find information on how to install your flavour of Cucumber on the [installation](/docs/installation) page.
### Which version of Cucumber should I use?
In general, it is recommended to use the most recently released version of Cucumber for your programming language.
Each release will fix known bugs and/or add new features.
You can find the most recent version of Cucumber either in the [10-minute tutorial](/docs/guides/10-minute-tutorial), the [installation](/docs/installation) page or on [GitHub](https://github.com/cucumber).
### How should I upgrade to a newer version?
See our [guide to upgrading](./guides/upgrading.md).
### How do I run Cucumber?
For information on how to run Cucumber, see [Running Cucumber](/docs/cucumber/api/#running-cucumber).
### How do I run Cucumber from the CLI?
For information on how to run the Cucumber CLI, see [From the command line](/docs/cucumber/api/#from-the-command-line).
### What are the configuration options for running Cucumber?
For information about configuration options, see [Configuration](/docs/cucumber/configuration/).
## Usage and troubleshooting
### How do I call other steps or scenarios?
Each scenario should be *independent*; you should be able to run them in any order or in parallel without one scenario interfering with another.
Each scenario should *test exactly one thing* so that when it fails, it fails for a clear reason. This means you wouldn't reuse one scenario inside another scenario.
If your scenarios use the same or similar steps, or perform similar actions on your system, you can extract [helper methods](#how-to-use-helper-methods) to do those things.
#### How to use helper methods
Helper methods allow you to re(use) actions in steps and avoid writing multiple step definitions for similar behaviours. You write a helper method for actions like *logging in to your application* and then reuse them as a step or part of other steps.
This helps keep your tests clean, concise and maintainable.
To learn more about using helper methods, check out [Helper methods](/docs/gherkin/step-organization/#helper-methods) and [Grouping step definitions](/docs/gherkin/step-organization/#grouping-step-definitions).
### How detailed should my scenarios be?
Your scenarios should contain *just enough* information to describe the *behaviour* of the system.
They should not describe the implementation of your application, as that might change - causing your tests to fail.
They shouldn't contain too many details, as this will distract from the actual *behaviour*.
Let's illustrate this with an example.
Imagine we have a process where the user will be notified of the result.
At the moment that might be implemented as sending them an email, but that might change in the future (for instance, to a text message).
You can specify the step as follows:
```gherkin
Then the user will be notified
```
This way, if the implementation of how the user is notified changes, you will only have to change the step definition (or the helper method called by that step definition),
rather than the step itself **and** all underlying code.
For more information, have a look at [Writing better Gherkin](/docs/bdd/better-gherkin/) and/or [Writing maintainable automated acceptance tests (pdf).](http://dhemery.com/pdf/writing_maintainable_automated_acceptance_tests.pdf)
### How can I specify my test cases in Excel/CSV?
We advise you *not* to use Excel or csv files to define your test cases; using Excel or csv files is considered an anti-pattern.
One of the goals of Cucumber is to have *executable specifications*. This means your feature files should contain just the right level of information to document the expected behaviour of the system.
If your test cases are kept in separate files, how would you be able to read the documentation?
This also means you shouldn't have too many details in your feature file. If you do, you might consider moving them to your step definitions or [helper methods](#how-to-use-helper-methods).
For instance, if you have a form where you need to populate lots of different fields, you might use the [Builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) to do so.
### How can I make Cucumber conditionally skip steps
Each scenario should test *one thing* and fail for one particular reason. This means there should be no reason to skip steps.
If there does seem to be a reason you'd want to skip steps conditionally, you probably have an anti-pattern.
For instance, you might be trying to test multiple things in one scenario or you might not be in control of the state of your test environment or test data.
The best thing to do here is to fix the root cause.
### How can I make Cucumber run the skipped steps after a failed step
Cucumber skips all steps after a failed step by design. Once a step has failed, the test has failed and there should be no reason to perform the next steps.
If you have a need to run the additional steps, likely your scenario is testing too many different things at once. Consider splitting your scenario into smaller tests.
### How do I take a screenshot after a (failed) step?
See our [browser automation guide](./guides/browser-automation.mdx).
### How do I share state between steps?
The JavaScript and Ruby implementations of Cucumber have the [world object](/docs/cucumber/state/#world-object) for sharing state between steps.
If you are using Cucumber on the JVM, you can use [dependency injection (DI)](/docs/cucumber/state/#dependency-injection) to share state between steps. If your project already uses a dependency framework supported by Cucumber (and/or you are familiar with one of them), it's probably easiest to use that framework. Otherwise, Picocontainer is the most light weight framework you can use.
## Cucumber-JVM
### Cucumber says my steps are undefined, but I have implemented step definitions!
If Cucumber is telling you that your steps are undefined, when you have defined step definitions, this means that Cucumber cannot *find* your step definitions.
You'll need to make sure to specify the path to your step definitions (glue path) correctly.
By default Cucumber-JVM will search in the package (or sub-packages) of the runner class.
You can also tell Cucumber-JVM explicitly which packages (and sub-packages) to search, with:
```java
@CucumberOptions(glue = {"<package>", "<package>", "<etc>"})
public class RunCucumberTest{}
```
```kotlin
@CucumberOptions(glue = ["<package>", "<package>", "<etc>"])
class RunCucumberTest
```
### Cucumber expressions vs regex
For more information about Cucumber expressions, see the section on [Cucumber expressions](/docs/cucumber/cucumber-expressions/).
You can still use regular expression (regex) also, but you cannot use Cucumber expressions and regular expressions in the same step definition.
Cucumber expressions were added in Cucumber-JVM version 3.0.0.
Note that a step definition using regex will start with `^` and end with `$`, while a step definition using Cucumber expressions will not.
An example using regex:
```java
@Given("^today is ([0-9]{4}-[0-9]{2}-[0-9]{2})$")
public void today_is(Date date) {
calculator = new DateCalculator(date);
}
```
An example using Cucumber expressions:
```java
@When("I add {int} and {int}")
public void adding(int arg1, int arg2) {
calc.push(arg1);
calc.push(arg2);
calc.push("+");
}
```
### How do I use lambdas to define step definitions?
To use lambdas to define your step definitions, make sure to use the `cucumber-java8` dependency, instead of the `cucumber-java` dependency.
You can find the required dependencies [here](./installation/java.md).
For an example on how to use them in Java, see this [code example](https://github.com/cucumber/cucumber-jvm/blob/main/examples/calculator-java8-cli/src/test/java/io/cucumber/examples/calculator/RpnCalculatorSteps.java). For Kotlin, see this [code example](https://github.com/cucumber/cucumber-jvm/blob/main/cucumber-kotlin-java8/src/test/kotlin/io/cucumber/kotlin/LambdaStepDefinitions.kt).
### Getting weird characters in the console output
If you are getting some weird additional characters in the output of your steps, like `[32m`, this is a problem with escaping ANSI color codes.
In order to prevent this problem, you can set the option `monochrome` to `true.
If you are using Eclipse, you might try this [plugin](https://marketplace.eclipse.org/content/ansi-escape-console).
### Arity mismatch
An arity mismatch exception (`cucumber.runtime.CucumberException: Arity mismatch`) indicates that the step does not provide the right number of arguments needed for the step definition.
### Duplicate step definition
A DuplicateStepDefinitionException indicates that you have defined the same step twice. First of all, Cucumber doesn't
distinguish between [keywords](./gherkin/reference.md#keywords) used with a particular step when
[matching steps](/docs/cucumber/api/#matching-steps). This means that `Given an order exists` and `Then an order exists`
will both match "an order exists". When providing arguments using Cucumber expressions and/or regular expressions,
multiple steps might match the same expression. Finally, this means that you cannot extend a class which defines step
definitions, as that will lead to duplicates.
### Does Cucumber-JVM support Kotlin?
You can use [Cucumber-JVM](https://github.com/cucumber/cucumber-jvm) to write step definitions in Kotlin. Please have a look at the [Kotlin examples for cucumber-jvm](https://github.com/cucumber/cucumber-jvm/tree/master/cucumber-kotlin-java8).
At the moment it is not possible to generate step definitions in Kotlin. The reason for this is that there is no Kotlin Backend implemented. If this is something you'd like to work on, there is [a request for one](https://github.com/cucumber/cucumber-jvm/issues/1520). There is also a request for a [native Kotlin implementation of Cucumber](https://github.com/cucumber/cucumber/issues/331).
### Cucumber can't find my step definitions in IntelliJ IDEA
In this instance, you need to configure a new run configuration in IntelliJ IDEA.
1. Click **Run** > **Edit Configurations** from the menu in IntelliJ IDEA.
2. Click the **+** icon on the top-left and type in _cucumber_. Select **Cucumber Java**.
3. Create the configuration according to the [Run/Debug Configuration Cucumber Java](https://www.jetbrains.com/help/idea/run-debug-configuration-cucumber-java.html) instructions from JetBrains.
If IntelliJ IDEA doesn't recognize the package with step definitions, you can specify it manually by entering the package name in the Glue field, for example _stepdefs_.
For more information, please see [Run Cucumber Tests](https://www.jetbrains.com/help/idea/running-cucumber-tests.html) from JetBrains documentation.
### How do I fix an error where the stacktrace contains `Failed to instantiate public cucumber.runtime.java.JavaBackend` or `NoSuchMethodException`?
Check that the Cucumber version is the same for all Cucumber dependencies and make sure you only have the required dependencies. This means you need to ensure that you get the transitive dependencies that go with the version of Cucumber that you have.
You can see all your Maven dependencies, including transitive ones by running `mvn dependency:tree`.
If you're using any other library which also contains a dependency on Cucumber (a transitive dependency), try excluding
that transitive dependency in your pom file to ensure only one version of Cucumber is being referenced. Please refer to
the Maven [instructions for excluding dependencies](https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html#dependency-exclusions) for steps on excluding transitive dependencies.
================================================
FILE: docs/index.md
================================================
---
sidebar_position: 0
---
# Introduction
Cucumber is a tool that supports [Behaviour-Driven Development (BDD)](./bdd/index.md).
If you're new to Behaviour-Driven Development read our [BDD introduction](./bdd/index.md)
first.
## What is Cucumber?
Ok, now that you know that BDD is about discovery, collaboration and examples
(and not testing), let's take a look at Cucumber.
Cucumber reads executable specifications written in plain text and validates
that the software does what those specifications say. The specifications
consist of multiple *examples*, or *scenarios*. For example:
```gherkin
Scenario: Breaker guesses a word
Given the Maker has chosen a word
When the Breaker makes a guess
Then the Maker is asked to score
```
Each scenario is a list of *steps* for Cucumber to work through. Cucumber
verifies that the software conforms with the specification and generates a
report indicating ✅ success or ❌ failure for each scenario.
In order for Cucumber to understand the scenarios, they must follow some basic
syntax rules, called [Gherkin](./gherkin/index.mdx).
## What is Gherkin?
Gherkin is a set of grammar rules that makes plain text structured enough for
Cucumber to understand. The scenario above is written in Gherkin.
Gherkin serves multiple purposes:
- Unambiguous executable specification
- Automated testing using Cucumber
- Document how the system *actually* behaves

The Cucumber grammar exists in different flavours for many [spoken languages](./gherkin/reference.md#spoken-languages)
so that your team can use the keywords in your own language.
Gherkin documents are stored in `.feature` text files and are typically
versioned in source control alongside the software.
See the [Gherkin reference](./gherkin/reference.md) for more details.
## What are step definitions?
[Step definitions](./cucumber/step-definitions.mdx) connect Gherkin steps to
programming code. A step definition carries out the action that should be
performed by the step. So step definitions hard-wire the specification to the
implementation.
```
┌────────────┐ ┌──────────────┐ ┌───────────┐
│ Steps │ │ Step │ │ │
│ in Gherkin ├──matched with──>│ Definitions ├───manipulates──>│ System │
│ │ │ │ │ │
└────────────┘ └──────────────┘ └───────────┘
```
Step definitions can be written in many programming languages. Here is an example
using JavaScript:
```javascript
When('{maker} starts a game', maker => {
maker.startGameWithWord({ word: 'whale' })
})
```
================================================
FILE: docs/ztest-polyglot-once.mdx
================================================
---
unlisted: true
---
# TEST: Polyglot Once
<Tabs once="java,kotlin,scala,javascript,ruby"/>
## Generic content
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas scelerisque vitae quam vel interdum. Nunc porttitor pharetra sodales. Fusce tempor risus finibus, maximus sem ornare, efficitur metus. Morbi urna mi, gravida in tortor in, aliquet porta nunc. Integer justo diam, vehicula ut iaculis sit amet, varius et risus. Integer rhoncus, mi in viverra dapibus, ligula ligula molestie sapien, ut hendrerit ex ligula et neque. Nullam efficitur egestas nibh, in sodales ex dapibus vel. Quisque est nunc, sollicitudin vitae consectetur quis, elementum vel arcu. Integer volutpat iaculis mi et porttitor.
Nullam rutrum justo a nisi luctus semper. Nullam ut mollis metus. Curabitur viverra magna sit amet aliquam efficitur. Cras sed sem eleifend, pellentesque dui sed, pellentesque lectus. Integer velit magna, cursus pretium tellus a, porta vehicula risus. Aliquam eget ultrices ligula. Nunc ac enim sapien. Morbi in lorem eget leo iaculis tincidunt. Donec tincidunt molestie dolor a venenatis. Curabitur aliquam varius est non elementum. Sed et diam ut ante blandit cursus. Ut a felis fringilla, tristique diam vel, eleifend nibh. Phasellus tristique laoreet volutpat. Etiam non ipsum iaculis, porta lacus a, scelerisque magna. Integer justo arcu, malesuada vel molestie eget, euismod fringilla ipsum.
Aenean eget mattis augue, quis laoreet odio. Donec sed mi lectus. Nunc vitae arcu vitae magna malesuada feugiat in non nibh. Morbi felis magna, congue efficitur tempor eu, rhoncus et nunc. Proin eu est ac risus ullamcorper egestas vitae ac nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris semper tortor leo. Duis sit amet elit at odio maximus tempus. In hac habitasse platea dictumst. Mauris dignissim quam quis elementum dignissim. Cras nec neque eu tortor semper fringilla a eu lacus.
Nam eleifend euismod pulvinar. Sed id risus diam. Duis nec ullamcorper ligula. Ut scelerisque in erat eget bibendum. Sed sed lacus nec lorem finibus dignissim a quis massa. Donec ultricies justo ut orci volutpat posuere. Nunc efficitur malesuada urna, quis scelerisque tortor imperdiet venenatis. Sed cursus dictum iaculis. Nulla in nulla sit amet nibh dapibus imperdiet quis ut nulla. Nullam accumsan, mauris a ultricies imperdiet, orci lacus sodales augue, ut euismod elit nisi ac est. Nullam ac sapien vitae augue accumsan sodales sed et nunc.
Ut nulla nunc, commodo et euismod id, dictum sollicitudin nunc. Praesent et dui venenatis tellus semper consectetur non sed ipsum. Ut a ultricies lectus. Praesent est est, consectetur ullamcorper sapien euismod, volutpat lobortis velit. Nam nec odio vitae lorem egestas viverra. Proin fermentum tortor ut lacus fringilla, interdum auctor massa faucibus. Suspendisse dignissim porta velit, at congue mi malesuada eu. Aliquam commodo nisi erat, nec posuere magna sagittis rhoncus. Maecenas ac felis laoreet, aliquet nulla eget, ullamcorper tellus. Duis enim augue, ornare vitae lacus vel, porta posuere ex. Sed pretium nunc ac suscipit finibus. Aenean sagittis ipsum sit amet sapien venenatis lacinia. Curabitur sed diam nulla. Fusce id urna lacus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas scelerisque vitae quam vel interdum. Nunc porttitor pharetra sodales. Fusce tempor risus finibus, maximus sem ornare, efficitur metus. Morbi urna mi, gravida in tortor in, aliquet porta nunc. Integer justo diam, vehicula ut iaculis sit amet, varius et risus. Integer rhoncus, mi in viverra dapibus, ligula ligula molestie sapien, ut hendrerit ex ligula et neque. Nullam efficitur egestas nibh, in sodales ex dapibus vel. Quisque est nunc, sollicitudin vitae consectetur quis, elementum vel arcu. Integer volutpat iaculis mi et porttitor.
Nullam rutrum justo a nisi luctus semper. Nullam ut mollis metus. Curabitur viverra magna sit amet aliquam efficitur. Cras sed sem eleifend, pellentesque dui sed, pellentesque lectus. Integer velit magna, cursus pretium tellus a, porta vehicula risus. Aliquam eget ultrices ligula. Nunc ac enim sapien. Morbi in lorem eget leo iaculis tincidunt. Donec tincidunt molestie dolor a venenatis. Curabitur aliquam varius est non elementum. Sed et diam ut ante blandit cursus. Ut a felis fringilla, tristique diam vel, eleifend nibh. Phasellus tristique laoreet volutpat. Etiam non ipsum iaculis, porta lacus a, scelerisque magna. Integer justo arcu, malesuada vel molestie eget, euismod fringilla ipsum.
Aenean eget mattis augue, quis laoreet odio. Donec sed mi lectus. Nunc vitae arcu vitae magna malesuada feugiat in non nibh. Morbi felis magna, congue efficitur tempor eu, rhoncus et nunc. Proin eu est ac risus ullamcorper egestas vitae ac nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris semper tortor leo. Duis sit amet elit at odio maximus tempus. In hac habitasse platea dictumst. Mauris dignissim quam quis elementum dignissim. Cras nec neque eu tortor semper fringilla a eu lacus.
Nam eleifend euismod pulvinar. Sed id risus diam. Duis nec ullamcorper ligula. Ut scelerisque in erat eget bibendum. Sed sed lacus nec lorem finibus dignissim a quis massa. Donec ultricies justo ut orci volutpat posuere. Nunc efficitur malesuada urna, quis scelerisque tortor imperdiet venenatis. Sed cursus dictum iaculis. Nulla in nulla sit amet nibh dapibus imperdiet quis ut nulla. Nullam accumsan, mauris a ultricies imperdiet, orci lacus sodales augue, ut euismod elit nisi ac est. Nullam ac sapien vitae augue accumsan sodales sed et nunc.
Ut nulla nunc, commodo et euismod id, dictum sollicitudin nunc. Praesent et dui venenatis tellus semper consectetur non sed ipsum. Ut a ultricies lectus. Praesent est est, consectetur ullamcorper sapien euismod, volutpat lobortis velit. Nam nec odio vitae lorem egestas viverra. Proin fermentum tortor ut lacus fringilla, interdum auctor massa faucibus. Suspendisse dignissim porta velit, at congue mi malesuada eu. Aliquam commodo nisi erat, nec posuere magna sagittis rhoncus. Maecenas ac felis laoreet, aliquet nulla eget, ullamcorper tellus. Duis enim augue, ornare vitae lacus vel, porta posuere ex. Sed pretium nunc ac suscipit finibus. Aenean sagittis ipsum sit amet sapien venenatis lacinia. Curabitur sed diam nulla. Fusce id urna lacus.
## Polyglot content
<Content lang="java,kotlin,scala">
Here's some JVM stuff.
</Content>
<Content lang="javascript">
```js
console.log('here')
```
</Content>
<Content lang="ruby">
Gems!
</Content>
================================================
FILE: docs/bdd/_category_.json
================================================
{
"position": 4,
"label": "Behaviour-Driven Development"
}
================================================
FILE: docs/bdd/better-gherkin.md
================================================
---
sidebar_position: 7
---
# Writing better Gherkin
There are several ways to make your Gherkin better.
## Describe behaviour
Your scenarios should describe the intended behaviour of the system, not the implementation.
In other words, it should describe *what*, not *how*.
For example, for an authentication Scenario, you should write:
```gherkin
When "Bob" logs in
```
instead of:
```gherkin
Given I visit "/login"
When I enter "Bob" in the "user name" field
And I enter "tester" in the "password" field
And I press the "login" button
Then I should see the "welcome" page
```
The first example, **When "Bob" logs in**, is a *functional requirement*. The second, much longer, example is a *procedural reference*.
Functional requirements are features, but procedures belong in the implementation details.
That way, when the implementation of a feature changes, you'll only need to change the process steps behind the scenes.
The behaviour does not have to change just because the implementation does.
In fact, a good question to ask yourself when writing a feature clause is: “Will this wording need to change if the implementation does?”.
If the answer is “Yes”, then you should rework it avoiding implementation specific details.
As a side benefit, in consequence your scenarios will be a lot shorter and much easier to follow and understand.
## Consider a more declarative style
One way to make scenarios easier to maintain and less brittle is to use a declarative style. Declarative style describes the behaviour of the application, rather than the implementation details. Declarative scenarios read better as "living documentation". A declarative style helps you focus on the value that the customer is getting, rather than the keystrokes they will use.
Imperative tests communicate details, and in some contexts this style of test is appropriate. On the other hand, because they are so closely tied to the mechanics of the current UI, they often require more work to maintain. Any time the implementation changes, the tests need to be updated too.
Here's an example of a feature in an imperative style:
```gherkin
Feature: Subscribers see different articles based on their subscription level
Scenario: Free subscribers see only the free articles
Given users with a free subscription can access "FreeArticle1" but not "PaidArticle1"
When I type "freeFrieda@example.com" in the email field
And I type "validPassword123" in the password field
And I press the "Submit" button
Then I see "FreeArticle1" on the home page
And I do not see "PaidArticle1" on the home page
Scenario: Subscriber with a paid subscription can access "FreeArticle1" and "PaidArticle1"
Given I am on the login page
When I type "paidPattya@example.com" in the email field
And I type "validPassword123" in the password field
And I press the "Submit" button
Then I see "FreeArticle1" and "PaidArticle1" on the home page
```
Each step is a precise instruction. The inputs and expected results are specified exactly. But it's easy to imagine changes to the application which would require changing these tests. The available options for free versus paid subscriptions can change. Even the means of logging in could change. What if, in the future, users log in with a voice interface or a thumbprint?
A more declarative style hides the details of how the application's capabilities are implemented.
```gherkin
Feature: Subscribers see different articles based on their subscription level
Scenario: Free subscribers see only the free articles
Given Free Frieda has a free subscription
When Free Frieda logs in with her valid credentials
Then she sees a Free article
Scenario: Subscriber with a paid subscription can access both free and paid articles
Given Paid Patty has a basic-level paid subscription
When Paid Patty logs in with her valid credentials
Then she sees a Free article and a Paid article
```
With a declarative style, each step communicates an idea, but the exact values aren't specified. The details of *how* the user interacts with the system, such as which specific articles are free or paid, and the subscription level of different test users, are specified in the step definitions (the automation code that interacts with the system). The subscription packages could change in the future. The business could change what content is available to subscribers on free and paid plans, without having to change this scenario and other scenarios that use the same step definitions. If another subscription level is added later, it's easy to add a scenario for that. By avoiding terms like “click a button” that suggest implementation, the scenario is more resilient to implementation details of the UI. The intent of the scenario remains the same, even if the implementation changes later. In addition, having too many implementation details in a scenario, makes it harder to understand the intended behaviour it illustrates.
================================================
FILE: docs/bdd/discovery-workshop.md
================================================
---
sidebar_position: 1
---
# Discovery workshop
## What is a discovery workshop?
A discovery workshop is a conversation where technical and business people collaborate to explore, discover and agree as much as they can about the desired behaviour for a [User Story](/docs/terms/user-story/).
## How do you conduct a discovery workshop?
There are several discovery workshop models, these are just a few:
[**Example Mapping**](/docs/bdd/example-mapping/)
Uses a pack of index cards in four different colours to map rules (a summary of constraints/acceptance criteria the team has agreed upon) to examples (illustrations/cases of the acceptance criteria)
[**OOPSI Mapping (Outcomes, Outputs, Processes, Scenarios, Inputs)**](https://jennyjmar.com/2016/04/16/bdd-discovery-and-oopsi/)
Similar to Example Mapping, uses Post-it Notes of different colours to map shared processes/relationships between outputs and scenarios.
[**Feature Mapping**](https://johnfergusonsmart.com/feature-mapping-a-simpler-path-from-stories-to-executable-acceptance-criteria/)
Also uses Post-it Notes of different colours. The team picks a story from the backlog, identifies the actors involved, breaks the story down into tasks, and maps those tasks to specific examples.
## When should you hold a discovery workshop?
As late as possible before development on a new User Story begins, in order to prevent details from being lost. Conducting a discovery workshop as late as possible also gives the team enough leg room to shift their plans should new details surface.
## Who should attend?
A good rule-of-thumb is 3-6 people, but at a bare minimum your [Three Amigos](/docs/bdd/who-does-what/#the-three-amigos/) should be present: a product owner, a developer, and a tester. Your product owner will identify the problem the team should be trying to solve, your developer will address how to build a solution around said problem, and your tester will address any edge cases that could arise.
## How long does a discovery workshop take?
A discovery workshop should ideally only last about 25-30 minutes per story. If you need any more time than this, it's likely the story is far too large and should be broken down, or some of the specifics are missing. In the latter case, you should set aside the story as the team needs to do more research.
## Why bother?
The purpose of a discovery workshop is to give all stakeholders, both technical and non-technical, a *shared understanding* of the work at hand. Doing so encourages cross-functional collaboration, an increase in feedback, and covers any lost details or incorrect assumptions made.
## Conclusion
A discovery workshop is a very important piece of the BDD lifecycle, among other agile development approaches. Without it, you are sure to run into miscommunications and your team won't discover any unknowns, which could really hamper your project's success.
================================================
FILE: docs/bdd/example-mapping.md
================================================
---
sidebar_position: 2
---
# Example Mapping
Before you pull a user story into development, it’s crucial to have a conversation to clarify and confirm the acceptance criteria.
Example Mapping is a method designed to make this conversation short and very productive.
## How it works
Concrete examples are a great way to help us explore and understand the problem domain. They are a great basis for our acceptance tests.
When discussing examples, other things might come up in the conversation that deserve to be captured too:
- **rules** that summarise a set of examples, or express other constraints.
- **questions** that cannot be answered during the conversation, or assumptions that are made.
- new **user stories** discovered or sliced and deferred out of scope.
We can capture these different types of information on index cards, and arrange them in a map:
- We write the story on a **yellow** card and place it on top.
- Each of the acceptance criteria, or rules, is written on a **blue** card and placed beneath the yellow story card.
- Examples to illustrate these rules are written on a **green** card and placed under the relevant rule.
- Questions that cannot be answered during the session are captured on a **red** card so we can move on with the conversation.
We keep going until the group is satisfied that the scope of the story is clear, or we run out of time.
## More information
For more details, see Matt Wynne's blog on [Example Mapping](/blog/bdd/example-mapping-introduction).
To get started yourself, see Steve Tooke's blog on [Your first Example Mapping session](/blog/bdd/your-first-example-mapping-session).
Or have a look at the [Example Mapping Webinar](/blog/bdd/example-mapping-webinar).
================================================
FILE: docs/bdd/examples.md
================================================
---
sidebar_position: 3
---
# Examples
Good BDD examples are *concrete* rather than *abstract*. They mention names of
people and places, exact dates and amounts, and anything that is relevant to the
problem domain of the software.
Good examples don't mention technical details.
:::info[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. Imagine it's 1922, when there were no computers.
:::
================================================
FILE: docs/bdd/history.md
================================================
---
sidebar_position: 4
---
# History of BDD
Behavior-driven development was pioneered by [Daniel Terhorst-North](https://dannorth.net) back in the early 00s, as he explained in a 2006 article called [Introducing BDD](http://dannorth.net/introducing-bdd/). It grew from a response to test-driven development (TDD), as a way to help programmers on new agile teams "get straight to the good stuff" of knowing how to approach testing and coding, and minimize misunderstandings. BDD has evolved into both analysis and automated testing at the acceptance level. [Liz Keogh](https://lizkeogh.com), another BDD pioneer, started writing and speaking about it extensively beginning in 2004.
## Early tools supporting BDD
In 2003, Daniel Terhorst-North started writing a replacement for JUnit called JBehave, using vocabulary based on "behaviour" rather than "test". Liz Keogh and Chris Matts also started contributing early on. Influenced by the idea of ubiquitous language introduced in Eric Evans' [Domain-Driven Design](https://domainlanguage.com/ddd/), and also focusing on business value, the "Given/When/Then" template was developed to capture a story's acceptance criteria in an executable form. It grew partly from the "As a..., I ..., So that..." template for writing user stories, created by [Rachel Davies](http://rachelcdavies.github.io/) at Connextra that had become a recognized standard.
In 2005, the [RSpec](https://rspec.info/) project, which supported BDD in the Ruby language, was founded by [Dave Astels](http://daveastels.com/), [Steven Baker](https://stevenrbaker.com/), [Aslak Hellesøy](https://twitter.com/aslak_hellesoy) and [David Chelimsky](https://twitter.com/dchelimsky).
## Origins of Cucumber
As he helped improve RSpec, Aslak had a lot of ideas for improvements in areas like error messages, step definition snippets, and result reporting. RSpec was designed for programmers, whereas the RSpec Story Runner was for the whole team, including non-coding stakeholders.
He started a new project, intending to make a better version of Story Runner. He initially called it _Stories_, but asked his then-fiancée for a catchier name. She thought of _Cucumber_, and it stuck.
================================================
FILE: docs/bdd/index.md
================================================
# Behaviour-Driven Development
Behaviour-Driven Development (BDD) is the software development process that Cucumber was built to support.
There's much more to BDD than just using Cucumber.
## What is BDD?
BDD is a way for software teams to work that closes the gap between business people and technical people by:
* Encouraging collaboration across roles to build shared understanding of the problem to be solved
* Working in rapid, small iterations to increase feedback and the flow of value
* Producing system documentation that is automatically checked against the system's behaviour
We do this by focusing collaborative work around concrete, real-world examples that illustrate how we want the system to behave. We use those examples to guide us from concept through to implementation, in a process of continuous collaboration.
### BDD and agile
We assume that your team are using some kind of agile methodology already, planning work in small increments of value like [User Stories]. BDD does not replace your existing agile process, it enhances it.
Think of BDD as a set of plugins for your existing process that will make your team more able to deliver on the promises of agile: timely, reliable releases of working software that meets your organisation’s evolving needs, requiring some maintenance effort and discipline.
### Rapid iterations
We assume you would like to be able to respond quickly to feedback from your users, and do only the minimal work necessary to meet those needs.
BDD encourages working in rapid iterations, continuously breaking down your user's problems into small pieces that can flow through your development process as quickly as possible.
## Three practices
Essentially, day-to-day BDD activity is a three-step, iterative process:
1. First, take a small upcoming change to the system -- a [User Story] -- and talk about concrete examples of the new functionality to explore, discover and agree on the details of what's expected to be done.
1. Next, document those examples in a way that can be automated, and check for agreement.
1. Finally, implement the behaviour described by each documented example, starting with an automated test to guide the development of the code.
The idea is to make each change small and iterate rapidly, moving back up a level each time you need more information. Each time you automate and implement a new example, you've added something valuable to your system, and you're ready to respond to feedback.
We call these practices _Discovery_, _Formulation_, and _Automation_.
<figure>
<img alt="Diagram of how the practices fit together" src="/img/docs/bdd-practices-diagram.png"/>
<figcaption>Discovery, Formulation and Automation</figcaption>
</figure>
Over time, the documented examples become an asset that enables your team to continue confidently and rapidly making changes to the system. The code reflects the documentation, and the documentation reflects the team's shared understanding of the problem domain. This shared understanding is constantly evolving.
There's lots to learn about each of these practices. We'll summarise each of them below.
### Discovery: What it _could_ do
> The hardest single part of building a software system is deciding precisely what to build.
>
> -- <cite>Fred Brooks, The mythical man-month</cite>
Although documentation and automated tests are produced by a BDD team, you can think of them as nice side-effects. The real goal is valuable, working software, and the fastest way to get there is through conversations between the people who are involved in imagining and delivering that software.
BDD helps teams to have the right conversations at the right time so you minimise the amount of time spent in meetings and maximising the amount of valuable code you produce.
We use structured conversations, called [discovery workshops], that focus around real-world examples of the system from the users' perspective. These conversations grow our team's shared understanding of the needs of our users, of the rules that govern how the system should function, and of the scope of what needs to be done.
It may also reveal gaps in our understanding, where we need more information before we know what to do.
The scrutiny of a discovery session often reveals low-priority functionality that can be deferred from the scope of a user story, helping the team to work in smaller increments, improving their flow.
If you're new to BDD, discovery is the right place to start. You won't get much joy from the other two practices until you've mastered discovery.
### Formulation: What it _should_ do
As soon as we have identified at least one valuable example from our discovery sessions, we can now formulate each example as structured documentation. This gives us a quick way to confirm that we really do have a shared understanding of what to build.
In contrast to traditional documentation, we use [a medium that can be read by both humans and computers](../gherkin), so that:
* We can get feedback from the whole team about our shared vision of what we're building.
* We'll be able to automate these examples to guide our development of the implementation.
By writing this executable specification collaboratively, we establish a shared language for talking about the system. This helps us to use problem-domain terminology all the way down into the code.
### Automation: What it _actually does_
Now that we have our executable specification, we can use it to guide our development of the implementation.
Taking one example at a time, we automate it by connecting it to the system as a test. The test fails because we have not implemented the behaviour it describes yet. Now we develop the implementation code, using [lower-level examples of the behaviour of internal system components](https://www.geepawhill.org/2020/06/12/microtest-tdd-more-definition/) to guide us as required.
The automated examples work like guide-rails, helping us to keep our development work on track.
When we need to come back and maintain the system later, the automated examples will help us to understand what the system is currently doing, and to make changes safely without unintentionally breaking anything.
This rapid, repeatable feedback reduces the burden of manual regression testing, freeing people up to do more interesting work, like exploratory testing.
## Learn more
Read the topics below to dig deeper and learn more about BDD.
[discovery workshops]: /docs/bdd/discovery-workshop/
[User Story]: /docs/terms/user-story/
[User Stories]: /docs/terms/user-story/
================================================
FILE: docs/bdd/myths.md
================================================
---
sidebar_position: 5
---
# Myths about BDD
Let's bust some of the most common myths and misunderstandings about BDD.
## Myth: You can pick and choose the practices in any order
Here's [Liz Keogh's take](https://lizkeogh.com/2014/01/22/using-bdd-with-legacy-systems/) on this:
> having conversations is more important than capturing conversations is more important than automating conversations.
Unless you've already done effective discovery work, trying to formulate scenarios is a waste of time.
Similarly, you can't automate examples when you haven't done the work to figure out the most important examples to automate, or got your business stakeholder's feedback in how to word them.
## Myth: You can automate scenarios after the code is implemented
Many people use Cucumber to do test automation, to check for bugs after the code has already been implemented. That's a perfectly reasonable way to do test automation, but it's not BDD.
## Myth: Discovery doesn't need a conversation
We see plenty of teams who try to leave the work of identifying examples and turning them into formulated scenarios to a single individual on the team.
That's not BDD. Discovery work needs to be done _collaboratively_, bringing together representatives of the different specialists who all need to share understanding about what will be built.
## Myth: Using Cucumber means you're doing BDD
Just because you're using Cucumber, doesn't mean you're doing BDD. [There's much more to BDD than using Cucumber](/docs/bdd).
================================================
FILE: docs/bdd/who-does-what.md
================================================
---
sidebar_position: 6
---
# Who does what?
Who should be writing [Gherkin](/docs/gherkin/) documents, and who should write
[step definitions](/docs/cucumber/step-definitions)?
Product owners, business analysts, programmers and testers are often confused
about who should take on what responsibilities.
The answer depends on several factors, such as team structure, skills, culture,
process and more.
## The Three Amigos
*The Three Amigos* is a meeting that takes user stories and turns them into clean, thorough Gherkin scenarios. It involves three voices (at least):
- **The product owner** - This person is most concerned with the scope of the application. This involves translating user stories into a series of features. As the tester comes up with edge cases, the product owner is responsible for deciding what is within scope.
- **The tester** - This person will be generating lots of Scenarios, and lots of edge cases. How will the application break? What user stories have we not accounted for within these Features?
- **The developer** - This person will add many of the Steps to the Scenarios, and think of the details that go into each requirement. How will this application execute? What are some of the roadblocks or requirements behind the scenes?
These conversations can produce great tests, because each amigo sees
the product from a different perspective. For this reason it is *essential* that all of these roles have conversations to discover examples *together*.
[Example Mapping](/docs/bdd/example-mapping) and Event Storming are great collaborative analysis techniques for discovering examples.
Finally, there is no reason to limit these meetings to three people—or to hold only one such meeting at the beginning of the project. Continually refine your features and collaborate with everyone to best understand how to talk about, develop, and test your application.
## Writing Gherkin
To start with, when the language and style used in the scenarios
is still being established, it is recommended that the entire team collaborate on writing the Gherkin.
Later, it can be efficiently done by a pair: a developer (or someone who is responsible for the
automation) and a tester (or someone who is responsible for quality) as long as their
output is actively reviewed by the product owner (or business representative).
## Writing features
Cucumber tests are written in terms of “Features”. Each feature consists of one or more “Scenarios”.
Let’s start with an example Feature file:
```Gherkin
Feature: Explaining Cucumber
In order to gain an understanding of the Cucumber testing system
As a non-programmer
I want to have an overview of Cucumber that is understandable by non-geeks
Scenario: A worker seeks an overview of Cucumber
Given I have a coworker who knows a lot about Cucumber
When I ask my coworker to give an overview of how Cucumber works
And I listen to their explanation
Then I should have a basic understanding of Cucumber
```
Note that the scenarios do not go into the details of what the software
(or, in this case, the coworker) will do. It stays focused on the perspective of
the person the Feature is intended to serve (in this case, “a non-programmer”).
Every feature file has a single feature description at the top, but can have any
number of scenarios.
The `Feature` line names the feature. This should be a short label.
`In order to` presents the reason/justification for having the feature. In
general, this should match to one of the project’s core purposes or “business
values” such as:
- Protect revenue
- Increase revenue
- Manage cost
- Increase brand value
- Make the product remarkable
- Provide more value to your customers
`As a` describes the role of the people/users being served by the feature.
`I want` is a one sentence explanation of what the Feature is expected to do.
So, those three lines cover Why, Who, and What. Then, the document gets into the “How” with scenarios.
## Scenarios
You can have any number of scenarios for a feature.
If you have lots and lots of scenarios in one feature, you might
actually be describing *more* than one feature. When that happens, we recommend
splitting up the document into separate Feature definitions (The definition of
“lots and lots” here is subjective, and it's up to you to determine when it's time to split up a feature).
The first line provides a short description of what the scenario is intended to
cover. If you can’t describe your scenario in a single sentence (and not a
run-on sentence), then it’s probably trying to cover too much, and should be
split into multiple scenarios.
That is followed by some combination of “Steps”—lines that begin with the
keywords `Given`, `When`, and `Then` (typically in that order).
You can have many lines that use the same keyword (e.g., `Given there is something` followed by `Given I have another thing`). To increase the readability, you can substitute the keywords `And` or `But` (e.g., `Given there is something` followed by `And I have another thing`).
In general, any `Given` step line should describe only one thing. If you have
words like “and” in the middle of a step, you are probably describing more than
one step, and should split it into multiple steps.
For example:
```gherkin
When I fill in the "Name" field and the "Address" field
```
Becomes:
```gherkin
When I fill in the "Name" field
And I fill in the "Address" field
```
Cucumber features are best served by consistency. Don't say the same thing in
different ways — say it the same way every time.