SlideShare a Scribd company logo
UA	
  Tes'ng	
  with
Selenium	
  and	
  PHPUnit
TrueNorthPHP	
  2013	
  
Toronto,	
  Canada
Michelangelo	
  van	
  Dam
• PHP	
  Consultant	
  
• President	
  PHPBenelux	
  
• Conference	
  speaker

2
3
Today’s	
  goal
• Set	
  up	
  and	
  use	
  Selenium	
  IDE	
  
• Record	
  UA	
  tests	
  
• Convert	
  to	
  PHPUnit	
  
• Run	
  con'nuously	
  
• Mul'	
  browser	
  support
4
DISCLAIMER
SELENIUM TESTS ARE NOT A
REPLACEMENT FOR REGULAR UNIT
TESTING. THEY ONLY PROVIDE AN
ADDITIONAL SET OF TESTS FOCUSED ON
U S E R A C C E P TA N C E A N D U S E R
EXPERIENCE TESTING.
For more information about unit testing, please
see my other material on www.slideshare.net and
www.speakerdeck.com. Search for “dragonbe”!
5
User	
  Acceptance

6
“Acceptance testing is a test conducted to determine if
the requirements of a specification or contract are met.”	

!

-- source: wikipedia

7
Checklist	
  for	
  web	
  applica'ons

8
Func'onal	
  tes'ng

• Test	
  func'onal	
  requirements	
  
-­‐

e.g.	
  no	
  access	
  to	
  profile	
  without	
  authen'ca'on	
  

-­‐

e.g.	
  buTons,	
  form	
  elements,	
  AJAX	
  controls,	
  …

• Test	
  UI	
  elements	
  on	
  the	
  web	
  interface	
  

9
A	
  word	
  of	
  cau'on!

• UA	
  tests	
  only	
  test	
  generated	
  output	
  
-­‐

not	
  a	
  replacement	
  for	
  unit	
  tes'ng	
  

-­‐

changes	
  to	
  the	
  DOM	
  might	
  lead	
  to	
  failing	
  UAT

• UA	
  tests	
  are	
  heavily	
  depending	
  on	
  DOM	
  

10
Browser	
  support

11
Selenium	
  to	
  the	
  rescue

12
Plugin	
  for	
  firefox

13
Get	
  the	
  plugin	
  (demo)

14
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
Let’s	
  get	
  started

16
Pick	
  a	
  test	
  case

17
Issue	
  #7

18
Verify	
  this	
  issue	
  on	
  PROD

19
20
Fix	
  the	
  issue

21
Run	
  test	
  to	
  see	
  it’s	
  fixed

22
23
Save	
  your	
  test	
  as	
  .html

24
It’s	
  that	
  easy!

25
Automated	
  Tes'ng

26
PHPUnit	
  to	
  the	
  rescue

27
Export	
  to	
  PHPUnit

28
The	
  PHPUnit	
  TestCase
?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
Change	
  class	
  name
?php
class Example extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this-setBrowser(*chrome);
class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
$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
The	
  PHPUnit	
  TestCase
?php
class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this-setBrowser(*chrome);
$this-setBrowserUrl(http://www.theialive.com/);
}

!

}
?

public function testMyTestCase()
{
protected function setUp()
$this-open(/);
{
$this-click(link=login);
$this-waitForPageToLoad(30000);
$this-setBrowser(*iexplore);
$this-type(id=email, dragonbe+tek13@gmail.com);
$this-setBrowserUrl(http://www.theialive.com/);
$this-type(id=password, test1234);
$this-click(id=signin);
$this-setHost('192.168.56.101');
$this-waitForPageToLoad(30000);
$this-setPort(12666);
$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);
}

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);
public function testMarkTestAsDone()
$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
startSeleniumStandAlone.BAT
C:Program FilesJavajre7binjava.exe
-jar C:Jarselenium-server-standalone-2.28.0.jar
-port 12666

33
Now	
  run	
  your	
  tests

34
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
How	
  it	
  runs	
  on	
  the	
  node

36
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
Advantages
• 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	
  plaeorms	
  
• Con'nuous	
  Integra'on	
  possible
38
Next	
  Steps

39
Mul'	
  Browser	
  support

40
Base	
  TestCase
?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);
}

41
Base	
  TestCase
?php

! array (
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
!
'name' = 'Internet Explorer 8 on Windows 7',
class TestCase extends PHPUnit_Extensions_SeleniumTestCase
'browser' = '*iexplore',
{
//const TEST_HUB = '217.21.179.192';
const 'host'= = self::TEST_HUB,
TEST_HUB
'192.168.56.101';
const 'port' == self::TEST_PORT,
TEST_PORT
12666;
!
), USERNAME = 'dragonbe+tek13@gmail.com';
const
!

!
}

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
?php

!
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
!
class TestCase extends PHPUnit_Extensions_SeleniumTestCase
{ array (
//const TEST_HUB = '217.21.179.192';
const 'name'= = 'Firefox on Windows 7',
TEST_HUB
'192.168.56.101';
const TEST_PORT = 12666;
'browser' = '*firefox',
!
const 'host'= = self::TEST_HUB,
USERNAME
'dragonbe+tek13@gmail.com';
const PASSWORD = 'test1234';
const 'port''http://www.theialive.com';
BASURL =
= self::TEST_PORT,
! ),
public static $browsers = array (

!
}

);

array (
'name'
'host'
),
array (
'name'
'host'
),
array (
'name'
'host'
),

= 'Internet Explorer 8 on Windows 7', 'browser' = '*iexplore',
= self::TEST_HUB, 'port' = self::TEST_PORT,
= 'Firefox on Windows 7', 'browser' = '*firefox',
= self::TEST_HUB, 'port' = self::TEST_PORT,
= 'Google Chrome on Windows 7', 'browser' = '*googlechrome',
= self::TEST_HUB, 'port' = self::TEST_PORT,

protected function setUp()
{
$this-setBrowserUrl(self::BASURL);
}

43
Base	
  TestCase
?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;

! array (
const USERNAME = 'dragonbe+tek13@gmail.com';
const 'name'= = 'Google Chrome on Windows 7',
PASSWORD
'test1234';
const BASURL = 'http://www.theialive.com';
'browser' = '*googlechrome',
!
public static $browsers = array (
'host' = self::TEST_HUB,
array (
'port'== self::TEST_PORT, 7', 'browser' = '*iexplore',
'name'
'Internet Explorer 8 on Windows
), ), 'host' = self::TEST_HUB, 'port' = self::TEST_PORT,

!
}

);

array (
'name'
'host'
),
array (
'name'
'host'
),

= 'Firefox on Windows 7', 'browser' = '*firefox',
= self::TEST_HUB, 'port' = self::TEST_PORT,
= 'Google Chrome on Windows 7', 'browser' = '*googlechrome',
= self::TEST_HUB, 'port' = self::TEST_PORT,

protected function setUp()
{
$this-setBrowserUrl(self::BASURL);
}

44
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);
}
}

Require the TestCase
and extend it

45
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
• Procedure	
  
-­‐
-­‐
-­‐

centralized	
  server	
  (HUB)	
  
commands	
  clients	
  (nodes)	
  registered	
  
and	
  executes	
  the	
  tests	
  

-­‐
-­‐

allow	
  for	
  automa'on	
  
adding	
  clients	
  as	
  you	
  go

• Goal	
  

50
Selenium	
  Grid	
  Setup
Selenium Testing
Windows HUB launches
Selenium node clients
to execute tests

CI executes tests

Windows client
NODE

Linux client
NODE
CI Server

Windows
HUB
Windows Server collects
feedback from the Citrix
client nodes and reports
back to CI Server

Mac OS X client
NODE

Continuous User Acceptance Testing

51
Star'ng	
  the	
  server	
  [HUB]
C:Program FilesJavajre7binjava.exe
-jar C:Jarselenium-server-standalone-2.28.0.jar
-role hub
-port 12666

52
Star'ng	
  the	
  client	
  [NODE]
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

53
Mul'ple	
  nodes

54
Problem

55
Modify	
  Base	
  TestCase
?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);
}

56
More	
  informa'on

57
seleniumhq.org

58
phpunit.de
http://www.phpunit.de/manual/3.5/en/selenium.html

59
Credits
• 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
60
Contact
Michelangelo van Dam
Zend Certified Engineer	

!

email: michelangelo@in2it.be	

Contact us for	

Consultancy - Training - QA - Webdesign

61
https://joind.in/10018

62
Thank	
  you

63

More Related Content

What's hot

Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
Jace Ju
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards
Denis Ristic
 
What's new with PHP7
What's new with PHP7What's new with PHP7
What's new with PHP7
SWIFTotter Solutions
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
Damien Seguy
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
MoscowDjango
 
Django - Know Your Namespace: Middleware
Django - Know Your Namespace: MiddlewareDjango - Know Your Namespace: Middleware
Django - Know Your Namespace: Middleware
howiworkdaily
 
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
Michelangelo van Dam
 
OWASP Top 10 at International PHP Conference 2014 in Berlin
OWASP Top 10 at International PHP Conference 2014 in BerlinOWASP Top 10 at International PHP Conference 2014 in Berlin
OWASP Top 10 at International PHP Conference 2014 in Berlin
Tobias Zander
 
SQL Injection in PHP
SQL Injection in PHPSQL Injection in PHP
SQL Injection in PHP
Dave Ross
 
Top5 scalabilityissues
Top5 scalabilityissuesTop5 scalabilityissues
Top5 scalabilityissues
ColdFusionConference
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
Your code are my tests
Your code are my testsYour code are my tests
Your code are my tests
Michelangelo van Dam
 
WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...
WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...
WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...
GeeksLab Odessa
 
Unit testing
Unit testingUnit testing
Unit testing
davidahaskins
 
Fatc
FatcFatc
PHP Security
PHP SecurityPHP Security
PHP Security
Mindfire Solutions
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
Wim Godden
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
Michelangelo van Dam
 
Обзор фреймворка Twisted
Обзор фреймворка TwistedОбзор фреймворка Twisted
Обзор фреймворка Twisted
Maxim Kulsha
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 

What's hot (20)

Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards
 
What's new with PHP7
What's new with PHP7What's new with PHP7
What's new with PHP7
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Django - Know Your Namespace: Middleware
Django - Know Your Namespace: MiddlewareDjango - Know Your Namespace: Middleware
Django - Know Your Namespace: Middleware
 
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
 
OWASP Top 10 at International PHP Conference 2014 in Berlin
OWASP Top 10 at International PHP Conference 2014 in BerlinOWASP Top 10 at International PHP Conference 2014 in Berlin
OWASP Top 10 at International PHP Conference 2014 in Berlin
 
SQL Injection in PHP
SQL Injection in PHPSQL Injection in PHP
SQL Injection in PHP
 
Top5 scalabilityissues
Top5 scalabilityissuesTop5 scalabilityissues
Top5 scalabilityissues
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Your code are my tests
Your code are my testsYour code are my tests
Your code are my tests
 
WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...
WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...
WebCamp: Developer Day: Web Security: Cookies, Domains and CORS - Юрий Чайков...
 
Unit testing
Unit testingUnit testing
Unit testing
 
Fatc
FatcFatc
Fatc
 
PHP Security
PHP SecurityPHP Security
PHP Security
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
Обзор фреймворка Twisted
Обзор фреймворка TwistedОбзор фреймворка Twisted
Обзор фреймворка Twisted
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 

Viewers also liked

Policy and procedure
Policy and procedurePolicy and procedure
Policy and procedure
Abdullah831412
 
Sacudete
SacudeteSacudete
Sacudete
cpervar
 
In search for a good practice of finding information
In search for a good practice of finding informationIn search for a good practice of finding information
In search for a good practice of finding information
Kristian Norling
 
Bouwkennis - crowdfunding in de bouw
Bouwkennis -  crowdfunding in de bouwBouwkennis -  crowdfunding in de bouw
Bouwkennis - crowdfunding in de bouw
Ronald Kleverlaan
 
Meeting the Retirement Challenge
Meeting the Retirement ChallengeMeeting the Retirement Challenge
Meeting the Retirement Challenge
Steven Reta
 
Crowdfunding voor religieus erfgoed - kerken
Crowdfunding voor religieus erfgoed - kerkenCrowdfunding voor religieus erfgoed - kerken
Crowdfunding voor religieus erfgoed - kerken
Ronald Kleverlaan
 
Open data policy in Catalonia. New European judicial framework for opening ac...
Open data policy in Catalonia. New European judicial framework for opening ac...Open data policy in Catalonia. New European judicial framework for opening ac...
Open data policy in Catalonia. New European judicial framework for opening ac...
gencat .
 
Guia Hootsuite CAT
Guia Hootsuite CATGuia Hootsuite CAT
Guia Hootsuite CAT
gencat .
 

Viewers also liked (8)

Policy and procedure
Policy and procedurePolicy and procedure
Policy and procedure
 
Sacudete
SacudeteSacudete
Sacudete
 
In search for a good practice of finding information
In search for a good practice of finding informationIn search for a good practice of finding information
In search for a good practice of finding information
 
Bouwkennis - crowdfunding in de bouw
Bouwkennis -  crowdfunding in de bouwBouwkennis -  crowdfunding in de bouw
Bouwkennis - crowdfunding in de bouw
 
Meeting the Retirement Challenge
Meeting the Retirement ChallengeMeeting the Retirement Challenge
Meeting the Retirement Challenge
 
Crowdfunding voor religieus erfgoed - kerken
Crowdfunding voor religieus erfgoed - kerkenCrowdfunding voor religieus erfgoed - kerken
Crowdfunding voor religieus erfgoed - kerken
 
Open data policy in Catalonia. New European judicial framework for opening ac...
Open data policy in Catalonia. New European judicial framework for opening ac...Open data policy in Catalonia. New European judicial framework for opening ac...
Open data policy in Catalonia. New European judicial framework for opening ac...
 
Guia Hootsuite CAT
Guia Hootsuite CATGuia Hootsuite CAT
Guia Hootsuite CAT
 

Similar to UA testing with Selenium and PHPUnit - TrueNorthPHP 2013

Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
sitecrafting
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
Enterprise PHP Center
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023
Mark Niebergall
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
patter
 
Selenium RC Presentation 20110104
Selenium RC Presentation 20110104Selenium RC Presentation 20110104
Selenium RC Presentation 20110104
Michael Salvucci
 
Selenium rc presentation_20110104
Selenium rc presentation_20110104Selenium rc presentation_20110104
Selenium rc presentation_20110104
Michael Salvucci
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Selenium
SeleniumSelenium
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
markstory
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
Thanh Robi
 
Unit Testing from Setup to Deployment
Unit Testing from Setup to DeploymentUnit Testing from Setup to Deployment
Unit Testing from Setup to Deployment
Mark Niebergall
 
Browser testing with nightwatch.js - Drupal Europe
Browser testing with nightwatch.js - Drupal EuropeBrowser testing with nightwatch.js - Drupal Europe
Browser testing with nightwatch.js - Drupal Europe
Salvador Molina (Slv_)
 
2010 07-28-testing-zf-apps
2010 07-28-testing-zf-apps2010 07-28-testing-zf-apps
2010 07-28-testing-zf-apps
Venkata Ramana
 
Browser-Based testing using Selenium
Browser-Based testing using SeleniumBrowser-Based testing using Selenium
Browser-Based testing using Selenium
ret0
 
PHPUnit your bug exterminator
PHPUnit your bug exterminatorPHPUnit your bug exterminator
PHPUnit your bug exterminator
rjsmelo
 
Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022
Mark Niebergall
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
Eric Hogue
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo Web
Mikel Torres Ugarte
 

Similar to UA testing with Selenium and PHPUnit - TrueNorthPHP 2013 (20)

Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Selenium RC Presentation 20110104
Selenium RC Presentation 20110104Selenium RC Presentation 20110104
Selenium RC Presentation 20110104
 
Selenium rc presentation_20110104
Selenium rc presentation_20110104Selenium rc presentation_20110104
Selenium rc presentation_20110104
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Selenium
SeleniumSelenium
Selenium
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Unit Testing from Setup to Deployment
Unit Testing from Setup to DeploymentUnit Testing from Setup to Deployment
Unit Testing from Setup to Deployment
 
Browser testing with nightwatch.js - Drupal Europe
Browser testing with nightwatch.js - Drupal EuropeBrowser testing with nightwatch.js - Drupal Europe
Browser testing with nightwatch.js - Drupal Europe
 
2010 07-28-testing-zf-apps
2010 07-28-testing-zf-apps2010 07-28-testing-zf-apps
2010 07-28-testing-zf-apps
 
Browser-Based testing using Selenium
Browser-Based testing using SeleniumBrowser-Based testing using Selenium
Browser-Based testing using Selenium
 
PHPUnit your bug exterminator
PHPUnit your bug exterminatorPHPUnit your bug exterminator
PHPUnit your bug exterminator
 
Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo Web
 

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 default
Michelangelo 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 functions
Michelangelo van Dam
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
Michelangelo van Dam
 
DevOps or DevSecOps
DevOps or DevSecOpsDevOps or DevSecOps
DevOps or DevSecOps
Michelangelo van Dam
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
Michelangelo van Dam
 
Continuous deployment 2.0
Continuous deployment 2.0Continuous deployment 2.0
Continuous deployment 2.0
Michelangelo van Dam
 
Let your tests drive your code
Let your tests drive your codeLet your tests drive your code
Let your tests drive your code
Michelangelo 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 story
Michelangelo 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 advantage
Michelangelo van Dam
 
The road to php 7.1
The road to php 7.1The road to php 7.1
The road to php 7.1
Michelangelo van Dam
 
Open source for a successful business
Open source for a successful businessOpen source for a successful business
Open source for a successful business
Michelangelo 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 later
Michelangelo 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 minutes
Michelangelo 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 heaven
Michelangelo van Dam
 
Getting hands dirty with php7
Getting hands dirty with php7Getting hands dirty with php7
Getting hands dirty with php7
Michelangelo van Dam
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
Michelangelo van Dam
 
The Continuous PHP Pipeline
The Continuous PHP PipelineThe Continuous PHP Pipeline
The Continuous PHP Pipeline
Michelangelo 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 tests
Michelangelo 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 api
Michelangelo van Dam
 
200K+ reasons security is a must
200K+ reasons security is a must200K+ reasons security is a must
200K+ reasons security is a must
Michelangelo 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
 
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
 
200K+ reasons security is a must
200K+ reasons security is a must200K+ reasons security is a must
200K+ reasons security is a must
 

Recently uploaded

Semantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software DevelopmentSemantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software Development
Baishakhi Ray
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
Brian Pichman
 
July Patch Tuesday
July Patch TuesdayJuly Patch Tuesday
July Patch Tuesday
Ivanti
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
bhumivarma35300
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
maigasapphire
 
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
bellared2
 
Mastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for SuccessMastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for Success
David Wilson
 
Tailored CRM Software Development for Enhanced Customer Insights
Tailored CRM Software Development for Enhanced Customer InsightsTailored CRM Software Development for Enhanced Customer Insights
Tailored CRM Software Development for Enhanced Customer Insights
SynapseIndia
 
Integrating Kafka with MuleSoft 4 and usecase
Integrating Kafka with MuleSoft 4 and usecaseIntegrating Kafka with MuleSoft 4 and usecase
Integrating Kafka with MuleSoft 4 and usecase
shyamraj55
 
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
sunilverma7884
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
Matthias Neugebauer
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
aakash malhotra
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
SAI KAILASH R
 
(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf
(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf
(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf
Priyanka Aash
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
Adam Dunkels
 
Feature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptxFeature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptx
ssuser1915fe1
 
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Muhammad Ali
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
Safe Software
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
Shiv Technolabs
 
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
Priyanka Aash
 

Recently uploaded (20)

Semantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software DevelopmentSemantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software Development
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
 
July Patch Tuesday
July Patch TuesdayJuly Patch Tuesday
July Patch Tuesday
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
 
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
Russian Girls Call Navi Mumbai 🎈🔥9920725232 🔥💋🎈 Provide Best And Top Girl Ser...
 
Mastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for SuccessMastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for Success
 
Tailored CRM Software Development for Enhanced Customer Insights
Tailored CRM Software Development for Enhanced Customer InsightsTailored CRM Software Development for Enhanced Customer Insights
Tailored CRM Software Development for Enhanced Customer Insights
 
Integrating Kafka with MuleSoft 4 and usecase
Integrating Kafka with MuleSoft 4 and usecaseIntegrating Kafka with MuleSoft 4 and usecase
Integrating Kafka with MuleSoft 4 and usecase
 
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
 
(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf
(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf
(CISOPlatform Summit & SACON 2024) Gen AI & Deepfake In Overall Security.pdf
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
 
Feature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptxFeature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptx
 
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
 
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
 

UA testing with Selenium and PHPUnit - TrueNorthPHP 2013

  • 1. UA  Tes'ng  with Selenium  and  PHPUnit TrueNorthPHP  2013   Toronto,  Canada
  • 2. Michelangelo  van  Dam • PHP  Consultant   • President  PHPBenelux   • Conference  speaker 2
  • 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. DISCLAIMER SELENIUM TESTS ARE NOT A REPLACEMENT FOR REGULAR UNIT TESTING. THEY ONLY PROVIDE AN ADDITIONAL SET OF TESTS FOCUSED ON U S E R A C C E P TA N C E A N D U S E R EXPERIENCE TESTING. For more information about unit testing, please see my other material on www.slideshare.net and www.speakerdeck.com. Search for “dragonbe”! 5
  • 7. “Acceptance testing is a test conducted to determine if the requirements of a specification or contract are met.” ! -- source: wikipedia 7
  • 8. 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   -­‐ e.g.  buTons,  form  elements,  AJAX  controls,  … • Test  UI  elements  on  the  web  interface   9
  • 10. A  word  of  cau'on! • UA  tests  only  test  generated  output   -­‐ not  a  replacement  for  unit  tes'ng   -­‐ changes  to  the  DOM  might  lead  to  failing  UAT • UA  tests  are  heavily  depending  on  DOM   10
  • 12. Selenium  to  the  rescue 12
  • 14. Get  the  plugin  (demo) 14
  • 17. Pick  a  test  case 17
  • 19. Verify  this  issue  on  PROD 19
  • 20. 20
  • 22. Run  test  to  see  it’s  fixed 22
  • 23. 23
  • 24. Save  your  test  as  .html 24
  • 27. PHPUnit  to  the  rescue 27
  • 29. The  PHPUnit  TestCase ?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
  • 30. Change  class  name ?php class Example extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this-setBrowser(*chrome); class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase $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
  • 31. The  PHPUnit  TestCase ?php class MarkTaskDoneTest extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this-setBrowser(*chrome); $this-setBrowserUrl(http://www.theialive.com/); } ! } ? public function testMyTestCase() { protected function setUp() $this-open(/); { $this-click(link=login); $this-waitForPageToLoad(30000); $this-setBrowser(*iexplore); $this-type(id=email, dragonbe+tek13@gmail.com); $this-setBrowserUrl(http://www.theialive.com/); $this-type(id=password, test1234); $this-click(id=signin); $this-setHost('192.168.56.101'); $this-waitForPageToLoad(30000); $this-setPort(12666); $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); } 31
  • 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); public function testMarkTestAsDone() $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
  • 34. Now  run  your  tests 34
  • 36. How  it  runs  on  the  node 36
  • 38. Advantages • 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  plaeorms   • Con'nuous  Integra'on  possible 38
  • 41. Base  TestCase ?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); } 41
  • 42. Base  TestCase ?php ! array ( require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; ! 'name' = 'Internet Explorer 8 on Windows 7', class TestCase extends PHPUnit_Extensions_SeleniumTestCase 'browser' = '*iexplore', { //const TEST_HUB = '217.21.179.192'; const 'host'= = self::TEST_HUB, TEST_HUB '192.168.56.101'; const 'port' == self::TEST_PORT, TEST_PORT 12666; ! ), USERNAME = 'dragonbe+tek13@gmail.com'; const ! ! } 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
  • 43. Base  TestCase ?php ! require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; ! class TestCase extends PHPUnit_Extensions_SeleniumTestCase { array ( //const TEST_HUB = '217.21.179.192'; const 'name'= = 'Firefox on Windows 7', TEST_HUB '192.168.56.101'; const TEST_PORT = 12666; 'browser' = '*firefox', ! const 'host'= = self::TEST_HUB, USERNAME 'dragonbe+tek13@gmail.com'; const PASSWORD = 'test1234'; const 'port''http://www.theialive.com'; BASURL = = self::TEST_PORT, ! ), public static $browsers = array ( ! } ); array ( 'name' 'host' ), array ( 'name' 'host' ), array ( 'name' 'host' ), = 'Internet Explorer 8 on Windows 7', 'browser' = '*iexplore', = self::TEST_HUB, 'port' = self::TEST_PORT, = 'Firefox on Windows 7', 'browser' = '*firefox', = self::TEST_HUB, 'port' = self::TEST_PORT, = 'Google Chrome on Windows 7', 'browser' = '*googlechrome', = self::TEST_HUB, 'port' = self::TEST_PORT, protected function setUp() { $this-setBrowserUrl(self::BASURL); } 43
  • 44. Base  TestCase ?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; ! array ( const USERNAME = 'dragonbe+tek13@gmail.com'; const 'name'= = 'Google Chrome on Windows 7', PASSWORD 'test1234'; const BASURL = 'http://www.theialive.com'; 'browser' = '*googlechrome', ! public static $browsers = array ( 'host' = self::TEST_HUB, array ( 'port'== self::TEST_PORT, 7', 'browser' = '*iexplore', 'name' 'Internet Explorer 8 on Windows ), ), 'host' = self::TEST_HUB, 'port' = self::TEST_PORT, ! } ); array ( 'name' 'host' ), array ( 'name' 'host' ), = 'Firefox on Windows 7', 'browser' = '*firefox', = self::TEST_HUB, 'port' = self::TEST_PORT, = 'Google Chrome on Windows 7', 'browser' = '*googlechrome', = self::TEST_HUB, 'port' = self::TEST_PORT, protected function setUp() { $this-setBrowserUrl(self::BASURL); } 44
  • 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); } } Require the TestCase and extend it 45
  • 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 • Procedure   -­‐ -­‐ -­‐ centralized  server  (HUB)   commands  clients  (nodes)  registered   and  executes  the  tests   -­‐ -­‐ allow  for  automa'on   adding  clients  as  you  go • Goal   50
  • 51. Selenium  Grid  Setup Selenium Testing Windows HUB launches Selenium node clients to execute tests CI executes tests Windows client NODE Linux client NODE CI Server Windows HUB Windows Server collects feedback from the Citrix client nodes and reports back to CI Server Mac OS X client NODE Continuous User Acceptance Testing 51
  • 52. Star'ng  the  server  [HUB] C:Program FilesJavajre7binjava.exe -jar C:Jarselenium-server-standalone-2.28.0.jar -role hub -port 12666 52
  • 53. Star'ng  the  client  [NODE] 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 53
  • 56. Modify  Base  TestCase ?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); } 56
  • 60. Credits • 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 60
  • 61. Contact Michelangelo van Dam Zend Certified Engineer ! email: michelangelo@in2it.be Contact us for Consultancy - Training - QA - Webdesign 61