Blog - shawnhooper.ca
Twitter - @shawnhooper
Automated UI Testing
Using Selenium
WPCampus 2017, Buffalo NY
Shawn Hooper
Director of IT, Actionable.co
Slide 2
Slide 2 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Shawn Hooper
Director of IT at Actionable.co
Remote Worker
WordPress Developer Since 2011
Co-Organizer of WordCamp Ottawa, Ontario
2nd WPCampus
about( $me );
Slide 3
Slide 3 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Today we’re going to talk
about….
Slide 4
Slide 4 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Unit Testing
Slide 5
Slide 5 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Testing individual units of source code
Run a function with with X arguments,
we expect Y return value, or the test fails.
Unit Testing
Slide 6
Slide 6 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
A unit test would assert that calling:
$y = plus_one( 10 );
equals 11, or the test fails.
Unit Testing
Slide 7
Slide 7 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Testing how our web application works
in the browser window.
UI Testing
Blog - shawnhooper.ca
Twitter - @shawnhooper
Selenium
Slide 10
Slide 10 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Selenium automates browsers.
Perfect for testing.
Selenium
Slide 11
Slide 11 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Requires a Server and a Client Library
Selenium
Slide 12
Slide 12 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Mac (with Homebrew):
brew install selenium-server-standalone
Install Browser Drivers:
brew install chromedriver
brew install geckodriver
Installing Selenium Server
Slide 13
Slide 13 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
brew services start chromedriver;
brew services start geckdriver;
selenium-server;
Starting Selenium Server
Slide 14
Slide 14 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
http://localhost:4444/wd/hub
You can see what sessions are running.
This is also the URL referenced in your tests.
Starting Selenium Server
Slide 15
Slide 15 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
When you run your tests, you’ll see a browser
window open, and run through the actions you’ve
defined in your test.
Starting Selenium Server
Slide 16
Slide 16 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Let’s Offload the Server
Component
Slide 17
Slide 17 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
There are many web services that will run the
server-side of the Selenium tests for you.
We use Sauce Labs.
Offloading the Server
Slide 18
Slide 18 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Includes Support for Multiple Platforms, Browsers &
Versions
Manual and Automated Testing
Logs of all tests
Captures Screenshots
Includes a REST API
Offloading the Server
Slide 19
Slide 19 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Change the URL you use for WebDriver:
Offloading the Server
Slide 20
Slide 20 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Slide 21
Slide 21 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
WebDriver is the API that speaks to Selenium
Server.
WebDriver
Slide 22
Slide 22 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
There are officially supported WebDrivers from
Selenium for:
Java
C#
Ruby
Python
JavaScript (Node)
WebDriver
Slide 23
Slide 23 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
But what about PHP ?
WebDriver
Slide 24
Slide 24 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
There are lots of unofficial WebDriver libraries as
well, including for PHP.
The one we’ll use in this demo is php-webdriver
a library developed by Facebook.
WebDriver
Slide 25
Slide 25 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
We can install php-webdriver into our project with
composer:
composer require facebook/webdriver
WebDriver
Slide 26
Slide 26 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
The official tests for WordPress are all written in
PHPUnit, so let’s take advantage of it for our
Selenium testing!
composer require phpunit/phpunit
PHPUnit
Slide 27
Slide 27 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Getting Started…
Slide 28
Slide 28 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
HomePageTest.php
Slide 29
Slide 29 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Run it…
Slide 30
Slide 30 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
If it failed…
Slide 31
Slide 31 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
get() — Retrieves a web page by URL
getTitle() - Return the of the page
quit() - Close the Web Browser
findElement() - Find 1st element matching query
findElements() - Find all elements matching query
WebDriver
Slide 32
Slide 32 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
switchTo() - Switch window or frame
navigate() - move through the browser history
manage() - manage cookies & logs
getPageSource() - “View Source”
getCurrentURL() - Get the Current URL
WebDriver
Blog - shawnhooper.ca
Twitter - @shawnhooper
Queries the current page to retrieve one or more
elements.
Returns a WebDriverElement object or an array of
WebDriverElement objects.
FindElement(s)
Slide 35
Slide 35 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Includes several query mechanisms
(WebDriverBy Class):
cssSelector
className
id
linkText
partialLinkText
name
tagName
xPath
FindElement(s)
Slide 36
Slide 36 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
FindElement(s)
Slide 37
Slide 37 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
sendKeys() - Enter a value into an input or textarea
click() - Click on the element
clear() - Clear an input or textarea
getID() - Get the ID of the element
getAttribute() - Returns any attribute of the element
getTagName() - Returns the HTML tag name
getCSSValue() - Returns the value of a CSS property
getLocation() - Returns x y coordinate
getSize() - Get the Size (Height & Width) of the Element
isDisplayed() - Is this element visible
isEnabled() - Is this element enabled
WebDriverElement
Slide 38
Slide 38 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
wp-login.php source:
Slide 39
Slide 39 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
WebDriverElement
Slide 40
Slide 40 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
You can also run a FindElement() or FindElements()
query on the RemoteWebElement object to find child
element(s).
WebDriverElement
Slide 41
Slide 41 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Back to Our Test…
Slide 42
Slide 42 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Let’s Abstract a WordPress Page into a class that we can
use for our tests.
Abstract Page Class
Slide 43
Slide 43 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Slide 44
Slide 44 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Slide 45
Slide 45 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Slide 46
Slide 46 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Login to WP Admin…
Slide 47
Slide 47 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Let’s see this Abstract class as I’m using it
on a real project.
Revenue Calculator Example
Blog - shawnhooper.ca
Twitter - @shawnhooper
Integrate into Build Servers
Slide 55
Slide 55 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Run Selenium Tests as part of your build
processes, so that you don’t deploy sites that fail
any of your functional UI tests.
Integrate into Build Servers
Slide 56
Slide 56 text
Blog - shawnhooper.ca
Twitter - @shawnhooper
Slides for this presentation will be available on
shawnhooper.ca
WPCampus Speaker Survey:
https://2017.wpcampus.org/session-survey/436
Tweet Me @shawnhooper
WordPress Slack: shooper
Thank You!