📜 ⬆️ ⬇️

Guide: Cucumber + Java

Unfortunately, there is no magic formula for developing high-quality software, but it is obvious that testing improves its quality, and test automation improves the quality of testing itself.

In this article, we will look at one of the most popular frameworks for automating testing using the BDD approach - Cucumber. Also see how it works and what tools it provides.

Cucumber was originally developed by the Ruby community, but over time has been adapted for other popular programming languages. This article will look at the work of Cucumber in the Java language.

Gherkin


BDD tests are simple text, in human language, written in the form of a story (script) describing some behavior.
')
In Cucumber, Gherkin-notation is used to write tests, which defines the structure of the test and a set of keywords. The test is written to a file with the extension * .feature and can contain one or more scripts.

Consider an example of a test in Russian using Gherkin:

# language: ru @all :         PIN-      ,     PIN-  ,     PIN- :               PIN- @correct :       PIN-           @fail :       PIN-    ,   PIN-  

As can be seen from the example, the scripts are described in a simple non-technical language, so that any project participant can understand and write them.

Pay attention to the structure of the script:

1. Get the initial state of the system;
2. To do something;
3. Get a new system state.

In the example, keywords are bold. Below is a complete list of keywords in Russian:

  1. Given , Suppose , Let - are used to describe a preliminary, previously known state;
  2. When , If - is used to describe key actions;
  3. And , besides , also - used to describe additional preconditions or actions;
  4. Then , then - are used to describe the expected result of the action performed;
  5. But , And - are used to describe the additional expected result;
  6. Function , Functional , Property - is used to name and describe the tested functional. The description may be multi-line;
  7. Script - used to refer to the script;
  8. Background , Context - used to describe the actions performed before each script in the file;
  9. Script structure , Examples - used to create a script template and a table of parameters passed to it.

The keywords listed in clauses 1-5 are used to describe the steps of the script, Cucumber does not technically distinguish them. Instead, you can use the * symbol, but doing so is not recommended. These words have a definite purpose, and they were chosen precisely for it.

List of reserved characters:

# - indicates comments;
@ - tagging scripts or functionality;
| - separates data in a tabular format;
"" " - frames the multiline data.

The script begins with the line # language: ru. This line indicates Cucumber, that the script uses the Russian language. If you do not specify it, the framework, encountering a Russian text in the script, will throw a LexingError exception and the test will not run. The default is English.

Simple project


A Cucumber project consists of two parts - these are text files with script descriptions (* .feature) and files with implementation of steps in a programming language (in our case, * .java files).

To create a project, we will use the Apache Maven project build automation system.
First, add cucumber to the Maven dependency:

 <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-java</artifactId> <version>1.2.4</version> </dependency> 

To run the tests, we will use JUnit (it is possible to run through TestNG), for this we will add two more dependencies:

 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-junit</artifactId> <version>1.2.4</version> </dependency> 

The cucumber-junit library contains the cucumber.api.junit.Cucumber class, which allows you to run tests using the RunWith JUnit annotation. The class specified in this annotation determines how to run the tests.

Create a class that will be the entry point for our tests.

 import cucumber.api.CucumberOptions; import cucumber.api.SnippetType; import cucumber.api.junit.Cucumber; import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions( features = "src/test/features", glue = "ru.savkk.test", tags = "@all", dryRun = false, strict = false, snippets = SnippetType.UNDERSCORE, // name = "^|.*" ) public class RunnerTest { } 

Please note that the class name must have a Test end, otherwise the tests will not run.

Consider the options Cucumber:

  1. features - path to the folder with .feature files. The framework will search for files in this and all child folders. You can specify several folders, for example: features = {"src / test / features", "src / test / feat"};
  2. glue is a package containing classes with steps and hooks. You can specify several packages, for example, like this: glue = {"ru.savkk.test", "ru.savkk.hooks"};
  3. tags is a filter for running tests by tags. List of tags can be separated by commas. The ~ symbol excludes a test from the list of running tests, for example ~ @ fail;
  4. dryRun - if true, immediately after running the test, the framework checks whether all test steps are developed, if not, it gives a warning. If false, a warning will be issued upon reaching the undeveloped step. The default is false.
  5. strict - if true, then if an unworked step is encountered, the test will stop with an error. False - skipped undeveloped steps. The default is false.
  6. snippets - indicates in what format the framework will offer a template for unrealized steps. Available values: SnippetType.CAMELCASE, SnippetType.UNDERSCORE.
  7. name - filters launched tests by name satisfying a regular expression.

You cannot use the tags and name options to filter test runs.

Creating "features"

In the src / test / features folder we will create a file with the description of the tested functionality. We describe two simple withdrawal scenarios - successful and failure.

 # language: ru @withdrawal :     @success :           120000       20000       100000  @fail :     -        100       120     "   " 

Run

Let's try to run RunnerTest with the following settings:

 @RunWith(Cucumber.class) @CucumberOptions( features = "src/test/features", glue = "ru.savkk.test", tags = "@withdrawal", snippets = SnippetType.CAMELCASE ) public class RunnerTest { } 

The result of passing the test appeared in the console:

 Undefined scenarios: test.feature:6 # :      test.feature:12 # :     -   2 Scenarios (2 undefined) 6 Steps (6 undefined) 0m0,000s You can implement missing steps with the snippets below: @("^    (\\d+) $") public void (int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @("^    (\\d+) $") public void (int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @("^  \"([^\"]*)\"$") public void (String arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } 

Cucumber did not find the implementation of the steps and offered its templates for development.
Create the MyStepdefs class in the ru.savkk.test package and transfer the methods proposed by the framework to it:

 import cucumber.api.PendingException; import cucumber.api.java.ru.*; public class MyStepdefs { @("^    (\\d+) $") public void (int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @("^    (\\d+) $") public void (int arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } @("^  \"([^\"]*)\"$") public void (String arg1) throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } } 

When you run the test, Cucumber runs through the script step by step. Taking a step, he separates the keyword from the step description and tries to find in the Java classes of the package the specified in the glue option an annotation with a regular expression suitable for the description. Having found a match, the framework calls the method with the found annotation. If several regular expressions satisfy the step description, the framework throws an error.

As mentioned above, for Cucumber there is technically no difference in the keywords describing the steps; this is also true for the annotation, for example:

 @("^    (\\d+) $") 

and

 @("^    (\\d+) $") 

for the framework are the same.

What is written in brackets in regular expressions is passed to the method as an argument. The framework itself determines what needs to be passed from script to method as an argument. These numbers are (\\ d +). And the text, escaped in quotes - \ "([^ \"] *) \ ". This is the most common of the arguments passed.

The following table lists the elements used in regular expressions:
regular expressions:




.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .



.
(
)

2
j
.*
0
( )
Abracadabra
789-160-87


,
.+

( )
,
,
.
.{2}
(
)

22
$
JJ
.{1,3}

(
)


!
^

^aaa aaa
^aaa aaabbb
^aaa bbbaaa
$

aaa$ aaa
aaa$ aaabbb
aaa$ bbbaaa
\d*
[0-9]*
( )
12321

5323
\d+
[0-9]+

,
,
.
\w*
,
( )
_we
_1ee
Gfd4
\s
,

\t, \r
\n
"[^\"]*"
( )

"aaa"
""
"3213dsa"
?


abc?
ab
abc, b bc
|

aaa|bbb
aaa
bbb, aaabbb
()
. Cucumber

.
(\d+) 10 ,
10

(?: )
.
Cucumber
.
(\d+) (?:|) 3
, 3 ,
«» - .

Passing collections to arguments


Often there is a situation when it is necessary to transfer a set of data of the same type - collections to the method. Cucumber has several solutions for this task:

  1. The default framework wraps the data, separated by commas, in an ArrayList:

          , ,   

     @("^    (.*)$") public void (List<String> arg) { // -  } 

    To replace the delimiter, you can use the Delimiter annotation:

                

     @("^    (.+)$") public void (@Delimiter("  ") List<String> arg) { // -  } 

  2. Data written as a table with one column, Cucumber can also wrap in an ArrayList:

          |  | |  | |   | 

     @("^   $") public void (List<String> arg) { // -  } 

  3. The data recorded in the table with two columns, Cucumber can wrap in an associative array, where the data from the first column is the key, and from the second - the data:

          |  | true | |  | false | |   | true | 

     public void (Map<String, Boolean> arg) { // -  } 

  4. Data transfer in the form of a table with a large number of columns is possible in two ways:

    • Datatable

            |  | true | 5 | |  | false | 8 | |   | true | 2 | 

       @("^   $") public void (DataTable arg) { // -  } 

      DataTable is a class that emulates a tabular representation of data. It has a large number of methods for accessing data. Consider some of them:

       public <K,V> List<Map<K,V>> asMaps(Class<K> keyType,Class<V> valueType) 

      Converts a table to a list of associative arrays. The first row of the table is used for naming keys, the rest as values:

            |  |  |   | |  | true | 5 | |  | false | 8 | |   | true | 2 | 

       @("^   $") public void (DataTable arg) { List<Map<String, String>> table = arg.asMaps(String.class, String.class); System.out.println(table.get(0).get("")); System.out.println(table.get(1).get("")); System.out.println(table.get(2).get("")); } 

      This example will output to the console:





       public <T> List<List<T>> asLists(Class<T> itemType) 

      The method converts a table to a list of lists:

            |  | true | 5 | |  | false | 8 | |   | true | 2 | 

       @("^   $") public void (DataTable arg) { List<List<String>> table = arg.asLists(String.class); System.out.print(table.get(0).get(0) + " "); System.out.print(table.get(0).get(1) + " "); System.out.println(table.get(0).get(2) + " "); System.out.print(table.get(1).get(0) + " "); System.out.print(table.get(1).get(1) + " "); System.out.println(table.get(1).get(2) + " "); } 

      The console will display:

      true 5
      false 8


       public List<List<String>> cells(int firstRow) 

      This method does the same as the previous method, except that it is impossible to determine what type of data is in the table, always returns a list of rows - List. The method takes the first line number as an argument:

            |  | true | 5 | |  | false | 8 | |   | true | 2 | 

       @("^   $") public void (DataTable arg) { List<List<String>> table = arg.cells(1); System.out.print(table.get(0).get(0) + " "); System.out.print(table.get(0).get(1) + " "); System.out.println(table.get(0).get(2) + " "); System.out.print(table.get(1).get(0) + " "); System.out.print(table.get(1).get(1) + " "); System.out.println(table.get(1).get(2) + " "); } 

      The method will output to the console:

      false 8
      true 2


    • Class
      Cucumber can create objects from tabular data passed from a script. There are two ways to do this.

      For example, let's create the Menu class:

       public class Menu { private String title; private boolean isAvailable; private int subMenuCount; public String getTitle() { return title; } public boolean getAvailable() { return isAvailable; } public int getSubMenuCount() { return subMenuCount; } } 

      For the first method, we write the step in the script as follows:

            | title | isAvailable | subMenuCount | |  | true | 5 | |  | false | 8 | |   | true | 2 | 

      Implementation:

       @("^   $") public void (List<Menu> arg) { for (int i = 0; i < arg.size(); i++) { System.out.print(arg.get(i).getTitle() + " "); System.out.print(Boolean.toString(arg.get(i).getAvailable()) + " "); System.out.println(Integer.toString(arg.get(i).getSubMenuCount())); } } 

      Output to console:

      true 5
      false 8
      true 2


      The framework creates a linked list of objects from a table with three columns. The first row of the table should contain the names of the fields of the class of the created object. If a field is not specified, it will not be initialized.

      For the second method, we will take the script step to the following form:

            | title |  |  |   | | isAvailable | true | false | true | | subMenuCount | 5 | 8 | 2 | 

      And in the step description argument we use the @Transpose annotation.

       @("^   $") public void (@Transpose List<Menu> arg) { // -  } 

      Cucumber, as in the previous example, will create a linked list of objects, but, in this case, the names of the fields are recorded in the first column of the table.

  5. Multi-line arguments

    To pass multiline data to a method argument, they must be escaped with three double quotes:

          """        .        . """ 

    The data in the method comes in the form of an object of class String:

     @("^   $") public void (String expectedText) { // -  } 

Date


The framework independently provides data from the script to the data type specified in the argument of the method. If this is not possible, then throw a ConversionException exception. This is also true for the Date and Calendar classes. Consider an example:

     04.05.2017 

 @("^   (.+)$") public void  (Date arg) { // -  } 

Everything worked perfectly, Cucumber converted 04.05.2017 into a Date object with the value “Thu May 04 00:00:00 EET 2017”.

Consider another example:

     04-05-2017 

 @("^   (.+)$") public void  (Date arg) { // -  } 

Having reached this step, Cucumber threw an exception:

 cucumber.deps.com.thoughtworks.xstream.converters.ConversionException: Couldn't convert "04-05-2017" to an instance of: [class java.util.Date] 

Why did the first example work and the second one not?

The fact is that Cucumber has built-in support for date formats sensitive to the current locale. If you need to write the date in a format different from the format of the current locale, you must use the Format annotation:

     04-05-2017 

 @("^   (.+)$") public void  (@Format("dd-MM-yyyy") Date arg) { // -  } 

Script structure


There are cases when it is necessary to run the test several times with a different set of data; in such cases, the “Structure of the scenario” construction comes to the rescue:

 # language: ru @withdrawal :     @success  :           <>       <>       <>  : |  |  |  | | 10000 | 1 | 9999 | | 9999 | 9999 | 0 | 

The essence of this construction is that the data from the Examples table are inserted into the places designated by <> characters. The test will be run alternately for each row from this table. The names of the columns must match the name of the data insertion points.

Use hooks


Cucumber supports hooks (hooks) methods that run before or after a script. For their designation, the Before and After annotation is used. The class with hooks must be in the package specified in the options of the framework. An example of a class with hooks:

 import cucumber.api.java.After; import cucumber.api.java.Before; public class Hooks { @Before public void prepareData() { //  } @After public void clearData() { //  } } 

The c annotation method Before will run before each script, After - after.

Execution order


The hakam can set the order in which they will be executed. To do this, you must specify the order parameter in the annotation. The default order value is 10000.

For Before, the smaller this value is, the earlier the method will be executed:

 @Before(order = 10) public void connectToServer() { //   } @Before(order = 20) public void prepareData() { //  } 

In this example, the connectToServer () method is executed first, then prepareData ().

After working in the reverse order.

Tagging


In the value parameter, you can specify script tags for which hooks will work. The symbol ~ means "except." Example:

 @Before(value = "@correct", order = 30) public void connectToServer() { // - } @Before(value = "~@fail", order = 20) public void prepareData() { // - } 

The connectToServer method will be executed for all scripts with the correct tag, the prepareData method for all scripts with the exception of scripts with the fail tag.

Scenario class


If you specify an object of the Scenario class in the definition of the hook method in the argument, then this method will provide you with a lot of useful information about the running script, for example:

 @After public void getScenarioInfo(Scenario scenario) { System.out.println(scenario.getId()); System.out.println(scenario.getName()); System.out.println(scenario.getStatus()); System.out.println(scenario.isFailed()); System.out.println(scenario.getSourceTagNames()); } 

For the script:

 # language: ru @all :         PIN-           PIN-       PIN- :               PIN- @correct :       PIN-           

Print to console:

--;-

passed
false
[@correct, @all]


Finally


Cucumber is a very powerful and flexible framework that can be used in conjunction with many other popular tools. For example, with Selenium - a framework for automating web applications, or Yandex.Allure - a library that allows you to create convenient reports.
Good luck to everyone in automation.

Source: https://habr.com/ru/post/332754/


All Articles