You are on page 1of 49

 

Test automation fundamentals

 
www.qaitive.rs
 

Content

Table of Contents
WHAT IS AUTOMATION TESTING? 3

WHY AUTOMATED TESTING? 4

WHICH TEST CASES TO AUTOMATE? 4

SELENIUM 5

WHAT IS WEBDRIVER? 5

WHAT IS SELENIUM GRID? 6

SETUP MAVEN AND JDK ON WINDOWS OPERATING SYSTEM 7

SETUP PROJECT IN INTELLIJ IDEA 12

FIRST SELENIUM WEBDRIVER SCRIPT: JAVA CODE EXAMPLE 16

WEB ELEMENTS AND LOCATORS 17


DOM (Document object model) 17
Web element tags 18
Web element attributes 18
Types of locators 18
Inspect 19
Ranorex Selocity 19
CSS locators 19
XPath 21

Selenium Commands 22
Instantiating Web Elements 22
Select tag 27

CUCUMBER 28
WHAT IS A "FEATURE FILE"? 28

 
www.qaitive.rs
 

GHERKIN 29
Feature file in detail 30
Scenario 30
Steps 31
Given 31
When 31
Then 31
Scenario Outline 31
Step Definitions 32
Steps Definitions 33
Example of Step Definition File 34
Excercise 34

JENKINS 39
What is Jenkins? 39
Example for Jenkins job 39

Appendix 1: Tips and tricks 45

WHAT IS AUTOMATION TESTING?


Manual Testing is performed by a human sitting in front of a computer carefully executing the test steps.

Automation Testing means using an automation tool to execute your test case suite.

The automation software can also enter test data into the System Under Test , compare expected and
actual results and generate detailed test reports.

Test Automation demands considerable investments of money and resources.

Successive development cycles will require execution of same test suite repeatedly.

Using a test automation tool it's possible to record this test suite and re-play it as required.

Once the test suite is automated, no human intervention is required .

Goal of Automation is to reduce number of test cases to be run manually and not eliminate Manual Testing
all together.

 
www.qaitive.rs
 

WHY AUTOMATED TESTING?

Automated software testing is important due to following reasons:

Manual Testing of all work flows, all fields , all negative scenarios is time and cost consuming
It is difficult to test for multi lingual sites manually
Automation does not require Human intervention. You can run automated test unattended
(overnight)
Automation increases speed of test execution
Automation helps increase Test Coverage
Manual Testing can become boring and hence error prone.

WHICH TEST CASES TO AUTOMATE?

Test cases to be automated can be selected using the following criterion to increase the automation
ROI

High Risk - Business Critical test cases


Test cases that are executed repeatedly
Test Cases that are very tedious or difficult to perform manually
Test Cases which are time consuming

The following category of test cases are not suitable for automation:

Test Cases that are newly designed and not executed manually atleast once
Test Cases for which the requirements are changing frequently
Test cases which are executed on ad-hoc basis.

Automated Testing Process:

Following steps are followed in an Automation Process

 
www.qaitive.rs
 

Define the scope of Automation

Scope of automation is the area of your Application Under Test which will be automated. Following
points help determine scope:

Feature that are important for the business


Scenarios which have ​large amount of data
Common functionalities​ across applications
Technical feasibility
Extent to which business components are reused
Complexity​ of test cases
Ability to use the same test cases for cross browser testing

SELENIUM
Selenium is a free (open source) automated testing suite for web applications across different
browsers and platforms.

WHAT IS WEBDRIVER?
WebDriver is a web automation framework that allows you to execute your tests against different
browsers, not just Firefox.

WebDriver also enables you to use a programming language in creating your test scripts.

You can now use conditional operations like if-then-else or switch-case


You can also perform looping like do-while.

Following programming languages are supported by WebDriver

Java
.Net
PHP

 
www.qaitive.rs
 

Python
Perl
Ruby

You do not have to know all of them. You just need to be knowledgeable in one. However, in this
tutorial, we will be using Java with IntelliJ IDEA as our IDE.

WHAT IS SELENIUM GRID?


Selenium Grid is a part of the Selenium Suite that specializes in running multiple tests across
different browsers, operating systems, and machines in parallel.

Selenium Grid uses a hub-node concept where you only run the test on a single machine called a
hub, but the execution will be done by different machines called nodes.

When to Use Selenium Grid?

You should use Selenium Grid when you want to do either one or both of following:

Run your tests against different browsers, operating systems, and machines all at the same
time. This will ensure that the application you are Testing is fully compatible with a wide
range of browser-OS combinations.
Save time in the execution of your test suites. If you set up Selenium Grid to run, say, 4 tests
at a time, then you would be able to finish the whole suite around 4 times faster.

Selenium Grid Architecture

 
www.qaitive.rs
 

The Hub

The hub is the central point where you load your tests into.
There should only be one hub in a grid.
The hub is launched only on a single machine, for example, a computer whose OS is
Windows 7 and whose browser is IE.
The machine containing the hub is where the tests will be run, but you will see the browser
being automated on the node.

The Nodes

Nodes are the Selenium instances that will execute the tests that you loaded on the hub.
There can be one or more nodes in a grid.
Nodes can be launched on multiple machines with different platforms and browsers.
The machines running the nodes need not be the same platform as that of the hub.

SETUP MAVEN AND JDK ON WINDOWS OPERATING SYSTEM


It is necessary to download from the Internet following data:

1. MAVEN
2. JDK

Maven​ - http://www-us.apache.org/dist/maven/maven-3/3.5.2/source/apache-maven-3.5.2-src.zip
JDK​ - http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

When you do that, first you need to unzip maven file that you download in C root on your windows
operating system like on pictures below.

 
www.qaitive.rs
 

Next you need to install JDK file, there is no need for additional settings during installation.

If you've successfully done these steps, we need to setup windows path to them.

Go through the Control panel, enter the System option. Follow the pictures below.

Enter in Environment Variables, ​follow the pictures below.

 
www.qaitive.rs
 

When you open Environment Variables click on New button, ​follow the pictures below.

 
www.qaitive.rs
 

You need to enter the first variable:


Example:
Variable name: JAVA_HOME
The value of the variable: C: \ Program Files \ Java \ jdk1.8.0_121

It is also necessary to enter the same for the MAVEN variable:


Variable name: MAVEN_HOME
The value of the variable: C:\apache-maven-3.5.0
The second step is to enter the path, click on button Edit but you need to select PATH on left side ,
follow the pictures below.

 
www.qaitive.rs
 

 
www.qaitive.rs
 

Insert the next path:


Example
C:\apache-maven-3.5.0\bin
C:\Program Files\Java\jdk1.8.0_121\bin
C:\Selenium\Chrome
When you do that In the end, you still need to create folder in C drive (C:\Selenium\Chrome) and
copy Chrome WebDriver.
Url for download Chrome WebDriver:
https://sites.google.com/a/chromium.org/chromedriver/
Checking that you do everything all right
You need to open CMD and enter comand
mvn –version
You will get a similar result as in the picture below.

If you get a result from an image, this means that you have successfully created the path.

SETUP PROJECT IN INTELLIJ IDEA


When you open a path, open the IDE, select Create new project, offer you the option to simulate
settings from some other projects, you choose another Do noting option.
When the following window appears, you must select MAVEN and set the path to the JDK folder.
Look at the pictures below.

During the Firewall selection process your Windows will ask you for IDEAS privileges, there will be
two checks.

 
www.qaitive.rs
 

Sticulate all options and confirm.

In the next window that opens you must enter the name of the project, ie. Groupid and Artifacid
names must be the same without spaces. See the picture below.

 
www.qaitive.rs
 

 
www.qaitive.rs
 

Do Next and the window you need to confirm will open again.
You will start the Idea and open a pom.xml file in which you need to enter Dependency, and before
that, in the lower right corner, you will receive a message to approve the enable auto imoport and
you must allow it.
See the image below where you need to enter the next Dependency.
You must find on left side panel file with name POM, you open this file and input Dependency.

 
www.qaitive.rs
 

Below you have a number of codes that you need to enter:

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
</dependencies>

When you do, the Idea will start retrieving selenium files that will last for a few minutes, no more
than 5 minutes, you can follow the process at the bottom right of the application.

FIRST SELENIUM WEBDRIVER SCRIPT: JAVA CODE EXAMPLE


Download driver executable

Go to ​https://www.seleniumhq.org/download/
Find and click ​Google Chrome Driver
Click latest release, again one more time
Click version for your operating system
Put it into root folder of your project
Instantiating objects and variables
This is how a driver object is instantiated.
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
WebDriver driver = new ChromeDriver();

 
www.qaitive.rs
 

A ChromeDriver class with no parameters means that the default Chrome profile will be launched
by our Java program. The default Chrome profile is similar to launching Chrome in safe mode (no
extensions are loaded).

Launching a Browser Session


WebDriver's ​get()​ method is used to launch a new browser session and directs it to the URL that
you specify as its parameter.
driver.get("https://www.google.com/");
Get the Actual Page Title
The WebDriver class has the ​getTitle()​ method that is always used to obtain the page title of the
currently loaded page.
driver.getTitle();

And to print it:


System.out.println(driver.getTitle());
Terminating a Browser Session
f you use this command without closing all browser windows first, your whole Java program will
end while leaving the browser window open.
driver.quit();

WEB ELEMENTS AND LOCATORS


DOM (Document object model)
DOM represents how the source code is rendered in a browser. It is (mostly) representation of the HTML of
that page. Differences occur when the browser makes corrections due to some error or discrepancy in the
HTML. It contains document root (html), element (head) and element (body).

 
www.qaitive.rs
 

Web element tags


Web elements tags are used by the browser to determine what kind of element is in question. There is
around 120 of different tags but in practice much smaller number is used.

List of all tags on W3C:

https://www.w3schools.com/tags/

Web element attributes


Web element attributes gives us additional information about the elements. Some tags do not need
attributes at all and can be left without any (<br>). There is about 175 attributes in total:

https://www.w3schools.com/tags/ref_attributes.asp

Some are general, meaning that those can be applied to any element:

https://www.w3schools.com/tags/ref_standardattributes.asp

And there are element specific, for example tag ​Input:

https://www.w3schools.com/tags/tag_input.asp

Types of locators
There are 8 types of locators available in Selenium:

id (only one that can‘t return list)


driver.findElement(By.​id("value"));
css
driver.findElement(By.​cssSelector("value"));

 
www.qaitive.rs
 

xpath
driver.findElement(By.​xpath("value"));
name
driver.findElement(By.​name("value"));
class name
driver.findElement(By.className("value"));
tag name
driver.findElement(By.​tagName("value"));
link text
driver.findElement(By.​linkText("value"));
partial link text
driver.findElement(By.​partialLinkText("value"));

Inspect
Element inspector exists in any browser. Just right-click an element and select Inspect. New pane will give us
the info we need, however we do not know number of results and can‘t check locator using it.

Ranorex Selocity
Best tool available at the moment. Before we had FirePath and FireBug in Firefox, but those are deprecated
and will not work in FireFox version 48 and later.

https://www.ranorex.com/selocity/browser-extension/

Install this extension in Chrome and there will be a new tab in Element console. Easiest way to activate it is
by right clicking an element and selecting ‘Inspect’.

CSS locators
For this exercise we will use ​google.com
To get an element or a list by the tag name we just use that tag. Open Selocity and enter ​‘input’.
There will be multiple results that we can scroll by clicking left and right arrows. It is a rare that we

 
www.qaitive.rs
 

can successfully locate an element just by using tag names and we usually need to use other
properties as well.

Notice that elements also have different attributes. Those are all other values besides tag name.

This one has: ‘class’, ‘id’, ‘dir’ and ‘style’ that we can use. We create locator by using:
[attributeName='attributeValue']
For example: ​[class='gsst_b sbib_c']
Enter it into Selocity and it will find the element.
Note that all other element attributes can be selected using this way. For example:
[id='gs_st0']
Special cases are ID and Class attributes. For ID instead of ​[id='gs_st0']​ we can use ​#gs_st0
And for Class ​[class='gsst_b'] ​we use ​.gsst_b sbib_c
Note the dot (.) in front of the class name. For class names that have spaces we replace spaces with
dots, too. For example ​[class='gsst_b sbib_c'] ​can be ​.gsst_b.sbib_c
Chaining
Sometimes it is not enough to use just one attribute. In that case we chain locators. We can chain a
tag name with one or more attributes and we can chain multiple attributes. Chaining is performed
by entering 2 or more values and their respective values by the following formula:
tagName[attributeName='attributeValue'][attributeName='attributeValue']
Note that there is no space beetween brackets.

 
www.qaitive.rs
 

Example with tag name/attribute combination: ​input[class=’gsfi’]​ or by using shortened annotation


input.gsfi
Example with attribute/attribute combination: ​[class='gsfi'][name='q']​ or by using shortened
annotation ​.gsfi[name='q']
Scoping
Sometimes we must use an element (or elements) that is child of another element. We can have 2
buttons with same properties but on the different part of the page. In that case we can scope
element by chaining element locators but with space.
[id='gs_lc0'] input
This will find all child elements of the element with id ​gs_lc0 ​that have tag name ​input.
[id='gs_lc0']>input
This will find all direct child elements of the element with id ​gs_lc0 ​that have tag name ​input.
Homework
Just play this game: ​https://flukeout.github.io/

XPath
Xpath is short for XML Path Language and is similar to the CSS as we will use it to locate elements but it
works very differently. It has relative and absolute nomenclature. One slash (/) is beginning from the root of
the DOM and double slash (//) works anywhere in the document. Remember that double slash can also be
used anywhere in the locator. One of the issues with XPath is that can be fragile.

- absolute XPath:
/html[1]/body[1]/div[1]/div[3]/form[1]/div[2]/div[2]/div[1]/div[1]/div[2]/div[1]/div[1]/div[2]/div[1]/i
nput[1]

- relative XPath
format: //tagName[@attributeName='attributeValue']
example: //input[@id='lst-ib']

- relative XPath with another //


format: /tagName//tagName[@attributeName='attributeValue']
example: /html//input[@id='lst-ib']

- contains
format: //tagName[contains(@attributeName, 'attributeValue')]
example: //input[contains(@id,'t-i')]

 
www.qaitive.rs
 

- starts with
format: //tagName[starts-with(@attributeName, 'attributeValue')]
example: //input[starts-with(@id,'lst')]

- * for tagname
format: //*[@attributeName='attributeValue']
example: //*[@id='lst-ib']

- * for attribute
format: //tagName[@*='attributeValue']
example: //input[@*='lst-ib']

- text
format: //tagName[text()='elementText']
example: //*[text()='Images']

- contains text
format: //tagName[contains(text(), 'partialElementText')]
example: //*[contains(text(),'Abou')]

- nth of element
format: //tagName[@attributeName='attributeValue'][number]
example: //span[@id='fsl']/a[1]

- .. up one level from a element


format: anyXpathLocator/..
example: //span[@id='fsl']/a/..

Selenium Commands
Instantiating Web Elements
Instead of using the long "driver.findElement(By.locator())" syntax every time you will access a
particular element, we can instantiate a WebElement object for it. The WebElement class is
contained in the "org.openqa.selenium.*" package.

Clicking on an Element

 
www.qaitive.rs
 

Clicking is perhaps the most common way of interacting with web elements​. The click() method is
used to simulate the clicking of any element. ​ The following example shows how click() was used to
click on Mercury Tours' "Sign-In" button.

Following things must be noted when using the click() method.

It does not take any parameter/argument.


The method ​automatically waits for a new page to load​ if applicable.
The element to be clicked-on, ​must be visible​ (height and width must not be equal to zero)

Entering text

driver.findElement(By.id(​"locator"​)).sendKeys(​“textToEnter”​);

Get Commands

Get commands fetch various important information about the page/element. Here are some
important "get" commands you must be familiar with.

It automatically opens a new browser window and fetches the page


that you specify inside its parentheses.
get()​ ​Sample usage: It is the counterpart of Selenium IDE's "open" command.
The parameter must be a ​String​ object.
Needs no parameters
getTitle()​ ​Sample Fetches the title of the current page
usage: Leading and trailing white spaces are trimmed
Returns a null string if the page has no title

getPageSource() Needs no parameters


Sample usage: Returns the ​source code of the page​ as a String value
Needs no parameters
getCurrentUrl() Fetches the string representing the ​current URL​ that the browser is
Sample usage: looking at
getText()​ ​Sample Fetches the ​inner text​ of the element that you specify
usage:

Implicit Wait

It is simpler to code than Explicit Waits.

 
www.qaitive.rs
 

It is usually declared in the instantiation part of the code.


You will only need one additional package to import.

To start using an implicit wait, you would have to import this package into your code.

Then on the instantiation part of your code, add this.

Explicit Wait

Explicit waits are done using the WebDriverWait and ExpectedCondition classes​. For the following
example, we shall wait up to 10 seconds for an element whose id is "username" to become visible
before proceeding to the next command. Here are the steps.
Step 1
Import these two packages:

Step 2
Declare a WebDriverWait variable. In this example, we will use "myWaitVar" as the name of the
variable.

 
www.qaitive.rs
 

Step 3
Use myWaitVar with ExpectedConditions on portions where you need the explicit wait to occur. In
this case, we will use explicit wait on the "username" (Mercury Tours HomePage) input before we
type the text "tutorial" onto it.

Conditions

Following methods are used in conditional and looping operations --

isEnabled()​ is used when you want to verify whether a certain element is enabled or not
before executing a command.

isDisplayed()​ is used when you want to verify whether a certain element is displayed or not
before executing a command.

isSelected()​ is used when you want to verify whether a certain ​checkbox, radio button, or
option in a drop-down box​ is selected. It does not work on other elements.

Using ExpectedConditions

 
www.qaitive.rs
 

The ExpectedConditions class offers a wider set of conditions that you can use in conjunction with
WebDriverWait until() method.

Below are some of the most common ExpectedConditions methods.

alertIsPresent() ​- waits until an alert box is displayed.

elementToBeClickable()​ - Waits until an element is visible and, at the same time, enabled.
The sample code below will wait until the element with id="username" to become visible
and enabled first before assigning that element as a WebElement variable named
"txtUserName".

frameToBeAvailableAndSwitchToIt() ​- Waits until the given frame is already available, and


then automatically switches to it.

Catching Exceptions

When using isEnabled(), isDisplayed(), and isSelected(), WebDriver assumes that the element
already exists on the page. Otherwise, it will throw a ​NoSuchElementException​. To avoid this, we
should use a try-catch block so that the program will not be interrupted.

 
www.qaitive.rs
 

If you use explicit waits, the type of exception that you should catch is the "TimeoutException".

Select tag
Select class is used for select tagname and has a special treatment in Selenium. First we initialize it:

Select select = new Select(driver.findElement(By.id("locator")));

Then we use one of the options:

select.selectByVisibleText("text");

select.selectByIndex(number);

select.selectByValue("value");

select.deselectAll;

select.deselectByVisibleText("text");

select.deselectByIndex(number);

select.deselectByValue("value");

 
www.qaitive.rs
 

Excercises:

http://the-internet.herokuapp.com/forgot_password

http://the-internet.herokuapp.com/login

http://toolsqa.com/automation-practice-form/

CUCUMBER
Before we learn about Cucumber, lets understand BDD
What is Behaviour Driven Development?
The general tendency of developers is to develop features and write test code later. As, evident in
above case, Test Case development for this case is complex and developer will put off Testing till
release , at which point he will do quick but ineffective testing.
To overcome this issue (Behavior Driven Development) BDD was conceived. It makes the entire
testing process easy for a developer.
In BDD, whatever you write must go into ​Given-When-Then steps. Let's consider the same example
above in BDD.
Given that a fund transfer module in net banking application has been developed
And I am accessing it with proper authentication
When I shall transfer with enough balance in my source account
Or I shall transfer on a Bank Holiday
Or I shall transfer on a future date
And destination a/c details are correct
And transaction password/rsa code / security authentication for the transaction is correct
And press or click send button
Then amount must be transferred
And the event will be logged in log file
Isn't it easy to write and read and understand? It covers all possible test cases for the fund transfer
module and can be easily modified to accommodate more. Also, it more like writing documentation
for the fund transfer module.

WHAT IS A "FEATURE FILE"?


For every cucumber project there is a single directory at the root of the project named "features".
This is where all of your cucumber features will reside. In this directory you will find additional
directories, which is step_definition and support directories.

 
www.qaitive.rs
 

Feature File consist of following components -

Feature​: A feature would describe the current test script which has to be executed.
Scenario​: Scenario describes the steps and expected outcome for a particular test case.
Scenario Outline​: Same scenario can be executed for multiple sets of data using scenario
outline. The data is provided by a tabular structure separated by (I I).
Given​: It specifies the context of the text to be executed. By using datatables "Given", step
can also be parameterized.
When​: "When" specifies the test action that has to performed
Then​: The expected outcome of the test can be represented by "Then"

GHERKIN

Cucumber executes your .feature files, and those files contain executable specifications written in a
language called Gherkin.

Gherkin is plain-text English (or one of 60+ other languages) with a little extra structure. Gherkin is
designed to be easy to learn by non-programmers, yet structured enough to allow concise
description of examples to illustrate business rules in most real-world domains.

Here is a sample Gherkin document:

In Gherkin, each line that isn't blank has to start with a Gherkin ​keyword, followed by any text you
like. The main keywords are:

Feature
Scenario
Given, When, Then, And, But (Steps)
Background
Scenario Outline
Examples

 
www.qaitive.rs
 

There are a few extra keywords as well:

""" (Doc Strings)


| (Data Tables)
@ (Tags)
# (Comments)

Feature file in detail

A .feature file is supposed to describe a single feature of the system, or a particular aspect of a
feature. It's just a way to provide a high-level description of a software feature, and to group
related scenarios.

A feature has three basic elements---the Feature: keyword, a name (on the same line) and an
optional (but highly recommended) description that can span multiple lines.

Cucumber does not care about the name or the description---the purpose is simply to provide a
place where you can document important aspects of the feature, such as a brief explanation and a
list of business rules (general acceptance criteria).

Here is an example:

Scenario

A scenario is a concrete example that illustrates a business rule. It consists of a list of steps.

You can have as many steps as you like, but we recommend you keep the number at 3-5 per
scenario. If they become longer than that they lose their expressive power as specification and
documentation.

 
www.qaitive.rs
 

In addition to being a specification and documentation, a scenario is also a test. As a whole, your
scenarios are an executable specification of the system.

Scenarios follow the same pattern:

Describe an initial context


Describe an event
Describe an expected outcome

Steps

A step typically starts with Given, When or Then. If there are multiple Given or When steps
underneath each other, you can use And or But. Cucumber does not differentiate between the
keywords, but choosing the right one is important for the readability of the scenario as a whole.

Given

Given steps are used to describe the initial context of the system---the scene of the scenario. It is
typically something that happened in the past.

When Cucumber executes a Given step it will configure the system to be in a well-defined state,
such as creating and configuring objects or adding data to the test database.

It's ok to have several Given steps (just use And or But for number 2 and upwards to make it more
readable).

When
When steps are used to describe an event, or an action. This can be a person interacting with the
system, or it can be an event triggered by another system.
It's strongly recommended you only have a single When step per scenario. If you feel compelled to
add more it's usually a sign that you should split the scenario up in multiple scenarios.

Then
Then steps are used to describe an expected outcome, or result.
The step definition of a Then step should use an assertion to compare the actual outcome (what
the system actually does) to the expected outcome (what the step says the system is supposed to
do).
Scenario Outline
When you have a complex business rule with severable variable inputs or outputs you might end up creating
several scenarios that only differ by their values.

 
www.qaitive.rs
 

Let's take an example from feed planning for cattle and sheep:

If there are many examples, this becomes tedious. We can simplify it with a Scenario Outline:

Step Definitions
Cucumber doesn't know how to execute your scenarios out-of-the-box. It needs Step Definitions to
translate plain text Gherkin steps into actions that will interact with the system.
When Cucumber executes a Step in a Scenario it will look for a matching Step Definition to execute.

A Step Definition is a small piece of code with a pattern attached to it. The pattern is used to link
the step definition to all the matching Steps, and the code is what Cucumber will execute when it
sees a Gherkin Step.

To understand how Step Definitions work, consider the following Scenario:

 
www.qaitive.rs
 

The I have 48 cukes in my belly part of the step (the text following the Given keyword) will match
the Step Definition below:

Example:

Feature​ − User login on social networking site.


The user should be able to login into the social networking site when the username and the
password are correct.
The user should be shown an error message when the username and the password are incorrect.
The user should be navigated to the home page if the username and the password are correct.
Outline​ − Login functionality for a social networking site.
The given user navigates to Facebook. When I enter Username as "<username>" and Password as
"<password>". Then, login should be unsuccessful.
| username | password |
| username1 | password1 |
* AND​ keyword is used to show conjunction between two conditions. ​AND​ can be used with any
other keywords like ​GIVEN, WHEN​ and ​THEN​.
There are no logic details written in the feature file.

Steps Definitions
We have got our feature file ready with the test scenarios defined. However, this is not the
complete job done. Cucumber doesn’t really know which piece of code is to be executed for any
specific scenario outlined in a feature file.
This calls the need of an intermediate – Step Definition file. Steps definition file stores the mapping
between each step of the scenario defined in the feature file with a code of function to be
executed.

 
www.qaitive.rs
 

So, now when Cucumber executes a step of the scenario mentioned in the feature file, it scans the
step definition file and figures out which function is to be called.
Example of Step Definition File
public void goToFacebook() {
driver = new FirefoxDriver();
driver.navigate().to("https://www.facebook.com/");
}

@When "^user logs in using Username as \"([^\"]*)\" and Password as \"([^\"]*)\"$"


public void I_enter_Username_as_and_Password_as(String arg1, String arg2) {
driver.findElement(By.id("email")).sendKeys(arg1);
driver.findElement(By.id("pass")).sendKeys(arg2);
driver.findElement(By.id("u_0_v")).click();
}

@Then"^login should be unsuccessful$"


public void validateRelogin() {
if(driver.getCurrentUrl().equalsIgnoreCase(
"https://www.facebook.com/login.php?login_attempt=1&lwv=110")){
System.out.println("Test Pass");
} else {
System.out.println("Test Failed");
}
driver.close();
}
So with each function, whatever code you want to execute with each test step (i.e.
GIVEN/THEN/WHEN), you can write it within Step Definition file. Make sure that code/function has
been defined for each of the steps.
This function can be Java functions, where we can use both Java and Selenium commands in order
to automate our test steps.

Excercise
In this exercise we’ll create a whole new project with cucumber. Also, we’ll create one standard Scenario and
one Scenario Outline. Scenario Outline takes data from example table and uses it a test data. Number of
rows determines how many times test will run with different inputs.

Test steps for Scenario will be to go to ​http://the-internet.herokuapp.com/login​, login and assert page URL.

For Scenario Outline, just enter username and password from the row and stop, without closing the browser.
This way we will see how Scenario Outline works.

● First, install Cucumber plugin for InterlliJ IDEA. Go to File > Settings. Search for ‘plugins’. When plugin
option is selected on the right enter ‘cucumber’ into plugins search.
● Choose ‘Cucumber for Java’ and click Install. Confirm when asked to install Gherkin plugin, too.
● Create a new Maven project and check that directory test > java is colored green, if not right click it,
choose ‘Mark Directory as’ and select ‘Test Sources Root’
● Copy Chrome driver executable in project root

 
www.qaitive.rs
 

● Add the following dependancies to pom.xml:

<?​xml version=​"1.0" ​encoding=​"UTF-8"​?>

<project ​xmlns=​"http://maven.apache.org/POM/4.0.0"

​xmlns:​xsi​=​"http://www.w3.org/2001/XMLSchema-instance"

x​ si​:schemaLocation=​"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"​>

<modelVersion>​4.0.0​</modelVersion>

<groupId>​QAserbia​</groupId>

<artifactId>​cucumber​</artifactId>

<version>​1.0-SNAPSHOT​</version>

<dependencies>

<dependency>

<groupId>​junit​</groupId>

<artifactId>​junit​</artifactId>

<version>​4.12​</version>

<scope>​test​</scope>

</dependency>

<dependency>

<groupId>​info.cukes​</groupId>

<artifactId>​cucumber-junit​</artifactId>

<version>​1.2.5​</version>

<scope>​test​</scope>

</dependency>

<dependency>

<groupId>​info.cukes​</groupId>

<artifactId>​cucumber-java​</artifactId>

 
www.qaitive.rs
 

<version>​1.2.5​</version>

<scope>​test​</scope>

</dependency>

<dependency>

<groupId>​org.seleniumhq.selenium​</groupId>

<artifactId>​selenium-java​</artifactId>

<version>​3.12.0​</version>

</dependency>

</dependencies>

</project>

● Create a new file in test > java named ‘login.feature’. Notice that file icon looks like a cucumber slice.
This means that file has been recognized as a cucumber feature file.
● Copy the following code into the file:

Feature: ​Login

​Scenario: ​Positive login


​Given ​User goes to Login page
​When ​User enters email and password
​And ​User clicks Login button
​Then ​User should be on Secure Area page

​Scenario Outline: ​Negative login


​Given ​User goes to Login page
​When ​Each user enters ​<email> ​and ​<password>
​Examples:
| ​email ​| ​password ​|
| ​email1@gmail.com ​| ​pass123 ​|

 
www.qaitive.rs
 

| ​email2@gmail.com ​| ​pass1234 ​|

● This will be our Feature with 2 scenarios. First Scenario contains 4 steps and second just 2.
● Notice that our steps are highlighted yellow as we haven't implemented step definitions yet. To
create step definitions, right click any of the highlighted steps and select ‘Create all step definition’.
In the new window choose a file name (you can leave it default), make sure that Java and not Java 8
is selected in the dropdown and click OK.
● Step definition file will be created but when opened notice that it has Pending exception. If we try to
run feature file now, first step will fail and others will be skipped.
● Create a directory under test > java named ‘steps’ and move step definition file into it
● To fill the step definition file, overwrite the whole file with the following:

import ​cucumber.api.java.en.​And​;

import ​cucumber.api.java.en.​Given​;

import ​cucumber.api.java.en.​Then​;

import ​cucumber.api.java.en.​When​;

import ​org.junit.Assert​;

import ​org.openqa.selenium.By​;

import ​org.openqa.selenium.WebDriver​;

import ​org.openqa.selenium.chrome.ChromeDriver​;

public class ​MyStepdefs {

​private ​WebDriver ​driver​;

​@Given​(​"^User goes to Login page$"​)

​public void ​userGoesToLoginPage​() {

System.​setProperty(​"webdriver.chrome.driver"​, ​"chromedriver.exe"​)​;

​driver ​= ​new ​ChromeDriver()​;

​driver​.get(​"http://the-internet.herokuapp.com/login"​)​;

​}

​@When​(​"^User enters email and password$"​)

 
www.qaitive.rs
 

​public void ​userEntersEmailAndPassword​() {

​driver​.findElement(By.​id(​"username"​)).sendKeys(​"tomsmith"​)​;

​driver​.findElement(By.​id(​"password"​)).sendKeys(​"SuperSecretPassword!"​)​;

​}

​@And​(​"^User clicks Login button$"​)

​public void ​userClicksLoginButton​() {

​driver​.findElement(By.​cssSelector(​".radius"​)).click()​;

​}

​@Then​(​"^User should be on Secure Area page$"​)

​public void ​userShouldBeOnSecureAreaPage​() {

Assert.​assertEquals(​driver​.getCurrentUrl()​, ​"http://the-internet.herokuapp.com/secure"​)​;

​driver​.quit()​;

​}

​@When​(​"^Each user enters (.*) and (.*)$"​)

​public void ​eachUserEntersEmailAndPassword​(String email​, ​String password) {

​driver​.findElement(By.​id(​"username"​)).sendKeys(email)​;

​driver​.findElement(By.​id(​"password"​)).sendKeys(password)​;

​}

● Notice that driver config is set to ‘chromedriver.exe’ if using Mac or Linux just delete ‘.exe’
● Got back to feature file. Right click Feature keyword and select Create Feature login
● In the new window check that under Glue option is filled ‘steps’. If not, enter manually
● Click OK
● Run the test config (green arrow in top left corner)
● Result summary should be similar to following:

3 Scenarios (3 passed)

 
www.qaitive.rs
 

8 Steps (8 passed)
0m10.786s
Process finished with exit code 0
DataTables
This is a specific data provider in Cucumber as it passes the whole table (hence the name):

Scenario: ​Login Data table


​Given ​User goes to Login page
​When ​Table user enters <email> and <password>
​| ​email | ​email@gmail.com |
| ​name | ​pera |
| ​lastName | ​peric |
| ​password | ​password11 |
Then ​Table user is on appropriate page by table <welcome message>
​| ​welcome message1 ​|
And in our step definition code we receive the whole table as an object, then convert it into a list matrix.
After we convert it into a matrix we access it as usual for matrices:

@When​(​"^Table user enters <email> and <password>$"​)


public void ​tableUserEntersEmailAndPassword​(DataTable userCredentials) {
List<List<String>> data = userCredentials.raw()​;
​driver​.findElement(By.​id(​"username"​)).sendKeys(data.get(​1​).get(​1​))​;
​driver​.findElement(By.​id(​"password"​)).sendKeys(data.get(​1​).get(​4​))​;
}
In this step we access second column by stating (data.get(1)) in both commands, then choose a second row
in first command (.get(1)) for username and fifth row (.get(4)) for password.

Note: in Java counting lists starts from 0, not 1, so the first row/column is numbered 0, second is numbered
1, and so on.

JENKINS
What is Jenkins?

 
www.qaitive.rs
 

Jenkins is a CI (Continuous Integration) server. It helps us automating steps during a software


development cycle. There are many things that CI can help us out like cloning the code repository,
perform static analysis or start our tests. Jenkins is most used CI currently and we will use it in our
example.

Example for Jenkins job

Download Jenkins WAR file from the ​https://jenkins.io/download/​. There are 2 columns: ​Long-term
Support (LTS) and ​Weekly. Scroll LTS column all the way down and download the file using ​Generic
Java package (.war) link.

Open command prompt (or terminal) and navigate to the location that WAR package is saved. Run
the following command to start Jenkins server:
java -jar jenkins.jar
Note: do not close the command prompt until whole example is finished. Otherwise Jenkins
server will be stopped.
After a couple of second you’ll see ‘INFO: Jenkins is fully up and running’ in your command prompt.
Open your browser and go to ​http://localhost:8080/. That is a start page for Jenkins.

There will be a file path painted in red. Go to that location, open the file with any text editor and
copy the code. Go back to browser and paste that code into input field named ‘Administrative
password’. Click Continue.

On the next screen there will be a choice what plugins to install. Just click on ‘Install suggested
plugins’. This will take a few minutes to complete. This is the screen that you will see during the
plugin installation:

 
www.qaitive.rs
 

After couple of minutes plugin installation will be complete and you will be prompted with the
following screen:

Enter desired username, password, full name and email. Click ‘Save and Continue’
If you get the following screen, just click ‘Save and Finish’:

 
www.qaitive.rs
 

And that is it! Just click ‘Start using Jenkins’.

On the Welcome screen click ​Manage Jenkins on the right, then ​Manage plugins in the middle of
the screen. On the new screen click tab called ​Avaliable. Enter ​Analylzer in the Filter field. Find ​Test
Results Analyzer and mark checkbox next to it. Click button ​Download now and install after restart.

Next screen is called ​Installing Plugins/Upgrades. Just mark the checkbox next to text ​Restart
Jenkins when installation is complete and no jobs are running. Refresh the page after about 10
seconds and login screen should appear. This means that Jenkins has been restarted. Login with
your credentials.

On the next screen click ​Create new jobs in the middle of the screen. In the ​Enter an item name
type name of the Jenkins job, for example ​Selenium01. Click ​Freestyle project option and click OK.
New job will be created.

Next screen is our job configuration. Scroll down to the heading called ​Build and click the button
called ​Add build step. If you are using a Windows operating system select option: ​Execute Windows
batch command and if you are using a Linux or a Mac choose: ​Execute shell from dropdown.

New windows called Command will be shown. Enter the following command:
mvn clean test

 
www.qaitive.rs
 

Next, scroll down to ​Post-build Actions and click ​Add Post-build Action dropdown. Choose ​Publish
JUnit test result report. In the ​Test report XMLs field just add:
target/surefire-reports/*.xml
Click Apply and Save and our Jenkins project is configured.

Next screen is the main screen of our project. Run job once for the workspace by clicking ​Build Now
button from the left hand menu. This is used to create job workspace.

Now, we will create a project and copy it into Jenkins workspace folder. Create Maven project with
the GroupID and ArtifactID of your choice. Copy driver executable for your operating system into
the project root folder.
Copy the following code into your pom.xml over the existing code:

<?​xml version=​"1.0" ​encoding=​"UTF-8"​?>


<project ​xmlns=​"http://maven.apache.org/POM/4.0.0"
​xmlns:​xsi​=​"http://www.w3.org/2001/XMLSchema-instance"
x​ si​:schemaLocation=​"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"​>
<modelVersion>​4.0.0​</modelVersion>

<groupId>​komocija​</groupId>
<artifactId>​jenkins​</artifactId>
<version>​1.0-SNAPSHOT​</version>

<dependencies>
<dependency>
<groupId>​org.seleniumhq.selenium​</groupId>

 
www.qaitive.rs
 

<artifactId>​selenium-java​</artifactId>
<version>​3.12.0​</version>
</dependency>
<dependency>
<groupId>​org.seleniumhq.selenium​</groupId>
<artifactId>​selenium-api​</artifactId>
<version>​3.12.0​</version>
</dependency>
<dependency>
<groupId>​org.testng​</groupId>
<artifactId>​testng​</artifactId>
<version>​6.14.3​</version>
<scope>​test​</scope>
</dependency>
</dependencies>
</project>

Then, create new java class called JenkinsTest and copy the following code into it:

import ​org.openqa.selenium.By​;
import ​org.openqa.selenium.WebDriver​;
import ​org.openqa.selenium.WebElement​;
import ​org.openqa.selenium.chrome.ChromeDriver​;
import ​org.testng.Assert​;
import ​org.testng.annotations.​Test​;

 
www.qaitive.rs
 

public class ​JenkinsTest {

WebDriver ​driver​;

​@Test
​public void ​jenkinsOne​() {
System.​setProperty(​"webdriver.chrome.driver"​, ​"chromedriver.exe"​)​;
​driver ​= ​new ​ChromeDriver()​;

​driver​.get(​"https://www.google.com/"​)​;

​WebElement element = ​driver​.findElement(By.​cssSelector(​"#lst-ib"​))​;


​element.sendKeys(​"123"​)​;

​Assert.​assertEquals(​1​, ​1​)​;
​driver​.quit()​;
​}
}

Note: ​for Mac and Linux systems use ​chromedriver instead of ​chromedriver.exe
Open the location that the project is in and copy all files inside the main folder.
Then open your Jenkins installation path (your home directory/.jenkins) and note that folder is
hidden. There will be a folder called ​Jenkins then a folder named after your Jenkins job name. Open
it and copy the files that you copied from project folder.

 
www.qaitive.rs
 

After than just go to Jenkins again and run build again. When finished click ​Test Results Analyzer link
on the left hand menu to display test results.

JUnit and TestNG annotations


Besides @Test annotation there are also other annotations for JUnit and TestNG that help us writing out test
code. Annotations are prefixed with @ sign and are placed just before a method declaration.

With JUnit there is 5 annotations that are most often used:

- @Before: runs before every test method


- @BeforeClass: runs once before all tests in class
- @After: runs after every test method
- @BeforeClass: runs once after all tests in class
- @Rule: adds a functionality to each test with more flexibility

And with TestNG there are

- @BeforeSuite: runs once before all tests in project


- @BeforeClass: runs once before all tests in class
- @BeforeTest: runs before each test
- @BeforeMethod: runs before each method in class (if all our methods in a class are tests, this is the
same as above)
- @BeforeGroups: runs before any of the tests of the specified group
- @AfterSuite: runs once after all tests in project
- @AfterTest: runs after each test
- @AfterClass: runs once before all tests in class
- @AfterMethod: runs after each method in class (if all our methods in a class are tests, this is the
same as above)
- @AfterGroups: runs before any of the tests of the specified group

Note: Use annotations sparingly and with a purpose. If used incorrectly, annotations provide more harm
than good.

Uploading files
This a very simple operation. We just perform sendKeys command on an element that is used to upload file
(usually a some kind of button). Then, in the sendKeys parameters we specify absolute path to the file. For
example:

WebElement element = ​driver​.findElement(By.​id(​"photo"​))​;


element.sendKeys(​"c:\images\image.png"​)​;

Appendix 1: Tips and tricks


There will be some situations that block a tester from running the tests, although all the code appears in
order. Those include a few of common issues:

 
www.qaitive.rs
 

Issues with IDE itself

No software is bug free or perfect and the same goes for IDEs. Sometimes the cache of the IDE is stuck and
can’t be used. In that case just perform ​File > Invalidate caches/Restart > Invalidate and Restart. After caches
are deleted, IDE will restart and rebuild cache.

Issue with Selenium stack compatibility

Browser versions are upgraded frequently and we need to provide appropriate driver in order to use those
new browser versions. Sometimes we don’t but sometimes we do need to update our Selenium driver and
appropriate dependencies. To do that, just go to ​mvnrepository.com and search for needed dependency.
After dependency is found, we can check if newer version has been published. Please note that we also need
to update linked dependencies.

For example if we have selenium dependency version 3.12:

<dependency>

<groupId>​org.seleniumhq.selenium​</groupId>

<artifactId>​selenium-java​</artifactId>

<version>​3.12.0​</version>

</dependency>

We probably need to update driver versions. Example with Chrome driver:

<dependency>

<groupId>​org.seleniumhq.selenium​</groupId>

<artifactId>​selenium-chrome-driver​</artifactId>

<version>​3.12.0​</version>

</dependency>

 
www.qaitive.rs