SlideShare a Scribd company logo
1 of 63
Download to read offline
UA	
  Tes'ng	
  with
Selenium	
  and	
  PHPUnit
Dutch	
  PHP	
  Conference	
  2013,	
  Amsterdam
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.	
  buQons,	
  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
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
How	
  it	
  runs	
  on	
  the	
  node
36
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	
  placorms
• 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 = '217.21.179.192';
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
• apple	
  store:	
  hQp://www.flickr.com/photos/jtjdt/3571748777
• checklist:	
  hQp://www.flickr.com/photos/alancleaver/
4439276478
• flat	
  're:	
  hQp://www.flickr.com/photos/anijdam/2468493546/
• first	
  place:	
  hQp://www.flickr.com/photos/evelynishere/
3417340248/
• gears:	
  hQp://www.flickr.com/photos/wwarby/4782904694
• steps:	
  hQp://www.flickr.com/photos/ben_salter/1407168763
• browsers:	
  hQp://www.flickr.com/photos/richoz/3791167457
• informa'on:	
  hQp://www.flickr.com/photos/twicepix/
2650241408/
• elephpant:	
  hQp://www.flickr.com/photos/drewm/3191872515
Contact
61
Michelangelo van Dam
Zend Certified Engineer
email: michelangelo@in2it.be
skype: michelangelovandam
twitter: @DragonBe
tel EU: +32 15 34 52 90
tel US: 202 559-7401
www.in2it.be
facebook.com/in2itvof | @in2itvof
Contact us for
Consultancy - Training - QA - Webdesign
62
http://joind.in/8813
Thank	
  you
63

More Related Content

More from Michelangelo van Dam

GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultGDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultMichelangelo van Dam
 
Moving from app services to azure functions
Moving from app services to azure functionsMoving from app services to azure functions
Moving from app services to azure functionsMichelangelo van Dam
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyGeneral Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyMichelangelo van Dam
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageLeveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageMichelangelo van Dam
 
Open source for a successful business
Open source for a successful businessOpen source for a successful business
Open source for a successful businessMichelangelo van Dam
 
Decouple your framework now, thank me later
Decouple your framework now, thank me laterDecouple your framework now, thank me later
Decouple your framework now, thank me laterMichelangelo van Dam
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesDeploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesMichelangelo van Dam
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heavenAzure and OSS, a match made in heaven
Azure and OSS, a match made in heavenMichelangelo van Dam
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your projectMichelangelo van Dam
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
Easily extend your existing php app with an api
Easily extend your existing php app with an apiEasily extend your existing php app with an api
Easily extend your existing php app with an apiMichelangelo van Dam
 

More from Michelangelo van Dam (20)

GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultGDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and default
 
Moving from app services to azure functions
Moving from app services to azure functionsMoving from app services to azure functions
Moving from app services to azure functions
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
 
DevOps or DevSecOps
DevOps or DevSecOpsDevOps or DevSecOps
DevOps or DevSecOps
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
 
Continuous deployment 2.0
Continuous deployment 2.0Continuous deployment 2.0
Continuous deployment 2.0
 
Let your tests drive your code
Let your tests drive your codeLet your tests drive your code
Let your tests drive your code
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyGeneral Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's story
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageLeveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantage
 
The road to php 7.1
The road to php 7.1The road to php 7.1
The road to php 7.1
 
Open source for a successful business
Open source for a successful businessOpen source for a successful business
Open source for a successful business
 
Decouple your framework now, thank me later
Decouple your framework now, thank me laterDecouple your framework now, thank me later
Decouple your framework now, thank me later
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesDeploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutes
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heavenAzure and OSS, a match made in heaven
Azure and OSS, a match made in heaven
 
Getting hands dirty with php7
Getting hands dirty with php7Getting hands dirty with php7
Getting hands dirty with php7
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
 
The Continuous PHP Pipeline
The Continuous PHP PipelineThe Continuous PHP Pipeline
The Continuous PHP Pipeline
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Easily extend your existing php app with an api
Easily extend your existing php app with an apiEasily extend your existing php app with an api
Easily extend your existing php app with an api
 

Recently uploaded

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 

Recently uploaded (20)

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 

UA Testing with Selenium and PHPUnit DPC 2013

  • 1. UA  Tes'ng  with Selenium  and  PHPUnit Dutch  PHP  Conference  2013,  Amsterdam
  • 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.  buQons,  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
  • 15.
  • 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", "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"); } } ?>
  • 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", "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
  • 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", "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); }
  • 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", "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()
  • 34. Now  run  your  tests 34
  • 35.
  • 36. How  it  runs  on  the  node 36
  • 37.
  • 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  placorms • 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 = '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); } }
  • 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 = '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, ),
  • 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 = '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, ),
  • 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 = '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, ),
  • 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 = '217.21.179.192'; 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); } }
  • 60. Credits 60 • apple  store:  hQp://www.flickr.com/photos/jtjdt/3571748777 • checklist:  hQp://www.flickr.com/photos/alancleaver/ 4439276478 • flat  're:  hQp://www.flickr.com/photos/anijdam/2468493546/ • first  place:  hQp://www.flickr.com/photos/evelynishere/ 3417340248/ • gears:  hQp://www.flickr.com/photos/wwarby/4782904694 • steps:  hQp://www.flickr.com/photos/ben_salter/1407168763 • browsers:  hQp://www.flickr.com/photos/richoz/3791167457 • informa'on:  hQp://www.flickr.com/photos/twicepix/ 2650241408/ • elephpant:  hQp://www.flickr.com/photos/drewm/3191872515
  • 61. Contact 61 Michelangelo van Dam Zend Certified Engineer email: michelangelo@in2it.be skype: michelangelovandam twitter: @DragonBe tel EU: +32 15 34 52 90 tel US: 202 559-7401 www.in2it.be facebook.com/in2itvof | @in2itvof Contact us for Consultancy - Training - QA - Webdesign