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	
  c...
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 ...
User	
  Acceptance
6
7
“Acceptance testing is a test conducted to determine if
the requirements of a specification or contract are met.”
-- sour...
Checklist	
  for	
  web	
  applica'ons
8
9
Func'onal	
  tes'ng
• Test	
  func'onal	
  requirements
-­‐ e.g.	
  no	
  access	
  to	
  profile	
  without	
  authen'ca...
A	
  word	
  of	
  cau'on!
10
• UA	
  tests	
  only	
  test	
  generated	
  output
-­‐ not	
  a	
  replacement	
  for	
  u...
Browser	
  support
11
Selenium	
  to	
  the	
  rescue
12
Plugin	
  for	
  firefox
13
Get	
  the	
  plugin	
  (demo)
14
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()...
Change	
  class	
  name
30
<?php
class Example extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
...
The	
  PHPUnit	
  TestCase
31
<?php
class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
{
protected functio...
Meaningful	
  method	
  name
<?php
class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
{
protected function...
startSeleniumStandAlone.BAT
33
"C:Program FilesJavajre7binjava.exe"
-jar "C:Jarselenium-server-standalone-2.28.0.jar"
-por...
Now	
  run	
  your	
  tests
34
How	
  it	
  runs	
  on	
  the	
  node
36
Advantages
38
• You	
  can	
  start	
  tes'ng	
  immediately
• Even	
  test	
  “hard	
  to	
  test”	
  kind	
  of	
  situa...
Next	
  Steps
39
Mul'	
  Browser	
  support
40
Base	
  TestCase
41
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extension...
Base	
  TestCase
42
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extension...
Base	
  TestCase
43
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extension...
Base	
  TestCase
44
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit_Extension...
Modify	
  MarkTaskDoneTest	
  
<?php
/**
* Class MarkTaskDoneTest
*
* @group Selenium
*/
require_once 'TestCase.php';
clas...
Running	
  test
46
47
Benefits
• run	
  your	
  tests	
  on	
  mul'ple	
  browsers
• detect	
  flaws	
  in	
  specific	
  browsers	
  (e.g.	
  IE6)...
Mul'ple	
  Node	
  Setup
49
The	
  GRID
50
• Procedure
-­‐ centralized	
  server	
  (HUB)
-­‐ commands	
  clients	
  (nodes)	
  registered
-­‐ and	
  ...
Selenium	
  Grid	
  Setup
51
Selenium Testing
CI Server Windows
"HUB"
Linux client
"NODE"
CI executes tests
Windows HUB la...
Star'ng	
  the	
  server	
  [HUB]
52
"C:Program FilesJavajre7binjava.exe"
-jar "C:Jarselenium-server-standalone-2.28.0.jar...
Star'ng	
  the	
  client	
  [NODE]
53
"C:Program FilesJavajre7binjava.exe"
-jar "C:Jarselenium-server-standalone-2.28.0.ja...
Mul'ple	
  nodes
54
Problem
55
Modify	
  Base	
  TestCase
56
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class TestCase extends PHPUnit...
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/phot...
Contact
61
Michelangelo van Dam
Zend Certified Engineer
email: michelangelo@in2it.be
Contact us for
Consultancy - Training ...
62
https://joind.in/9080
Thank	
  you
63
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013
Upcoming SlideShare
Loading in...5
×

UA Testing with Selenium and PHPUnit - ZendCon 2013

3,335
-1

Published on

Nothing is as frustrated as deploying a new release of your web application to find out functionality you had doesn't work anymore. Of course you have all your unit tests in place and you run them through your CI environment, but nothing prepared you to a failing javascript error or a link that doesn't work anymore. Welcome to User Acceptance testing or UAT. Before you start putting real people in front of your application, create macros and export them as PHPUnit test classes. Then run them in an automated way just like your unit tests and hook them into your CI. In this talk I will show you how easy it is to create Selenium macros that can be converted into PHPUnit scripts and run automatically on different virtual machines (VM's) so you can test all different browsers on a diversity of operating systems.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,335
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
36
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

UA Testing with Selenium and PHPUnit - ZendCon 2013

  1. 1. UA  Tes'ng  with Selenium  and  PHPUnit ZendCon  2013,  Santa  Clara
  2. 2. 2 • PHP  Consultant • President  PHPBenelux • Conference  speaker Michelangelo  van  Dam
  3. 3. 3
  4. 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. 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”!
  6. 6. User  Acceptance 6
  7. 7. 7 “Acceptance testing is a test conducted to determine if the requirements of a specification or contract are met.” -- source: wikipedia
  8. 8. Checklist  for  web  applica'ons 8
  9. 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. 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
  11. 11. Browser  support 11
  12. 12. Selenium  to  the  rescue 12
  13. 13. Plugin  for  firefox 13
  14. 14. Get  the  plugin  (demo) 14
  15. 15. Let’s  get  started 16
  16. 16. Pick  a  test  case 17
  17. 17. Issue  #7 18
  18. 18. Verify  this  issue  on  PROD 19
  19. 19. 20
  20. 20. Fix  the  issue 21
  21. 21. Run  test  to  see  it’s  fixed 22
  22. 22. 23
  23. 23. 24 Save  your  test  as  .html
  24. 24. It’s  that  easy! 25
  25. 25. Automated  Tes'ng 26
  26. 26. PHPUnit  to  the  rescue 27
  27. 27. Export  to  PHPUnit 28
  28. 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"); } } ?>
  29. 29. 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
  30. 30. 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); }
  31. 31. 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()
  32. 32. startSeleniumStandAlone.BAT 33 "C:Program FilesJavajre7binjava.exe" -jar "C:Jarselenium-server-standalone-2.28.0.jar" -port 12666
  33. 33. Now  run  your  tests 34
  34. 34. How  it  runs  on  the  node 36
  35. 35. 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
  36. 36. Next  Steps 39
  37. 37. Mul'  Browser  support 40
  38. 38. 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); } }
  39. 39. 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, ),
  40. 40. 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, ),
  41. 41. 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, ),
  42. 42. 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
  43. 43. Running  test 46
  44. 44. 47
  45. 45. Benefits • run  your  tests  on  mul'ple  browsers • detect  flaws  in  specific  browsers  (e.g.  IE6) -­‐ adapt  your  apps  to  solve  these  flaws 48
  46. 46. Mul'ple  Node  Setup 49
  47. 47. 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
  48. 48. 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
  49. 49. Star'ng  the  server  [HUB] 52 "C:Program FilesJavajre7binjava.exe" -jar "C:Jarselenium-server-standalone-2.28.0.jar" -role hub -port 12666
  50. 50. 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
  51. 51. Mul'ple  nodes 54
  52. 52. Problem 55
  53. 53. 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); } }
  54. 54. More  informa'on 57
  55. 55. seleniumhq.org 58
  56. 56. phpunit.de 59 http://www.phpunit.de/manual/3.5/en/selenium.html
  57. 57. 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
  58. 58. Contact 61 Michelangelo van Dam Zend Certified Engineer email: michelangelo@in2it.be Contact us for Consultancy - Training - QA - Webdesign
  59. 59. 62 https://joind.in/9080
  60. 60. Thank  you 63
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×