Вы находитесь на странице: 1из 6

27/05/2019 Cucumber Utils - CodeProject

Cucumber Utils
Slevoaca Florin, 22 May 2019

A little helper for writing Cucumber Java tests

Download latest Repository Archive


Download local copy

Summary
A Java library meant to help you write organized and clean Cucumber tests.
It takes over the usual dependencies and features needed inside a test framework, such as:

Compare mechanism (compare XMLs, JSONs, and Java objects)


A light and powerful state-sharing mechanism between Cucumber Scenario Steps
Customized clients to access various resources, i.e databases, HTTP services, etc
Predefined Cucumber utility steps
other utility methods

Most of these features can be used directly from code within your test project and are also available as Cucumber step definitions.

Tutorial
Follow the Cucumber Utils Tutorial for a better picture on how this library is/should be used.

Maven Central

<dependency>
<groupId>io.github.fslev</groupId>
<artifactId>cucumber-utils</artifactId>
<version>${latest.version}</version>
</dependency>

Gradle: compile("io.github.fslev:cucumber-utils:${latest.version}")

Included dependencies that are worth to mention:

cucumber-java8
cucumber-guice
xml-unit
json-compare
apache-http-client

Configuration
https://www.codeproject.com/Articles/4457112/Cucumber-Utils?display=Print 1/6
27/05/2019 Cucumber Utils - CodeProject

In order to integrate cucumber-utils within your test project you must configure the following glue package inside your IDE
Cucumber plugin or / and inside the code:

com.cucumber.utils

Features

1. Compare mechanism
The following types of objects are supported for complex comparison, via the Cucumbers class:

JSONs (String, JsonNode)

dependency: json-compare

String expected = "{\"!b\":val1\",\"a\":\"val2\"}";


String actual = "{\"a\":\"val2\",\"c\":\"val1\"}";
cucumbers.compare(expected, actual); //comparison passes

JSON convertible Java objects

List<String> expected = Arrays.asList(new String[]{"a", "b", "c", ".*"});


List<String> actual = Arrays.asList(new String[]{"c", "a", "c", "b"});
cucumbers.compare(expected, actual); //comparison passes

XMLs

dependency: xml-unit

String expected = "<struct><int a=1>some .* text</int><boolean>false</boolean></struct>";


String actual = "<struct><int a=1>some dummy text</int><boolean>false</boolean></struct>";
cucumbers.compare(expected, actual); //comparison passes

Strings, with regex support

String expected = "some .* text";


String actual = "some dummy text";
cucumbers.compare(expected, actual); //comparison passes

If the objects compared are not of any type from above, then the comparison is done via the equals() method.

1.1 Poll and compare


Compare until condition is met or until timeout:

// Compare every 1000 millis until generated random number is 3 or until total time duration is
10s
int expected = 3;
cucumbers.pollAndCompare(expected, 1000, 10, () -> generateRandomNumber());

2. State-sharing mechanism
The state sharing mechanism is based on guice, cucumber-guice and Cucumber anonymous parameter types.
State is shared between different Cucumber steps inside same scenario by using scenario properties.

2.1 How to set and use scenario properties

https://www.codeproject.com/Articles/4457112/Cucumber-Utils?display=Print 2/6
27/05/2019 Cucumber Utils - CodeProject

within the Cucumber Scenario, by using the param <name>="<value>" Cucumber step

Scenario: Test scenario properties


Given param animal="rabbit"
And param location="forest"
And the string with scenario properties "The #[animal] is running through the #[location]"
Then check string equals "The rabbit is running through the forest"

As you can see, in order to use the value of a scenario property within your Cucumber scenario, you must call it by its name, using
the special symbols #[ ].
Under the hood: If your Cucumber step definition uses anonymous parameter types {}, then any #[property.name] sequence is
parsed and the corresponding value is mapped to the corresponding argument:

@Given("the string with scenario properties \"{}\"")


public void setString(String str) {
this.str = str;
//taking the example above, the str parsed value is "The rabbit is running through the
forest"
}

from resource file, via load scenario props from file "relative/path/to/file.properties" Cucumber step

Scenario: Test scenario properties


* load scenario props from file "placeholders/scenario.properties"
Then COMPARE #[animal] with "Rabbit"

where, scenario.properties file contains:

animal=Rabbit

Note: Supported file types for setting scenario properties:

.properties
.yaml
.property
.json
.xml
.txt

If a scenario property is read from a .property, .json, .xml or .txt file, then the name of the scenario property will actually be the
name of the file, without extension:

Scenario: Test placeholder fill with scenario property file


* load scenario props from file "placeholders/animal.property"
Then COMPARE #[animal] with "Rabbit"

where, animal.property file contains:

Rabbit

from resource directory, via load all scenario props from dir "relative/path/to/dir" Cucumber step

* load all scenario props from dir "placeholders/properties"


Given The string with scenario placeholders "Soda=#[soda], food=#[food], whisky=#[whisky],
burger=#[burger] and cheese=#[cheese]"
Then Check filled string equals "Soda=Coca-Cola, food=burger, whisky=Johnny Walker,
burger=Cheeseburger and cheese=Mozzarela"

where, inside the properties directory are defined several files containing the corresponding properties.

Note:
The function for reading scenario properties from a directory walks through the whole directory tree structure. It filters only the
supported file types.

https://www.codeproject.com/Articles/4457112/Cucumber-Utils?display=Print 3/6
27/05/2019 Cucumber Utils - CodeProject

programmatically, by injecting the a ScenarioProps class instance via Guice:

import com.google.inject.Inject;

@ScenarioScoped
public class ParamSteps {

@Inject
private ScenarioProps scenarioProps;

public void setProp(String name, String value) {


scenarioProps.put(name, value);
}
}

Another way to set scenario properties is from the compare mechanism:


Suppose you want to extract a value from the JSON response received after calling the API of an application.
In order to do that, you must compare the actual response with an expected one, but inside the expected value you must
introduce a special placeholder ~[property.name].

Example:

Scenario: Test scenario properties


When invoke HTTP API Create user
Then check response body="{"id":"~[userId]"}"

If comparison passes, then a new scenario property will be set, having the name userId and the value matched from the HTTP
response.
This new scenario property can be used further inside your test scenario:

When invoke HTTP API Get user with id = #[userId]


Then check HTTP response status = 200

3. Customized clients
The following clients are available via Cucumber-Utils:

HTTP client
SQL clients (MySQL, PostgreSQL, Sybase, etc -> depending on the sql driver you configure)
Shell and Jsch clients

These clients are initialized and configured via the builder pattern, in order to allow construction of new settings between Cucumber
steps.

HTTP Client
Example:

HttpClient client = new HttpClient.Builder()


.address("http://example.com")
.path("/user/")
.method(Method.POST)
.addHeader("auth", "authCode")
.addQueryParam("host","google.ro")
.entity("{\"a\":\"some json value\"}")
.build();
HttpResponse response = client.execute();
String responseAsString = EntityUtils.toString(response.getEntity());

4. Predefined Cucumber utility steps


https://www.codeproject.com/Articles/4457112/Cucumber-Utils?display=Print 4/6
27/05/2019 Cucumber Utils - CodeProject

Set scenario properties

* load all scenario props from dir "relativePath/to/dir"


* load scenario props from file "relativePath/to/file"
Given param a="1"

Compare simple values

Given param a="1"


And param b="1"
Then COMPARE #[a] with "#[b]"
Given param json1 =
"""
{
"name": "J.*n",
"age": "\\d+",
}
"""
And param json2=
"""
{
"name": "John",
"age": 30,
}
"""
Then COMPARE #[json1] with "#[json2]"

Compare date times

Given DateTime pattern="yyyy-MM-dd HH:mm:ss"


Then DateTime check period from "2018-02-03 01:00:00" to "2019-02-03 01:00:00" is 1year
And DateTime check period from "2018-02-03 01:00:00" to "2019-02-02 12:01:10" is 364days
And DateTime check period from "2019-02-03 01:02:12" to "2019-02-03 23:59:10" is 22hours
And DateTime check period from "2019-02-03 22:02:12" to "2019-02-03 23:59:10" is 116minutes
And DateTime check period from "2019-02-03 23:58:12" to "2019-02-03 23:59:10" is 58seconds

Connect to SQL databases, execute queries, compare results and also execute updates

Scenario: Test MYSQL client select


Given SQL data source from file path "config/database/mysql.properties"
Then SQL execute query "select * from gift order by person_id asc limit 3" and compare result
with
| person_id | gift |
| .* | .* |
| 21189037 | fun & joy for everybody! |
| 21193939 | Leica M9-P Hermes Edition: http://vimeo.com/42108675 |

Scenario: Test POSTGRESQL client simple insert with tabular data


Given SQL data source from file path "config/database/psql.properties"
Then SQL INSERT into table "mag" the following data
| person_id | description |
| 14 | http://heheheh.ro |
| 16 | null |
| 17 | wow |

Execute shell / bash commands:

* SHELL execute command "ls -alh" and check response=".*"

Connect via SSH to a remote server and execute bash commands:

Given JSCH connection from properties file "config/jsch/jsch.properties"


Then JSCH execute command "hostname -f" and check response="vm-test\d+.sandbox.lan"

https://www.codeproject.com/Articles/4457112/Cucumber-Utils?display=Print 5/6
27/05/2019 Cucumber Utils - CodeProject

where jsch.properties contains:

host=vm-test1.sandbox.lan
port=22
user=tanja
password=*****
privateKey=/home/tanja/.ssh/id_rsa

License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author


Slevoaca FlorinNo Biography provided
Romania

Comments and Discussions


0 messages have been posted for this article Visit https://www.codeproject.com/Articles/4457112/Cucumber-Utils to post
and view comments on this article, or click here to get a print view with messages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile Article Copyright 2019 by Slevoaca Florin
Web04 | 2.8.190526.1 | Last Updated 22 May 2019 Everything else Copyright © CodeProject, 1999-2019

https://www.codeproject.com/Articles/4457112/Cucumber-Utils?display=Print 6/6

Вам также может понравиться