+ All Categories
Transcript
Page 1: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Improving Your Selenium WebDriver

Tests

Roy de KleijnTechnical Test ConsultantEmail: [email protected]: @TheWebTesterWebsite: http://www.rdekleijn.nlGithub: https://github.com/roydekleijn

Page 2: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Question #1

What makes your Selenium WebDriver tests suck?

Page 3: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Answer #1

Depending on third-party data

Synchronization issues

Cross-browser issues

Hard to locate elements

testdata

Slow feedback cycle

Flaky tests

High maintenance costs

Page 4: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Lack of confidence

Results in …

Page 5: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects• Handle synchronization

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 6: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Maintenance testM

aint

enan

ce e

ffort

Time

Start

with re

cord an

d playbac

k

Convert

recorded te

sts in

to code

Awesome, it

works

! Let’s

create

more UI te

sts Reality: code ends up into unmaintainable spaghetti

Design patt

erns applie

d

Implement fe

atures t

o mak

e tests

robust

wish

Page 7: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Testing Pyramid

unit

UI

API

feed

back

-cyc

le

- Extremely fast- Smallest units of the application / isolates failure- Executed during build time- No dependency on data

- Extremely slow- Requires running application- Will change frequently- Dependency on data

- Fast- Covering boundary conditions- Start early in SD process - Requires running application- (some) dependency on data

Page 8: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Mock External Interfaces

application

Interface 1

Interface 2

Interface 3

application

Interface 1

Interface 2

Interface 3m

ock

Page 9: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 10: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Question #2

What is wrong with these locators?

#1.//*[@id='wx-header-wrap']/div/div/div/div[2]/div[2]/div/section/div/form/input

#2.//*[@id='gnav-header-inner']/div/ul/li[2]/a

Page 11: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Answer #2

They contain too much information about the location

Page 12: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Closer look #1

Page 13: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Closer look #1.//*[@id='wx-header-wrap']/div/div/div/div[2]/div[2]/div/section/div/form/input

What if the location of this element will change over time?

It can be written like this: input[class = ‘input--search’]Orinput.input—searchOrinput[name = ‘search’]

Page 14: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Closer look #2

Page 15: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Closer look #2.//*[@id='gnav-header-inner']/div/ul/li[2]/a

What if the order of the links will change over time ?

It can be written like this: a[id=register]Ora#register

Page 16: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Attribute selectorscss xpath

Equals e[a=v] //e[@a=v]

Contains e[a*=v] //e[contains(@a, ‘v’)]

Starts-with e[a^=v] //e[starts-with(@a, ‘v’)]

Ends-with e[a$=v] //e[ends-with(@a, ‘v’)]

Page 17: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Tip: only use Xpath…

If you need to walk up the DOM

Demofile://localhost/Users/roydekleijn/Documents/whenXpath.html

Page 18: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

AngularJS - elements

• Different way of locating elements• Binding• Model• Repeat

• ngWebDriver library (create by Paul Hammant)• https://github.com/paul-hammant/ngWebDriver• Logic from Protractor project

Page 19: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

• Enable debug info• Call angular.reloadWithDebugInfo(); in your browser debug

console

• Execute the following snippet to reveal all the elements:

§

Page 20: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 21: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Speed-up and stabilize your tests Windows 7

IEFF

Chrome

Windows vistaIEFF

UbuntuFF

Opera

Mac OSFF

ChromeOpera

Nodes

Hub

Specification

HUB

Test Scripts

Page 22: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Docker Selenium

• Disposable Selenium Grid (in seconds)• Autoscaling features

• https://hub.docker.com/r/selenium/

Page 23: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Docker-composeseleniumhub: image: selenium/hub ports: - 4444:4444firefoxnode: image: selenium/node-firefox environment: SCREEN_WIDTH: 2880 SCREEN_HEIGHT: 1800 ports: - 5900 links: - seleniumhub:hub

chromenode: image: selenium/node-chrome environment: SCREEN_WIDTH: 2880 SCREEN_HEIGHT: 1800 ports: - 5900 links: - seleniumhub:hub

Page 24: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Docker commands

Start containers:docker-compose up –d

-d: Run containers in the background--force-recreate: Recreate containers entirely

IP of docker engine:docker-machine ip

Autoscaling:docker-compose scale firefoxnode=5 chromenode=1

Page 25: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 26: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Problems that arise

• Unmaintainable• Unreadable test scripts• Creation of test scripts is time consuming• Code duplication

Page 27: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

From problem to solution

Page 28: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Solution

Each page contains only a part of the total functionality available on the website

Put page specific functionality in a class with a corresponding name

Page 29: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Step-by-step plan

1. Identify necessary WebElements2. Create a class3. Define WebElements in corresponding classes4. Model the functionality of a page into methods5. Model the page flow by setting returntypes

Page 30: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Identify necessary WebElements

Page 31: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Create a class

A class with the name of the page extending from LoadableComponent

public class HomePage extends LoadableComponent<HomePage> { private WebDriver driver;

public HomePage(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); }

Page 32: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Define WebElementsOn class level (above the methods)

@FindBy(css = "a.login")

private WebElement loginLink;

Page 33: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Model the functionality

public LoginPage clickOnLoginLink() { loginLink.click(); return new LoginPage(driver); }

Page 34: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Model the page flow

• Prerequisite:• Multiple pages are modelled

• Modify returntype• The returntype is the name of the page (class) where you are navigating

towards• Use the current class name, if you stay on the same page

Page 35: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Model the page flow

public LoginPage clickOnLoginLink() { loginLink.click(); return new LoginPage(driver); }

Returning page

Page 36: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 37: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Data Objects final CustomerAccount account = new CustomerAccount.CustomerAccountBuilder("[email protected]","1qazxsw2").build();

Access data:account.getEmail()

account.getPassword()

Page 38: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Data Objects - Complex final Order order = new Order.OrderBuilder()//

.withInvoiceAddress(new Address.AddressBuilder("abc street", "1234ab").build())// .withShippingAddress(new Address.AddressBuilder("shipstreet”, "4321ab").withCountry("The Netherlands").build())//

.build();

// Retrieve data from the objectSystem.out.println(order.getInvoiceAddress().getStreet());

System.out.println(order.getShippingAddress().getCountry());

Page 39: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 40: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Synchronization issues

• Browser has to start• Page has to load• AJAX request need to be finished• Or, loader should be gone before we can continue

Page 41: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

What NOT to do …

NEVER, use Thread.sleep();

• It will probably make your test unnecessary slow• You never know if you wait exactly long enough

Page 42: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

What to do…• WebDriver build in wait mechanisms• implicitlyWait: poll till element is present

• Is not inline with fail-fast principle• setScriptTimeout: time to wait for an asynchronous script to finish• pageLoadTimeout: time to wait for a page load to complete

• ngWebDriver• waitForAngularRequestsToFinish – wait for outstanding angular requests

• Custom (gist)• checkPendingRequests – wait for all HTTP requests to be finished

Page 43: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Example 1

Wait for element to be clickable

@Testpublic void waitForElementToBeClickable() {

new WebDriverWait(driver, 20,100) //.until(ExpectedConditions.elementToBeClickable(

By.cssSelector("a.login")));}

Page 44: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Example 2

Wait for loader to be invisible

@Testpublic void waitForElementNotToBeVisable() {

new WebDriverWait(driver, 20, 100) //.until(ExpectedConditions.invisibilityOfElementLocated(

By.cssSelector("loader")));}

Page 45: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 46: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Play with ObjectsDownload sources from: https://github.com/roydekleijn/webdriver-workshop Or

http://bit.ly/2eDaWio

Website under test: http://demo.rdekleijn.nl

- Create Register test (model is in place)- Implement Search test (model not in place)- Implement Order test (if there is time left..)

Page 47: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Contents19:00 - 20:00 Part 1

• Introduction• Element locator tips & tricks• Speed-up and stabilize your tests (demo)• Implementing the Page Object Model• Utilize Data Objects

20:00 - 20:15 Coffee 20:15 - 21:15 Part 2

• Handle synchronization• Play with objects• What we have learned

We will start with an actual Page Object Model implementation today

Page 48: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

What we have learned today

Depending on third-party data

Cross-browser issues

Hard to locate elements

testdata

Slow feedback cycle

Flaky tests

High maintenance costs

Synchronization issuesAvoid Thread.sleep() or other hardcoded

waits

Utilize Page Object Model

id > name > css > xpath > angular

Mock interfaces

Run tests in parallel

Mock interfaces

Mock interfaces, setup clean environments,

implement page object model

Page 49: TestNet 2016 - Improving Your Selenium WebDriver Tests

© 2016 The Future Group - http://bit.ly/2eDaWio

Thank you…

Roy de KleijnTechnical Test ConsultantEmail: [email protected]: @TheWebTesterWebsite: http://www.rdekleijn.nlGithub: https://github.com/roydekleijn


Top Related