• Stars
    star
    179
  • Rank 214,039 (Top 5 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created about 7 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A skeleton project for Serenity BDD and Cucumber JVM

Getting started with Serenity and Cucumber

Serenity BDD is a library that makes it easier to write high quality automated acceptance tests, with powerful reporting and living documentation features. It has strong support for both web testing with Selenium, and API testing using RestAssured.

Serenity strongly encourages good test automation design, and supports several design patterns, including classic Page Objects, the newer Lean Page Objects/ Action Classes approach, and the more sophisticated and flexible Screenplay pattern.

The latest version of Serenity supports Cucumber 6.x.

The starter project

The best place to start with Serenity and Cucumber is to clone or download the starter project on Github (https://github.com/serenity-bdd/serenity-cucumber-starter). This project gives you a basic project setup, along with some sample tests and supporting classes. There are two versions to choose from. The master branch uses a more classic approach, using action classes and lightweight page objects, whereas the screenplay branch shows the same sample test implemented using Screenplay.

The project directory structure

The project has build scripts for both Maven and Gradle, and follows the standard directory structure used in most Serenity projects:

src
  + main
  + test
    + java                        Test runners and supporting code
    + resources
      + features                  Feature files

    + search                  Feature file subdirectories

             search_by_keyword.feature

Serenity 2.2.13 introduced integration with WebdriverManager to download webdriver binaries.

The sample scenario

Both variations of the sample project uses the sample Cucumber scenario. In this scenario, Sergey (who likes to search for stuff) is performing a search on the internet:

Feature: Search by keyword

  Scenario: Searching for a term
    Given Sergey is researching things on the internet
    When he looks up "Cucumber"
    Then he should see information about "Cucumber"

The Screenplay implementation

The sample code in the master branch uses the Screenplay pattern. The Screenplay pattern describes tests in terms of actors and the tasks they perform. Tasks are represented as objects performed by an actor, rather than methods. This makes them more flexible and composable, at the cost of being a bit more wordy. Here is an example:

    @Given("{actor} is researching things on the internet")
    public void researchingThings(Actor actor) {
        actor.wasAbleTo(NavigateTo.theWikipediaHomePage());
    }

    @When("{actor} looks up {string}")
    public void searchesFor(Actor actor, String term) {
        actor.attemptsTo(
                LookForInformation.about(term)
        );
    }

    @Then("{actor} should see information about {string}")
    public void should_see_information_about(Actor actor, String term) {
        actor.attemptsTo(
                Ensure.that(WikipediaArticle.HEADING).hasText(term)
        );
    }

Screenplay classes emphasise reusable components and a very readable declarative style, whereas Lean Page Objects and Action Classes (that you can see further down) opt for a more imperative style.

The NavigateTo class is responsible for opening the Wikipedia home page:

public class NavigateTo {
    public static Performable theWikipediaHomePage() {
        return Task.where("{0} opens the Wikipedia home page",
                Open.browserOn().the(WikipediaHomePage.class));
    }
}

The LookForInformation class does the actual search:

public class LookForInformation {
    public static Performable about(String searchTerm) {
        return Task.where("{0} searches for '" + searchTerm + "'",
                Enter.theValue(searchTerm)
                        .into(SearchForm.SEARCH_FIELD)
                        .thenHit(Keys.ENTER)
        );
    }
}

In Screenplay, we keep track of locators in light weight page or component objects, like this one:

class SearchForm {
    static Target SEARCH_FIELD = Target.the("search field")
                                       .locatedBy("#searchInput");

}

The Screenplay DSL is rich and flexible, and well suited to teams working on large test automation projects with many team members, and who are reasonably comfortable with Java and design patterns.

The Action Classes implementation.

A more imperative-style implementation using the Action Classes pattern can be found in the action-classes branch. The glue code in this version looks this this:

    @Given("^(?:.*) is researching things on the internet")
    public void i_am_on_the_Wikipedia_home_page() {
        navigateTo.theHomePage();
    }

    @When("she/he looks up {string}")
    public void i_search_for(String term) {
        searchFor.term(term);
    }

    @Then("she/he should see information about {string}")
    public void all_the_result_titles_should_contain_the_word(String term) {
        assertThat(searchResult.displayed()).contains(term);
    }

These classes are declared using the Serenity @Steps annotation, shown below:

    @Steps
    NavigateTo navigateTo;

    @Steps
    SearchFor searchFor;

    @Steps
    SearchResult searchResult;

The @Stepsannotation tells Serenity to create a new instance of the class, and inject any other steps or page objects that this instance might need.

Each action class models a particular facet of user behaviour: navigating to a particular page, performing a search, or retrieving the results of a search. These classes are designed to be small and self-contained, which makes them more stable and easier to maintain.

The NavigateTo class is an example of a very simple action class. In a larger application, it might have some other methods related to high level navigation, but in our sample project, it just needs to open the DuckDuckGo home page:

public class NavigateTo {

    WikipediaHomePage homePage;

    @Step("Open the Wikipedia home page")
    public void theHomePage() {
        homePage.open();
    }
}

It does this using a standard Serenity Page Object. Page Objects are often very minimal, storing just the URL of the page itself:

@DefaultUrl("https://wikipedia.org")
public class WikipediaHomePage extends PageObject {}

The second class, SearchFor, is an interaction class. It needs to interact with the web page, and to enable this, we make the class extend the Serenity UIInteractionSteps. This gives the class full access to the powerful Serenity WebDriver API, including the $() method used below, which locates a web element using a By locator or an XPath or CSS expression:

public class SearchFor extends UIInteractionSteps {

    @Step("Search for term {0}")
    public void term(String term) {
        $(SearchForm.SEARCH_FIELD).clear();
        $(SearchForm.SEARCH_FIELD).sendKeys(term, Keys.ENTER);
    }
}

The SearchForm class is typical of a light-weight Page Object: it is responsible uniquely for locating elements on the page, and it does this by defining locators or occasionally by resolving web elements dynamically.

class SearchForm {
    static By SEARCH_FIELD = By.cssSelector("#searchInput");
}

The last step library class used in the step definition code is the SearchResult class. The job of this class is to query the web page, and retrieve a list of search results that we can use in the AssertJ assertion at the end of the test. This class also extends UIInteractionSteps and

public class SearchResult extends UIInteractionSteps {
    public String displayed() {
        return find(WikipediaArticle.HEADING).getText();
    }
}

The WikipediaArticle class is a lean Page Object that locates the article titles on the results page:

public class WikipediaArticle {
    public static final By HEADING =  By.id("firstHeading");
}

The main advantage of the approach used in this example is not in the lines of code written, although Serenity does reduce a lot of the boilerplate code that you would normally need to write in a web test. The real advantage is in the use of many small, stable classes, each of which focuses on a single job. This application of the Single Responsibility Principle goes a long way to making the test code more stable, easier to understand, and easier to maintain.

Executing the tests

To run the sample project, you can either just run the CucumberTestSuite test runner class, or run either mvn verify or gradle test from the command line.

By default, the tests will run using Chrome. You can run them in Firefox by overriding the driver system property, e.g.

$ mvn clean verify -Ddriver=firefox

Or

$ gradle clean test -Pdriver=firefox

The test results will be recorded in the target/site/serenity directory.

Generating the reports

Since the Serenity reports contain aggregate information about all of the tests, they are not generated after each individual test (as this would be extremenly inefficient). Rather, The Full Serenity reports are generated by the serenity-maven-plugin. You can trigger this by running mvn serenity:aggregate from the command line or from your IDE.

They reports are also integrated into the Maven build process: the following code in the pom.xml file causes the reports to be generated automatically once all the tests have completed when you run mvn verify?

             <plugin>
                <groupId>net.serenity-bdd.maven.plugins</groupId>
                <artifactId>serenity-maven-plugin</artifactId>
                <version>${serenity.maven.version}</version>
                <configuration>
                    <tags>${tags}</tags>
                </configuration>
                <executions>
                    <execution>
                        <id>serenity-reports</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>aggregate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Simplified WebDriver configuration and other Serenity extras

The sample projects both use some Serenity features which make configuring the tests easier. In particular, Serenity uses the serenity.conf file in the src/test/resources directory to configure test execution options.

Webdriver configuration

The WebDriver configuration is managed entirely from this file, as illustrated below:

webdriver {
    driver = chrome
}
headless.mode = true

chrome.switches="""--start-maximized;--test-type;--no-sandbox;--ignore-certificate-errors;
                   --disable-popup-blocking;--disable-default-apps;--disable-extensions-file-access-check;
                   --incognito;--disable-infobars,--disable-gpu"""

Serenity uses WebDriverManager to download the WebDriver binaries automatically before the tests are executed.

Environment-specific configurations

We can also configure environment-specific properties and options, so that the tests can be run in different environments. Here, we configure three environments, dev, staging and prod, with different starting URLs for each:

environments {
  default {
    webdriver.base.url = "https://duckduckgo.com"
  }
  dev {
    webdriver.base.url = "https://duckduckgo.com/dev"
  }
  staging {
    webdriver.base.url = "https://duckduckgo.com/staging"
  }
  prod {
    webdriver.base.url = "https://duckduckgo.com/prod"
  }
}

You use the environment system property to determine which environment to run against. For example to run the tests in the staging environment, you could run:

$ mvn clean verify -Denvironment=staging

See this article for more details about this feature.

Want to learn more?

For more information about Serenity BDD, you can read the Serenity BDD Book, the official online Serenity documentation source. Other sources include:

More Repositories

1

serenity-core

Serenity BDD is a test automation library designed to make writing automated acceptance tests easier, and more fun.
HTML
715
star
2

serenity-cucumber

Cucumber integration for the Serenity BDD Reporting library
Java
78
star
3

serenity-demos

Java
64
star
4

screenplay-pattern-todomvc

Java
60
star
5

serenity-junit-starter

Java
53
star
6

serenity-cucumber4-starter

Java
48
star
7

serenity-articles

Source code for articles published about Serenity
HTML
45
star
8

the-serenity-book

A book about Serenity BDD
Java
41
star
9

serenity-documentation

The main Serenity BDD documentation
Java
40
star
10

serenity-jbehave

The Serenity integration for JBehave
Java
39
star
11

bdd-trader

The BDD Trader application is a demo application used for exercises in the Serenity Dojo BDD workshops
Java
27
star
12

serenity-rest-starter

Java
26
star
13

serenity-maven-plugin

JavaScript
19
star
14

serenity-jira

Java
14
star
15

serenity-cucumber5

Java
14
star
16

serenity-cucumber4

Java
13
star
17

serenity-cucumber6

Java
11
star
18

serenity-screenplay-train-demo

Java
11
star
19

serenity-rest-taxi-stands

Java
11
star
20

tutorials

Java
10
star
21

serenity-junit-screenplay-starter

Java
9
star
22

serenity-maven-archetypes

Java
7
star
23

serenity-banking-demo

Gherkin
7
star
24

journey-planner

A sample application illustrating Serenity Screenplay with Cucumber
Java
6
star
25

serenity-journey-demo

Java
6
star
26

serenity-bdd.github.io

Serenity BDD Documentation
HTML
6
star
27

serenity-exercises

Simple exercises using Serenity BDD
Java
5
star
28

serenity-jbehave-starter

Java
4
star
29

serenity-docs

Antora configuration project for the Serenity documentation
HTML
3
star
30

serenity-cucumber-page-objects-starter

Java
3
star
31

serenity-cli

An (experimental) command line interface for Serenity BDD
JavaScript
3
star
32

serenity-cucumber5-starter

Java
3
star
33

serenity-test-projects

Java
2
star
34

flying-high-tutorial

Java
2
star
35

serenity-junit-pageobjects-starter

Project template using Serenity BDD, JUnit 5 and Page Objects.
Java
2
star
36

typesafe-config-tutorial

Java
2
star
37

documentation

JavaScript
2
star
38

bdd-starter

Java
2
star
39

todomvc-screenplay-tutorial

Java
1
star
40

serenity-gradle-plugin

Groovy
1
star
41

serenity-cucumber4-smoketests

Java
1
star