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

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
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
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
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
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
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
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
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
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 

Recently uploaded (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
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
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
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
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
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
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
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...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
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
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 

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