First Cucumber JVM project

Context

The pre-requisites for this section are

  1. Install JDK
  2. Install and configure Maven
  3. Install and configure Eclipse (with plugins) OR Install IntelliJ Community Edition
  4. Set up selenium webdriver components

We also assume that you have a basic understanding on how to set up Selenium on your machine. If not, please complete the steps as listed below. You will need only these client components, the rest of the api’s will be gotten from Maven dependencies as jar.

  1. Set up Selenium Components

The GitHub code base for this project can be downloaded if you are self learner and not go through the below steps.

 

Agenda

Here we will write our first cucumber-jvm project that uses Selenium java libraries and opens a browser.

  1. Download template project and import in to eclipse
  2. cucumber-jvm and other dependent jars
  3. Project structure
  4. Cucumber first feature
  5. Write step definitions (automation code)
  6. Hooks (pre and post conditions)
  7. Runner class
  8. Execution from Eclipse and Command line
  9. Results
  10. Closing Thoughts

1) Download template project

Download cucumber-jvm-template project from github [or checkout if you are comfortable using git]. Unzip the project on your file system. I unzipped it into C:\GitProjects\some folder\cucumber-jvm-template

download_template_project

Import it in Eclipse as Maven project

Click File – Import in Eclipse and select the below option

existing_maven

Then point it to the directory where you download the project. In my case as mentioned above, I copy pasted the location of the directory as below. Then CHECK the box against pom.xml and then finish. The project should appear in Eclipse now

maven_project_import

2)cucumber-jvm and dependent jars

So far we have been talking only about set up. But where is cucumber-jvm and other jars. This is where we look into pom.xml, which has all necessary dependent information that is required for this project

The libraries or dependent jars that we will use are

  • cucumber-java: This library is being developed and is dependent on cucumber-core, which has most of the core api’s
  • cucumber-testng: cucumber can be run through testng too
  • cucumber-junit: This is the most popular way to kick off cucumber tests written in java
  • selenium-java: Selenium jars that are required for our browser based tests.
  • junit, log4j, apache-poi, xmlapis, xerces: All of these jars will be used over time.
  • maven-surefire plugin: This plugin is used for kicking off junit, testng and java main classes etc. It just makes life easy

pomxml

 

3)Project structure

template_project_structure

  • src/main/java: This will ideally contain source code
  • src/test/java: This will contain all java code that runs automation
  • src/test/resources: This will contain our feature files
  • BlankStepDefs.java: This file contains the step definitions. We will explain below. There can be any number of such files with different names [java classes]
  • Hooks.java: I have put this class so that we can have @Before and @After hooks for cucumber in one place. This contains the code for pre and post conditions of every scenario run.
  • RunCukesTest.java: This file contains the logic that will kick off the cucumber scenarios and other cucumber options that might be required.
  • features: This folder contains all the feature files

As you might have guessed by this time, this is NOT the only way to organize the files. However this is “one” way.

4)Cucumber First feature

Lets write our first cucumber feature (well in this case already written, but in the video below you can see how to write a new one.

We intend to open seleniumframework website and print its title and url. The assumption we are making here is that you already are aware of Selenium API’s. So we are not going to explain those. Feel free to read the Basic Tutorial on this website if you need a refresher.

5)Step Definitions

The corresponding step definitions are as below.

The explanation is as below

  1. I have a WebDriver variable that has a reference to the browser. So when this class is initialized, I assign the static webdriver (from hooks, we will discuss hooks below) to this variable
  2. The first step definition i.e. just enters the url in the browser and opens the website
  3. The second step definition validates that the title and URL of the page is what we expect. Here I have used testng assertEquals. However feel free to use any assertion mechanism you might be comfortable to use

6) Cucumber hooks

We talked about Cucumber hooks in our Basic tutorial, so read that if you need a refresher. In the below hooks file, we have @Before and @After – You can consider them as pre and post conditions for every scenario that runs. For example, we might want to open a browser before every scenario right. Similarly, we might want to close the browser after scenario executes.

Important pieces of explanation below

  • openBrowser: This method instantiates a new driver and assigns it to the static webdriver variable that Hooks class has. This webdriver variable will be used across the entire session of the cucumber scenario
  • embedScreenshot: I included this method, so that if scenario fails for some reason, we can take a screenshot and embed it inline in the html report that cucumber produces. This method also quits the driver at the end

7) Cucumber Runner

There are multiple ways to run cucumber-jvm and some of them are

  • cucumber cli: Call cucumber.api.Main class directly by placing all your jars and classes in java classpath.
  • JUnit Runner: Use the annotation @RunWith that Junit provides and hand off the control to Cucumber class. I found this very convenient, so we will be using this mechanism here
  • TestNG Runner: We can extent the AbstractTestNGCucumber Runner . In subsequent classes, we will see how this works
  • More: There are more coming on the way 😉

We define a class and put the below code in it. The maintenance we would have to do on this class is to add or remove cucumber options over time. However this can be overridden by passing command line arguments too. See the video below on how we can use command line

CucumberOptions

So obviously there are many options we can use here. The ones I have used so far are [We will cover each of them over time with examples]

8)Execution

Now lets go ahead and run this basic example. There are two ways to run it. First let’s start with eclipse IDE

Right click on the area where scenario is defined in the feature file and Run As –

eclipse_runas_cucumber

You should see browser popping up on your machine and the results in eclipse should look something like this

cucumber_feature_pass

Where are my colors ?

Thats a good question. Remember we installed ANSI plugin in the previous section when we configured eclipse. That is the one which will escape any ANSI characters [on some machines the ansi characters look very garbled]. So lets enable the plugin as below.

ansi_plugin

By default the “monochrome” option is set for cucumber eclipse plugin [even for cucumber main class if we run it otherwise] . So we need to disable that to see colors. So where is it found? When you go to Run as – Run Configurations

monochrome_disable

Now go ahead and run the feature again with the settings done above. It should be green as cucumber now 🙂

green_cucumber_pass

 

9) Command line Execution

Go to the root folder of the project in command line and type “mvn clean test”. This should pass too.

mvn_test_command

10) More Results:

The cucumber html report is produced in /target/cucumber-html-report folder [as we specified that folder in Cucumber Runner class] . Open the index.html and you can see the output.

cucumber_html_reports

Obviously at this point, you might be thinking how to extend it to Continuous Test Automation pattern implementation and execute it on a CI server. The json results would definitely help there

Closing Thoughts

So we have seen one thin slice of how we can use cucumber-jvm and get pretty much the same experience what we get in the Ruby world. There are definitely some improvements and enhancements in the library overall, but from my perspective, it is usable and can be implemented in a real-time environment.

If you liked this post, please follow me on github and fork my repositories, contribute. I would appreciate your feedback.