SlideShare a Scribd company logo
UA	
  Tes'ng	
  with
Selenium	
  and	
  PHPUnit
ZendCon	
  2013,	
  Santa	
  Clara
2
• PHP	
  Consultant
• President	
  PHPBenelux
• Conference	
  speaker
Michelangelo	
  van	
  Dam
3
Today’s	
  goal
• Set	
  up	
  and	
  use	
  Selenium	
  IDE
• Record	
  UA	
  tests
• Convert	
  to	
  PHPUnit
• Run	
  con'nuously
• Mul'	
  browser	
  support
4
5
DISCLAIMER
S E L E N I U M T E S T S A R E N OT A
REPLACEMENT FOR REGULAR UNIT
TESTING. THEY ONLY PROVIDE AN
ADDITIONAL SET OF TESTS FOCUSED
ON USER ACCEPTANCE AND USER
EXPERIENCE TESTING.
For more information about unit testing, please
see my other material on www.slideshare.net and
www.speakerdeck.com. Search for “dragonbe”!
User	
  Acceptance
6
7
“Acceptance testing is a test conducted to determine if
the requirements of a specification or contract are met.”
-- source: wikipedia
Checklist	
  for	
  web	
  applica'ons
8
9
Func'onal	
  tes'ng
• Test	
  func'onal	
  requirements
-­‐ e.g.	
  no	
  access	
  to	
  profile	
  without	
  authen'ca'on
• Test	
  UI	
  elements	
  on	
  the	
  web	
  interface
-­‐ e.g.	
  buTons,	
  form	
  elements,	
  AJAX	
  controls,	
  …
A	
  word	
  of	
  cau'on!
10
• UA	
  tests	
  only	
  test	
  generated	
  output
-­‐ not	
  a	
  replacement	
  for	
  unit	
  tes'ng
• UA	
  tests	
  are	
  heavily	
  depending	
  on	
  DOM
-­‐ changes	
  to	
  the	
  DOM	
  might	
  lead	
  to	
  failing	
  UAT
Browser	
  support
11
Selenium	
  to	
  the	
  rescue
12
Plugin	
  for	
  firefox
13
Get	
  the	
  plugin	
  (demo)
14
UA Testing with Selenium and PHPUnit - ZendCon 2013
Let’s	
  get	
  started
16
Pick	
  a	
  test	
  case
17
Issue	
  #7
18
Verify	
  this	
  issue	
  on	
  PROD
19
20
Fix	
  the	
  issue
21
Run	
  test	
  to	
  see	
  it’s	
  fixed
22
23
24
Save	
  your	
  test	
  as	
  .html
It’s	
  that	
  easy!
25
Automated	
  Tes'ng
26
PHPUnit	
  to	
  the	
  rescue
27
Export	
  to	
  PHPUnit
28
The	
  PHPUnit	
  TestCase
29
<?php
class Example extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this->setBrowser("*chrome");
$this->setBrowserUrl("http://www.theialive.com/");
}
public function testMyTestCase()
{
$this->open("/");
$this->click("link=login");
$this->waitForPageToLoad("30000");
$this->type("id=email", "dragonbe+tek13@gmail.com");
$this->type("id=password", "test1234");
$this->click("id=signin");
$this->waitForPageToLoad("30000");
$this->click("link=Test demo");
$this->waitForPageToLoad("30000");
$this->assertEquals("Done", $this->getText("xpath=//th[5]"));
$this->click("link=[EDIT]");
$this->waitForPageToLoad("30000");
$this->assertTrue($this->isElementPresent("id=done"));
$this->click("link=sign off");
$this->waitForPageToLoad("30000");
}
}
?>
Change	
  class	
  name
30
<?php
class Example extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this->setBrowser("*chrome");
$this->setBrowserUrl("http://www.theialive.com/");
}
public function testMyTestCase()
{
$this->open("/");
$this->click("link=login");
$this->waitForPageToLoad("30000");
$this->type("id=email", "dragonbe+tek13@gmail.com");
$this->type("id=password", "test1234");
$this->click("id=signin");
$this->waitForPageToLoad("30000");
$this->click("link=Test demo");
$this->waitForPageToLoad("30000");
$this->assertEquals("Done", $this->getText("xpath=//th[5]"));
$this->click("link=[EDIT]");
$this->waitForPageToLoad("30000");
$this->assertTrue($this->isElementPresent("id=done"));
$this->click("link=sign off");
$this->waitForPageToLoad("30000");
}
}
?>
class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
The	
  PHPUnit	
  TestCase
31
<?php
class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this->setBrowser("*chrome");
$this->setBrowserUrl("http://www.theialive.com/");
}
public function testMyTestCase()
{
$this->open("/");
$this->click("link=login");
$this->waitForPageToLoad("30000");
$this->type("id=email", "dragonbe+tek13@gmail.com");
$this->type("id=password", "test1234");
$this->click("id=signin");
$this->waitForPageToLoad("30000");
$this->click("link=Test demo");
$this->waitForPageToLoad("30000");
$this->assertEquals("Done", $this->getText("xpath=//th[5]"));
$this->click("link=[EDIT]");
$this->waitForPageToLoad("30000");
$this->assertTrue($this->isElementPresent("id=done"));
$this->click("link=sign off");
$this->waitForPageToLoad("30000");
}
}
?>
protected function setUp()
{
$this->setBrowser("*iexplore");
$this->setBrowserUrl("http://www.theialive.com/");
$this->setHost('192.168.56.101');
$this->setPort(12666);
}
Meaningful	
  method	
  name
<?php
class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this->setBrowser("*iexplore");
$this->setBrowserUrl("http://www.theialive.com/");
$this->setHost('192.168.56.101');
$this->setPort(12666);
}
public function testMyTestCase()
{
$this->open("/");
$this->click("link=login");
$this->waitForPageToLoad("30000");
$this->type("id=email", "dragonbe+tek13@gmail.com");
$this->type("id=password", "test1234");
$this->click("id=signin");
$this->waitForPageToLoad("30000");
$this->click("link=Test demo");
$this->waitForPageToLoad("30000");
$this->assertEquals("Done", $this->getText("xpath=//th[5]"));
$this->click("link=[EDIT]");
$this->waitForPageToLoad("30000");
$this->assertTrue($this->isElementPresent("id=done"));
$this->click("link=sign off");
$this->waitForPageToLoad("30000");
}
}
?>
32
public function testMarkTestAsDone()
startSeleniumStandAlone.BAT
33
"C:Program FilesJavajre7binjava.exe"
-jar "C:Jarselenium-server-standalone-2.28.0.jar"
-port 12666
Now	
  run	
  your	
  tests
34
UA Testing with Selenium and PHPUnit - ZendCon 2013
How	
  it	
  runs	
  on	
  the	
  node
36
UA Testing with Selenium and PHPUnit - ZendCon 2013
Advantages
38
• You	
  can	
  start	
  tes'ng	
  immediately
• Even	
  test	
  “hard	
  to	
  test”	
  kind	
  of	
  situa'ons
• More	
  nodes	
  for	
  parallel	
  tes'ng
• Tes'ng	
  different	
  browsers	
  and	
  plaforms
• Con'nuous	
  Integra'on	
  possible
Next	
  Steps
39
Mul'	
  Browser	
  support
40
Base	
  TestCase
41
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extensions_SeleniumTestCase
{
//const TEST_HUB = '217.21.179.192';
const TEST_HUB = '192.168.56.101';
const TEST_PORT = 12666;
const USERNAME = 'dragonbe+tek13@gmail.com';
const PASSWORD = 'test1234';
const BASURL = 'http://www.theialive.com';
public static $browsers = array (
array (
'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Firefox on Windows 7', 'browser' => '*firefox',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
);
protected function setUp()
{
$this->setBrowserUrl(self::BASURL);
}
}
Base	
  TestCase
42
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extensions_SeleniumTestCase
{
//const TEST_HUB = '217.21.179.192';
const TEST_HUB = '192.168.56.101';
const TEST_PORT = 12666;
const USERNAME = 'dragonbe+tek13@gmail.com';
const PASSWORD = 'test1234';
const BASURL = 'http://www.theialive.com';
public static $browsers = array (
array (
'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Firefox on Windows 7', 'browser' => '*firefox',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
);
protected function setUp()
{
$this->setBrowserUrl(self::BASURL);
}
}
array (
'name' => 'Internet Explorer 8 on Windows 7',
'browser' => '*iexplore',
'host' => self::TEST_HUB,
'port' => self::TEST_PORT,
),
Base	
  TestCase
43
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extensions_SeleniumTestCase
{
//const TEST_HUB = '217.21.179.192';
const TEST_HUB = '192.168.56.101';
const TEST_PORT = 12666;
const USERNAME = 'dragonbe+tek13@gmail.com';
const PASSWORD = 'test1234';
const BASURL = 'http://www.theialive.com';
public static $browsers = array (
array (
'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Firefox on Windows 7', 'browser' => '*firefox',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
);
protected function setUp()
{
$this->setBrowserUrl(self::BASURL);
}
}
array (
'name' => 'Firefox on Windows 7',
'browser' => '*firefox',
'host' => self::TEST_HUB,
'port' => self::TEST_PORT,
),
Base	
  TestCase
44
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extensions_SeleniumTestCase
{
//const TEST_HUB = '217.21.179.192';
const TEST_HUB = '192.168.56.101';
const TEST_PORT = 12666;
const USERNAME = 'dragonbe+tek13@gmail.com';
const PASSWORD = 'test1234';
const BASURL = 'http://www.theialive.com';
public static $browsers = array (
array (
'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Firefox on Windows 7', 'browser' => '*firefox',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
array (
'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome',
'host' => self::TEST_HUB, 'port' => self::TEST_PORT,
),
);
protected function setUp()
{
$this->setBrowserUrl(self::BASURL);
}
}
array (
'name' => 'Google Chrome on Windows 7',
'browser' => '*googlechrome',
'host' => self::TEST_HUB,
'port' => self::TEST_PORT,
),
Modify	
  MarkTaskDoneTest	
  
<?php
/**
* Class MarkTaskDoneTest
*
* @group Selenium
*/
require_once 'TestCase.php';
class MarkTaskDoneTest extends TestCase
{
public function testMarkTestAsDone()
{
$this->open("/");
$this->click("link=login");
$this->waitForPageToLoad("30000");
$this->type("id=email", TestCase::USERNAME);
$this->type("id=password", TestCase::PASSWORD);
$this->click("id=signin");
$this->waitForPageToLoad("30000");
$this->click("link=Test demo");
$this->waitForPageToLoad("30000");
$this->assertEquals("Done", $this->getText("xpath=//th[5]"));
$this->click("link=[EDIT]");
$this->waitForPageToLoad("30000");
$this->assertTrue($this->isElementPresent("id=done"));
$this->click("link=sign off");
$this->waitForPageToLoad("30000");
}
}
45
Require the TestCase
and extend it
Running	
  test
46
47
Benefits
• run	
  your	
  tests	
  on	
  mul'ple	
  browsers
• detect	
  flaws	
  in	
  specific	
  browsers	
  (e.g.	
  IE6)
-­‐ adapt	
  your	
  apps	
  to	
  solve	
  these	
  flaws
48
Mul'ple	
  Node	
  Setup
49
The	
  GRID
50
• Procedure
-­‐ centralized	
  server	
  (HUB)
-­‐ commands	
  clients	
  (nodes)	
  registered
-­‐ and	
  executes	
  the	
  tests
• Goal
-­‐ allow	
  for	
  automa'on
-­‐ adding	
  clients	
  as	
  you	
  go
Selenium	
  Grid	
  Setup
51
Selenium Testing
CI Server Windows
"HUB"
Linux client
"NODE"
CI executes tests
Windows HUB launches
Selenium node clients
to execute tests
Windows Server collects
feedback from the Citrix
client nodes and reports
back to CI Server
Windows client
"NODE"
Mac OS X client
"NODE"
Continuous User Acceptance Testing
Star'ng	
  the	
  server	
  [HUB]
52
"C:Program FilesJavajre7binjava.exe"
-jar "C:Jarselenium-server-standalone-2.28.0.jar"
-role hub
-port 12666
Star'ng	
  the	
  client	
  [NODE]
53
"C:Program FilesJavajre7binjava.exe"
-jar "C:Jarselenium-server-standalone-2.28.0.jar"
-role node
-host 192.168.56.103
-port 13666
-hub http://192.168.56.101:12666/grid/register
Mul'ple	
  nodes
54
Problem
55
Modify	
  Base	
  TestCase
56
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extensions_SeleniumTestCase
{
const TEST_HUB_WIN = '192.168.56.101';
const TEST_HUB_MAC = '192.168.56.1';
const TEST_HUB_LINUX = '192.168.56.102';
const TEST_PORT = 13666;
const USERNAME = 'dragonbe+tek13@gmail.com';
const PASSWORD = 'test1234';
const BASURL = 'http://www.theialive.com';
public static $browsers = array (
array (
'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore',
'host' => self::TEST_HUB_WIN, 'port' => self::TEST_PORT,
),
array (
'name' => 'Firefox on Mac OS X', 'browser' => '*firefox',
'host' => self::TEST_HUB_MAC, 'port' => self::TEST_PORT,
),
array (
'name' => 'Google Chrome on Linux', 'browser' => '*googlechrome',
'host' => self::TEST_HUB_LINUX, 'port' => self::TEST_PORT,
),
);
protected function setUp()
{
$this->setBrowserUrl(self::BASURL);
}
}
More	
  informa'on
57
seleniumhq.org
58
phpunit.de
59
http://www.phpunit.de/manual/3.5/en/selenium.html
Credits
60
• michelangelo:	
  hTp://www.flickr.com/photos/akrabat/
8784318813
• apple	
  store:	
  hTp://www.flickr.com/photos/jtjdt/3571748777
• checklist:	
  hTp://www.flickr.com/photos/alancleaver/4439276478
• flat	
  're:	
  hTp://www.flickr.com/photos/anijdam/2468493546/
• first	
  place:	
  hTp://www.flickr.com/photos/evelynishere/
3417340248/
• gears:	
  hTp://www.flickr.com/photos/wwarby/4782904694
• steps:	
  hTp://www.flickr.com/photos/ben_salter/1407168763
• browsers:	
  hTp://www.flickr.com/photos/richoz/3791167457
• informa'on:	
  hTp://www.flickr.com/photos/twicepix/
2650241408/
• elephpant:	
  hTp://www.flickr.com/photos/drewm/3191872515
Contact
61
Michelangelo van Dam
Zend Certified Engineer
email: michelangelo@in2it.be
Contact us for
Consultancy - Training - QA - Webdesign
62
https://joind.in/9080
Thank	
  you
63

More Related Content

What's hot (20)

PDF
JavaScript & HTML5 - Brave New World
Robert Nyman
 
PDF
Better Bullshit Driven Development [SeleniumCamp 2017]
automician
 
PDF
HTML5 JavaScript APIs
Remy Sharp
 
ODP
Beyond PHP - it's not (just) about the code
Wim Godden
 
PDF
soft-shake.ch - Hands on Node.js
soft-shake.ch
 
PDF
HTML5: friend or foe (to Flash)?
Remy Sharp
 
TXT
Send.php
abdoahmd44
 
PDF
Getting started with TDD - Confoo 2014
Eric Hogue
 
TXT
https://www.facebook.com/valdyna.monna?fref=ts
Arif Alexi
 
ODP
My app is secure... I think
Wim Godden
 
PDF
HTML5 & The Open Web - at Nackademin
Robert Nyman
 
ZIP
YUI 3
Dav Glass
 
PDF
What the heck went wrong?
Andy McKay
 
PDF
Continuous testing In PHP
Eric Hogue
 
PDF
Sane Async Patterns
TrevorBurnham
 
PPTX
The Screenplay Pattern: Better Interactions for Better Automation
Applitools
 
PDF
Commencer avec le TDD
Eric Hogue
 
ODP
My app is secure... I think
Wim Godden
 
PPT
Creating the interfaces of the future with the APIs of today
gerbille
 
PDF
Websockets talk at Rubyconf Uruguay 2010
Ismael Celis
 
JavaScript & HTML5 - Brave New World
Robert Nyman
 
Better Bullshit Driven Development [SeleniumCamp 2017]
automician
 
HTML5 JavaScript APIs
Remy Sharp
 
Beyond PHP - it's not (just) about the code
Wim Godden
 
soft-shake.ch - Hands on Node.js
soft-shake.ch
 
HTML5: friend or foe (to Flash)?
Remy Sharp
 
Send.php
abdoahmd44
 
Getting started with TDD - Confoo 2014
Eric Hogue
 
https://www.facebook.com/valdyna.monna?fref=ts
Arif Alexi
 
My app is secure... I think
Wim Godden
 
HTML5 & The Open Web - at Nackademin
Robert Nyman
 
YUI 3
Dav Glass
 
What the heck went wrong?
Andy McKay
 
Continuous testing In PHP
Eric Hogue
 
Sane Async Patterns
TrevorBurnham
 
The Screenplay Pattern: Better Interactions for Better Automation
Applitools
 
Commencer avec le TDD
Eric Hogue
 
My app is secure... I think
Wim Godden
 
Creating the interfaces of the future with the APIs of today
gerbille
 
Websockets talk at Rubyconf Uruguay 2010
Ismael Celis
 

Similar to UA Testing with Selenium and PHPUnit - ZendCon 2013 (20)

PDF
UA testing with Selenium and PHPUnit - PFCongres 2013
Michelangelo van Dam
 
PDF
Better Testing With PHP Unit
sitecrafting
 
PDF
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
Vladimir Roudakov
 
PPT
Selenium
husnara mohammad
 
PDF
Browser testing with nightwatch.js - Drupal Europe
Salvador Molina (Slv_)
 
KEY
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
PDF
symfony on action - WebTech 207
patter
 
PDF
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
PDF
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
Enterprise PHP Center
 
PDF
Join the darkside: Selenium testing with Nightwatch.js
Seth McLaughlin
 
PDF
Charla EHU Noviembre 2014 - Desarrollo Web
Mikel Torres Ugarte
 
KEY
Phpne august-2012-symfony-components-friends
Michael Peacock
 
PDF
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
PDF
20160905 - BrisJS - nightwatch testing
Vladimir Roudakov
 
PDF
Unit testing with zend framework tek11
Michelangelo van Dam
 
PDF
Selenium rc presentation_20110104
Michael Salvucci
 
PDF
Selenium RC Presentation 20110104
Michael Salvucci
 
PDF
Leveling Up With Unit Testing - php[tek] 2023
Mark Niebergall
 
PDF
Symfony2 from the Trenches
Jonathan Wage
 
PDF
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
UA testing with Selenium and PHPUnit - PFCongres 2013
Michelangelo van Dam
 
Better Testing With PHP Unit
sitecrafting
 
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
Vladimir Roudakov
 
Browser testing with nightwatch.js - Drupal Europe
Salvador Molina (Slv_)
 
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
symfony on action - WebTech 207
patter
 
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
Enterprise PHP Center
 
Join the darkside: Selenium testing with Nightwatch.js
Seth McLaughlin
 
Charla EHU Noviembre 2014 - Desarrollo Web
Mikel Torres Ugarte
 
Phpne august-2012-symfony-components-friends
Michael Peacock
 
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
20160905 - BrisJS - nightwatch testing
Vladimir Roudakov
 
Unit testing with zend framework tek11
Michelangelo van Dam
 
Selenium rc presentation_20110104
Michael Salvucci
 
Selenium RC Presentation 20110104
Michael Salvucci
 
Leveling Up With Unit Testing - php[tek] 2023
Mark Niebergall
 
Symfony2 from the Trenches
Jonathan Wage
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
Ad

More from Michelangelo van Dam (20)

PDF
GDPR Art. 25 - Privacy by design and default
Michelangelo van Dam
 
PDF
Moving from app services to azure functions
Michelangelo van Dam
 
PDF
Privacy by design
Michelangelo van Dam
 
PDF
DevOps or DevSecOps
Michelangelo van Dam
 
PDF
Privacy by design
Michelangelo van Dam
 
PDF
Continuous deployment 2.0
Michelangelo van Dam
 
PDF
Let your tests drive your code
Michelangelo van Dam
 
PDF
General Data Protection Regulation, a developer's story
Michelangelo van Dam
 
PDF
Leveraging a distributed architecture to your advantage
Michelangelo van Dam
 
PDF
The road to php 7.1
Michelangelo van Dam
 
PDF
Open source for a successful business
Michelangelo van Dam
 
PDF
Decouple your framework now, thank me later
Michelangelo van Dam
 
PDF
Deploy to azure in less then 15 minutes
Michelangelo van Dam
 
PDF
Azure and OSS, a match made in heaven
Michelangelo van Dam
 
PDF
Getting hands dirty with php7
Michelangelo van Dam
 
PDF
Create, test, secure, repeat
Michelangelo van Dam
 
PDF
The Continuous PHP Pipeline
Michelangelo van Dam
 
PDF
PHPUnit Episode iv.iii: Return of the tests
Michelangelo van Dam
 
PDF
Easily extend your existing php app with an api
Michelangelo van Dam
 
PDF
Your code are my tests
Michelangelo van Dam
 
GDPR Art. 25 - Privacy by design and default
Michelangelo van Dam
 
Moving from app services to azure functions
Michelangelo van Dam
 
Privacy by design
Michelangelo van Dam
 
DevOps or DevSecOps
Michelangelo van Dam
 
Privacy by design
Michelangelo van Dam
 
Continuous deployment 2.0
Michelangelo van Dam
 
Let your tests drive your code
Michelangelo van Dam
 
General Data Protection Regulation, a developer's story
Michelangelo van Dam
 
Leveraging a distributed architecture to your advantage
Michelangelo van Dam
 
The road to php 7.1
Michelangelo van Dam
 
Open source for a successful business
Michelangelo van Dam
 
Decouple your framework now, thank me later
Michelangelo van Dam
 
Deploy to azure in less then 15 minutes
Michelangelo van Dam
 
Azure and OSS, a match made in heaven
Michelangelo van Dam
 
Getting hands dirty with php7
Michelangelo van Dam
 
Create, test, secure, repeat
Michelangelo van Dam
 
The Continuous PHP Pipeline
Michelangelo van Dam
 
PHPUnit Episode iv.iii: Return of the tests
Michelangelo van Dam
 
Easily extend your existing php app with an api
Michelangelo van Dam
 
Your code are my tests
Michelangelo van Dam
 
Ad

Recently uploaded (20)

PPTX
𝙳𝚘𝚠𝚗𝚕𝚘𝚊𝚍—Wondershare Filmora Crack 14.0.7 + Key Download 2025
sebastian aliya
 
PDF
UiPath Agentic AI ile Akıllı Otomasyonun Yeni Çağı
UiPathCommunity
 
PDF
LLM Search Readiness Audit - Dentsu x SEO Square - June 2025.pdf
Nick Samuel
 
PPTX
Practical Applications of AI in Local Government
OnBoard
 
PDF
Plugging AI into everything: Model Context Protocol Simplified.pdf
Abati Adewale
 
PDF
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
PPTX
Simplifica la seguridad en la nube y la detección de amenazas con FortiCNAPP
Cristian Garcia G.
 
PDF
Java 25 and Beyond - A Roadmap of Innovations
Ana-Maria Mihalceanu
 
PDF
Hello I'm "AI" Your New _________________
Dr. Tathagat Varma
 
PPTX
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
PDF
Kubernetes - Architecture & Components.pdf
geethak285
 
PDF
5 Things to Consider When Deploying AI in Your Enterprise
Safe Software
 
PDF
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
PDF
Unlocking FME Flow’s Potential: Architecture Design for Modern Enterprises
Safe Software
 
PDF
ArcGIS Utility Network Migration - The Hunter Water Story
Safe Software
 
PDF
Redefining Work in the Age of AI - What to expect? How to prepare? Why it mat...
Malinda Kapuruge
 
PPTX
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
PDF
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
PDF
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
PPTX
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
𝙳𝚘𝚠𝚗𝚕𝚘𝚊𝚍—Wondershare Filmora Crack 14.0.7 + Key Download 2025
sebastian aliya
 
UiPath Agentic AI ile Akıllı Otomasyonun Yeni Çağı
UiPathCommunity
 
LLM Search Readiness Audit - Dentsu x SEO Square - June 2025.pdf
Nick Samuel
 
Practical Applications of AI in Local Government
OnBoard
 
Plugging AI into everything: Model Context Protocol Simplified.pdf
Abati Adewale
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
Simplifica la seguridad en la nube y la detección de amenazas con FortiCNAPP
Cristian Garcia G.
 
Java 25 and Beyond - A Roadmap of Innovations
Ana-Maria Mihalceanu
 
Hello I'm "AI" Your New _________________
Dr. Tathagat Varma
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
Kubernetes - Architecture & Components.pdf
geethak285
 
5 Things to Consider When Deploying AI in Your Enterprise
Safe Software
 
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
Unlocking FME Flow’s Potential: Architecture Design for Modern Enterprises
Safe Software
 
ArcGIS Utility Network Migration - The Hunter Water Story
Safe Software
 
Redefining Work in the Age of AI - What to expect? How to prepare? Why it mat...
Malinda Kapuruge
 
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
UserCon Belgium: Honey, VMware increased my bill
stijn40
 

UA Testing with Selenium and PHPUnit - ZendCon 2013

  • 1. UA  Tes'ng  with Selenium  and  PHPUnit ZendCon  2013,  Santa  Clara
  • 2. 2 • PHP  Consultant • President  PHPBenelux • Conference  speaker Michelangelo  van  Dam
  • 3. 3
  • 4. Today’s  goal • Set  up  and  use  Selenium  IDE • Record  UA  tests • Convert  to  PHPUnit • Run  con'nuously • Mul'  browser  support 4
  • 5. 5 DISCLAIMER S E L E N I U M T E S T S A R E N OT A REPLACEMENT FOR REGULAR UNIT TESTING. THEY ONLY PROVIDE AN ADDITIONAL SET OF TESTS FOCUSED ON USER ACCEPTANCE AND USER EXPERIENCE TESTING. For more information about unit testing, please see my other material on www.slideshare.net and www.speakerdeck.com. Search for “dragonbe”!
  • 7. 7 “Acceptance testing is a test conducted to determine if the requirements of a specification or contract are met.” -- source: wikipedia
  • 8. Checklist  for  web  applica'ons 8
  • 9. 9 Func'onal  tes'ng • Test  func'onal  requirements -­‐ e.g.  no  access  to  profile  without  authen'ca'on • Test  UI  elements  on  the  web  interface -­‐ e.g.  buTons,  form  elements,  AJAX  controls,  …
  • 10. A  word  of  cau'on! 10 • UA  tests  only  test  generated  output -­‐ not  a  replacement  for  unit  tes'ng • UA  tests  are  heavily  depending  on  DOM -­‐ changes  to  the  DOM  might  lead  to  failing  UAT
  • 12. Selenium  to  the  rescue 12
  • 14. Get  the  plugin  (demo) 14
  • 17. Pick  a  test  case 17
  • 19. Verify  this  issue  on  PROD 19
  • 20. 20
  • 22. Run  test  to  see  it’s  fixed 22
  • 23. 23
  • 24. 24 Save  your  test  as  .html
  • 27. PHPUnit  to  the  rescue 27
  • 29. The  PHPUnit  TestCase 29 <?php class Example extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("http://www.theialive.com/"); } public function testMyTestCase() { $this->open("/"); $this->click("link=login"); $this->waitForPageToLoad("30000"); $this->type("id=email", "[email protected]"); $this->type("id=password", "test1234"); $this->click("id=signin"); $this->waitForPageToLoad("30000"); $this->click("link=Test demo"); $this->waitForPageToLoad("30000"); $this->assertEquals("Done", $this->getText("xpath=//th[5]")); $this->click("link=[EDIT]"); $this->waitForPageToLoad("30000"); $this->assertTrue($this->isElementPresent("id=done")); $this->click("link=sign off"); $this->waitForPageToLoad("30000"); } } ?>
  • 30. Change  class  name 30 <?php class Example extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("http://www.theialive.com/"); } public function testMyTestCase() { $this->open("/"); $this->click("link=login"); $this->waitForPageToLoad("30000"); $this->type("id=email", "[email protected]"); $this->type("id=password", "test1234"); $this->click("id=signin"); $this->waitForPageToLoad("30000"); $this->click("link=Test demo"); $this->waitForPageToLoad("30000"); $this->assertEquals("Done", $this->getText("xpath=//th[5]")); $this->click("link=[EDIT]"); $this->waitForPageToLoad("30000"); $this->assertTrue($this->isElementPresent("id=done")); $this->click("link=sign off"); $this->waitForPageToLoad("30000"); } } ?> class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
  • 31. The  PHPUnit  TestCase 31 <?php class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("http://www.theialive.com/"); } public function testMyTestCase() { $this->open("/"); $this->click("link=login"); $this->waitForPageToLoad("30000"); $this->type("id=email", "[email protected]"); $this->type("id=password", "test1234"); $this->click("id=signin"); $this->waitForPageToLoad("30000"); $this->click("link=Test demo"); $this->waitForPageToLoad("30000"); $this->assertEquals("Done", $this->getText("xpath=//th[5]")); $this->click("link=[EDIT]"); $this->waitForPageToLoad("30000"); $this->assertTrue($this->isElementPresent("id=done")); $this->click("link=sign off"); $this->waitForPageToLoad("30000"); } } ?> protected function setUp() { $this->setBrowser("*iexplore"); $this->setBrowserUrl("http://www.theialive.com/"); $this->setHost('192.168.56.101'); $this->setPort(12666); }
  • 32. Meaningful  method  name <?php class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this->setBrowser("*iexplore"); $this->setBrowserUrl("http://www.theialive.com/"); $this->setHost('192.168.56.101'); $this->setPort(12666); } public function testMyTestCase() { $this->open("/"); $this->click("link=login"); $this->waitForPageToLoad("30000"); $this->type("id=email", "[email protected]"); $this->type("id=password", "test1234"); $this->click("id=signin"); $this->waitForPageToLoad("30000"); $this->click("link=Test demo"); $this->waitForPageToLoad("30000"); $this->assertEquals("Done", $this->getText("xpath=//th[5]")); $this->click("link=[EDIT]"); $this->waitForPageToLoad("30000"); $this->assertTrue($this->isElementPresent("id=done")); $this->click("link=sign off"); $this->waitForPageToLoad("30000"); } } ?> 32 public function testMarkTestAsDone()
  • 34. Now  run  your  tests 34
  • 36. How  it  runs  on  the  node 36
  • 38. Advantages 38 • You  can  start  tes'ng  immediately • Even  test  “hard  to  test”  kind  of  situa'ons • More  nodes  for  parallel  tes'ng • Tes'ng  different  browsers  and  plaforms • Con'nuous  Integra'on  possible
  • 41. Base  TestCase 41 <?php require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; class TestCase extends PHPUnit_Extensions_SeleniumTestCase { //const TEST_HUB = '217.21.179.192'; const TEST_HUB = '192.168.56.101'; const TEST_PORT = 12666; const USERNAME = '[email protected]'; const PASSWORD = 'test1234'; const BASURL = 'http://www.theialive.com'; public static $browsers = array ( array ( 'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Firefox on Windows 7', 'browser' => '*firefox', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), ); protected function setUp() { $this->setBrowserUrl(self::BASURL); } }
  • 42. Base  TestCase 42 <?php require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; class TestCase extends PHPUnit_Extensions_SeleniumTestCase { //const TEST_HUB = '217.21.179.192'; const TEST_HUB = '192.168.56.101'; const TEST_PORT = 12666; const USERNAME = '[email protected]'; const PASSWORD = 'test1234'; const BASURL = 'http://www.theialive.com'; public static $browsers = array ( array ( 'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Firefox on Windows 7', 'browser' => '*firefox', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), ); protected function setUp() { $this->setBrowserUrl(self::BASURL); } } array ( 'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ),
  • 43. Base  TestCase 43 <?php require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; class TestCase extends PHPUnit_Extensions_SeleniumTestCase { //const TEST_HUB = '217.21.179.192'; const TEST_HUB = '192.168.56.101'; const TEST_PORT = 12666; const USERNAME = '[email protected]'; const PASSWORD = 'test1234'; const BASURL = 'http://www.theialive.com'; public static $browsers = array ( array ( 'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Firefox on Windows 7', 'browser' => '*firefox', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), ); protected function setUp() { $this->setBrowserUrl(self::BASURL); } } array ( 'name' => 'Firefox on Windows 7', 'browser' => '*firefox', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ),
  • 44. Base  TestCase 44 <?php require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; class TestCase extends PHPUnit_Extensions_SeleniumTestCase { //const TEST_HUB = '217.21.179.192'; const TEST_HUB = '192.168.56.101'; const TEST_PORT = 12666; const USERNAME = '[email protected]'; const PASSWORD = 'test1234'; const BASURL = 'http://www.theialive.com'; public static $browsers = array ( array ( 'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Firefox on Windows 7', 'browser' => '*firefox', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), array ( 'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ), ); protected function setUp() { $this->setBrowserUrl(self::BASURL); } } array ( 'name' => 'Google Chrome on Windows 7', 'browser' => '*googlechrome', 'host' => self::TEST_HUB, 'port' => self::TEST_PORT, ),
  • 45. Modify  MarkTaskDoneTest   <?php /** * Class MarkTaskDoneTest * * @group Selenium */ require_once 'TestCase.php'; class MarkTaskDoneTest extends TestCase { public function testMarkTestAsDone() { $this->open("/"); $this->click("link=login"); $this->waitForPageToLoad("30000"); $this->type("id=email", TestCase::USERNAME); $this->type("id=password", TestCase::PASSWORD); $this->click("id=signin"); $this->waitForPageToLoad("30000"); $this->click("link=Test demo"); $this->waitForPageToLoad("30000"); $this->assertEquals("Done", $this->getText("xpath=//th[5]")); $this->click("link=[EDIT]"); $this->waitForPageToLoad("30000"); $this->assertTrue($this->isElementPresent("id=done")); $this->click("link=sign off"); $this->waitForPageToLoad("30000"); } } 45 Require the TestCase and extend it
  • 47. 47
  • 48. Benefits • run  your  tests  on  mul'ple  browsers • detect  flaws  in  specific  browsers  (e.g.  IE6) -­‐ adapt  your  apps  to  solve  these  flaws 48
  • 50. The  GRID 50 • Procedure -­‐ centralized  server  (HUB) -­‐ commands  clients  (nodes)  registered -­‐ and  executes  the  tests • Goal -­‐ allow  for  automa'on -­‐ adding  clients  as  you  go
  • 51. Selenium  Grid  Setup 51 Selenium Testing CI Server Windows "HUB" Linux client "NODE" CI executes tests Windows HUB launches Selenium node clients to execute tests Windows Server collects feedback from the Citrix client nodes and reports back to CI Server Windows client "NODE" Mac OS X client "NODE" Continuous User Acceptance Testing
  • 52. Star'ng  the  server  [HUB] 52 "C:Program FilesJavajre7binjava.exe" -jar "C:Jarselenium-server-standalone-2.28.0.jar" -role hub -port 12666
  • 53. Star'ng  the  client  [NODE] 53 "C:Program FilesJavajre7binjava.exe" -jar "C:Jarselenium-server-standalone-2.28.0.jar" -role node -host 192.168.56.103 -port 13666 -hub http://192.168.56.101:12666/grid/register
  • 56. Modify  Base  TestCase 56 <?php require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; class TestCase extends PHPUnit_Extensions_SeleniumTestCase { const TEST_HUB_WIN = '192.168.56.101'; const TEST_HUB_MAC = '192.168.56.1'; const TEST_HUB_LINUX = '192.168.56.102'; const TEST_PORT = 13666; const USERNAME = '[email protected]'; const PASSWORD = 'test1234'; const BASURL = 'http://www.theialive.com'; public static $browsers = array ( array ( 'name' => 'Internet Explorer 8 on Windows 7', 'browser' => '*iexplore', 'host' => self::TEST_HUB_WIN, 'port' => self::TEST_PORT, ), array ( 'name' => 'Firefox on Mac OS X', 'browser' => '*firefox', 'host' => self::TEST_HUB_MAC, 'port' => self::TEST_PORT, ), array ( 'name' => 'Google Chrome on Linux', 'browser' => '*googlechrome', 'host' => self::TEST_HUB_LINUX, 'port' => self::TEST_PORT, ), ); protected function setUp() { $this->setBrowserUrl(self::BASURL); } }
  • 60. Credits 60 • michelangelo:  hTp://www.flickr.com/photos/akrabat/ 8784318813 • apple  store:  hTp://www.flickr.com/photos/jtjdt/3571748777 • checklist:  hTp://www.flickr.com/photos/alancleaver/4439276478 • flat  're:  hTp://www.flickr.com/photos/anijdam/2468493546/ • first  place:  hTp://www.flickr.com/photos/evelynishere/ 3417340248/ • gears:  hTp://www.flickr.com/photos/wwarby/4782904694 • steps:  hTp://www.flickr.com/photos/ben_salter/1407168763 • browsers:  hTp://www.flickr.com/photos/richoz/3791167457 • informa'on:  hTp://www.flickr.com/photos/twicepix/ 2650241408/ • elephpant:  hTp://www.flickr.com/photos/drewm/3191872515
  • 61. Contact 61 Michelangelo van Dam Zend Certified Engineer email: [email protected] Contact us for Consultancy - Training - QA - Webdesign