SlideShare a Scribd company logo
REFACTORING USING CODECEPTION
$I->CANSEE(‘JEROEN’, ‘#VANDIJK’)
$I->USETWITTER(‘@JRVANDIJK’)
$I->AM(‘PHPBNL’, ‘.BOARD-MEMBER’)
$I->WORK(‘#ENRISE’)
Refactoring using Codeception
NETHERLANDS 
UNITED 
KINGDOM 
BELGIUM 
GERMANY 
AMSTERDAM
NETHERLANDS 
UNITED 
KINGDOM 
BELGIUM 
GERMANY 
AMSTERDAM 
NOT AMSTERDAM
NETHERLANDS 
UNITED 
KINGDOM 
BELGIUM 
GERMANY 
AMERSFOORT
GRAIN WAREHOUSE
REFACTORED
THIS TALK IS NOT…
THIS TALK IS NOT… 
REFACTORING 
DEPENDENCY INJECTION, DECOUPLING, ENCAPSULATION, TESTABLE CODE
WHAT IS CODECEPTION? 
A SIMPLE BDD STYLE TESTING FRAMEWORK 
WHICH IS EASY TO READ, WRITE AND DEBUG
YOU WRITE IN YOUR FAVORITE EDITOR
COMPOSER INSTALL CODECEPTION/CODECEPTION 
VENDOR/BIN/CODECEPT BOOTSTRAP
ACCEPTANCE.SUITE.YML 
class_name: AcceptanceTester 
modules: 
enabled: 
- PhpBrowser 
- AcceptanceHelper 
config: 
PhpBrowser: 
url: 'http://www.zendcon.com/'
PAGE USED FOR TESTING
CODECEPT GENERATE:CEST ACCEPTANCE HOME 
public function seeIfNameExists(AcceptanceTester $I) 
{ 
$I->wantTo('see if conference name exists'); 
$I->amOnPage(‘/'); 
$I->click(‘#rt-logo‘); 
$I->see('zendcon'); 
}
STEPS
CODECEPT GENERATE:STEPOBJECT ACCEPTANCE <NAME> 
GENERATED FILE EXTENDS ACCEPTANCETESTER CLASS
REUSE CODE FOR DIFFERENT TESTS 
class CompareSteps extends AcceptanceTester { 
public function seeIfNameExists() 
{ 
$I = $this; 
$I->amOnPage('/'); 
$I->see('zendcon'); 
} 
} 
class MenuCest { 
public function seeIfNameExistsViaCCStep(CompareSteps $I) 
{ 
$I->seeIfNameExists(); 
} 
}
PAGE OBJECTS
CODECEPT GENERATE:PAGEOBJECT ACCEPTANCE <NAME> 
GENERATED FILE IS JUST A CONTAINER
PAGE OBJECT CONTAINER 
class HomePage 
{ 
public static $URL = '/'; 
… // removed code for slide layout purposes 
public static function of(AcceptanceTester $I) 
{ 
return new static($I); 
} 
public function see($value) 
{ 
$I = $this->acceptanceTester; 
$I->amOnPage(self::$URL); 
$I->see($value); 
} 
}
USE THE OBJECT IN A TEST 
public function seeIfNameExistsViaPageObject() 
{ 
HomePage::of($this)->see('zendcon'); 
}
VERSION COMPARISON
MASTER !== RELEASE/NEXTGEN 
FROM A TECHNICAL PERSPECTIVE
MASTER === RELEASE/NEXTGEN 
FROM A FUNCTIONAL PERSPECTIVE
ATTENTION PLEASE 
LOST OF CODE COMING UP…
OVERRIDE DEFAULT CRAWLER 
public function getHtmlFromContent(InnerBrowser $innerBrowser, $css) 
{ 
$crawler = $this->getCrawler($innerBrowser); 
$selector = CssSelector::toXPath($css); 
$value = $crawler->filterXPath($selector); 
return $value->html(); 
} 
protected function getCrawler(InnerBrowser $innerBrowser) 
{ 
$reflection = new ReflectionClass(get_class($innerBrowser)); 
$property = $reflection->getProperty('crawler'); 
$property->setAccessible(true); 
return $property->getValue($innerBrowser); 
}
CREATE SECOND PHPBROWSER INSTANCE 
protected function getPhpBrowserByPage($page) { 
$phpBrowser = $this->getAlternatePhpBrowser(); 
$phpBrowser->amOnPage($page); 
return $phpBrowser; 
} 
protected function getAlternatePhpBrowser() { 
$config = Configuration::config(); 
$suite = Configuration::suiteSettings('acceptance', $config); 
$options = $suite['modules']['config']['PhpBrowser']; 
$options['url'] = $options['alternate-url']; 
$phpBrowser = new PhpBrowser($options)->_initialize(); 
$this->setProxyInGuzzle($phpBrowser->guzzle); 
return $phpBrowser; 
}
GET HTML OF BOTH VERSIONS 
public function getHtml($page, $path) 
{ 
$I = $this; 
$I->amOnPage($page); 
return $this->getHtmlFromContent( 
$I->fetchModule('PhpBrowser'), $path); 
} 
public function getAlternateHtml($page, $path) 
{ 
return $this->getHtmlFromContent( 
$this->getPhpBrowserByPage($page), $path); 
}
ADDING ALTERNATE URL 
class_name: AcceptanceTester 
modules: 
enabled: 
- PhpBrowser 
- AcceptanceHelper 
config: 
PhpBrowser: 
url: 'http://www.zendcon.com/' 
alternate-url: 'http://zendcon.com'
COMPARING 2 VERSIONS IN 1 RUN 
public function seeSameOnVersions($page, $path, $altPath, $message) 
{ 
$I = $this; 
list($left, $right) = $this->getContentFromVersions( 
$page, $path, $altPath); 
$I->seeEquals($left, $right, $message); 
} 
public function getContentFromVersions($page, $path, $altPath) 
{ 
return array( 
$this->getHtml($page, $path), 
$this->getAlternateHtml($page, $altPath) 
); 
}
TEST PAGE HEADER 
public function seeIfPageHeaderIsIdentical(CompareSteps $I) 
{ 
$I->seeSameOnVersions( 
HomePage::$URL, 
'h2', 
'h2', 
'Homepage header not identical' 
); 
}
TEST SIGNUP FORM 
public function seeIfFormActionIsIdentical(CompareSteps $I) 
{ 
$I->seeSameOnVersions( 
HomePage::$URL, 
'.rsformbox1', 
'.rsformbox1', 
'Homepage signup form not identical' 
); 
}
TEST SIGNUP FORM 
public function seeIfFormActionIsIdentical(CompareSteps $I) 
{ 
$I->seeSameOnVersions( 
HomePage::$URL, 
'.rsformbox1', 
'.rsformbox1', 
'Homepage signup form not identical' 
); 
} 
<div class="rsformbox1 title3"> 
- <form method=“post" id="userForm" action="http://www.zendcon.com/"> 
+ <form method="post" id="userForm" action="http://zendcon.com/">
RUNNING THE TESTS!
EXAMPLES?
USER SPECIFIC SETTINGS
CODECEPTION.YML 
CODECEPTION.DIST.YML 
VS 
CODECEPTION.YML.DIST
TESTING AN API
class_name: ApiTester 
modules: 
enabled: 
- ApiHelper 
- PhpBrowser 
- REST 
config: 
PhpBrowser: 
url: https://api.github.com 
REST: 
url: https://api.github.com
public function testGetGists(ApiTester $I) { 
$I->wantTo('see if we can get the gists listing'); 
$I->haveHttpHeader('Accept', 'application/vnd.github.beta+json'); 
$I->sendGet('/users/weierophinney/gists'); 
$I->seeResponseCodeIs(200); 
$I->seeResponseIsJson(); 
} 
public function testGetGist(ApiTester $I) { 
$I->wantTo('see if we can get a gist'); 
$I->haveHttpHeader('Accept', 'application/vnd.github.beta+json'); 
$I->sendGet('/gists/2c47c9d59f4a5214f0c3'); 
$I->seeResponseCodeIs(200); 
$I->seeResponseIsJson(); 
}
ENVIRONMENTS
/** 
* @env beta 
*/ 
public function testGetOldVersionGist(ApiTester $I) { 
$I->wantTo('see if we can get a gist'); 
$I->haveHttpHeader('Accept', $I->getAcceptHeader()); 
$I->sendGet('/gists/2c47c9d59f4a5214f0c3'); 
$I->seeResponseCodeIs(200); 
$I->seeResponseIsJson(); 
$I->seeResponseContainsJson( 
array('user' => array('login' => ‘weierophinney') 
)); 
}
SPOT THE DIFFERENCE 
/** 
* @env version3 
*/ 
public function testGetOldVersionGist(ApiTester $I) { 
$I->wantTo('see if we can get a gist'); 
$I->haveHttpHeader('Accept', $I->getAcceptHeader()); 
$I->sendGet('/gists/2c47c9d59f4a5214f0c3'); 
$I->seeResponseCodeIs(200); 
$I->seeResponseIsJson(); 
$I->seeResponseContainsJson( 
array('owner' => array('login' => ‘weierophinney') 
)); 
}
SUITE CONFIG ADDITIONS 
env: 
beta: 
config: 
data: 
accept: application/vnd.github.beta+json 
version3: 
config: 
data: 
accept: application/vnd.github.v3+json
CODECEPT RUN API —ENV BETA —ENV VERSION3 
TESTING 2 API VERSION IN 1 RUN
EXAMPLES?
READY TO DIG DEEPER? 
USING MODULES
CODECEPT GENERATE:SUITE 
USE YOUR IMAGINATION
FILESYSTEM MODULE 
class MigrateHelper extends CodeceptionModule { 
public function seeIfLineExistsInFile($file, $line) 
{ 
$filesystem = $this->getModule('Filesystem'); 
$filesystem->seeFileFound($file); 
$filesystem->seeInThisFile($line); 
} 
} 
class HostCest { 
public function testIfHostsFileIsConfigured(MigrateTester $I) 
{ 
$I->seeIfLineExistsInFile('/etc/hosts', '127.0.0.1'); 
} 
}
CLI MODULE 
class MigrateHelper extends CodeceptionModule { 
public function seeIfPortIsReachable($host, $port) 
{ 
$cli = $this->getModule('Cli'); 
$cli->runShellCommand('nmap '.$host.' -Pn -p '.$port); 
$cli->seeInShellOutput($port.'/tcp open'); 
} 
} 
class HostCest { 
public function testIfPortReachable(MigrateTester $I) 
{ 
$I->seeIfPortIsReachable('www.zendcon.com', 80); 
} 
}
CLI MODULE 
class MigrateHelper extends CodeceptionModule { 
public function seeAddressIsMatchingIp($address, $ip) 
{ 
$cli = $this->getModule('Cli'); 
$cli->runShellCommand('host '.$address); 
$cli->seeInShellOutput($address . ' has address '.$ip); 
} 
} 
class HostCest { 
public function testIfDnsCanBeResolved(MigrateTester $I) 
{ 
$I->seeAddressIsMatchingIp('zendcon.com', '50.56.0.87'); 
} 
}
FTP MODULE 
class MigrateHelper extends CodeceptionModule { 
public function seeContentsInRemoteFile($file, $line) 
{ 
$server = $this->getModule('FTP'); 
$server->seeFileFound(basename($file), dirname($file)); 
$server->openFile($file); 
$server->seeInThisFile($line); 
} 
} 
class HostCest { 
public function testIfRemoteFileHasContents(MigrateTester $I) 
{ 
$I->seeContentsInRemoteFile('/etc/hosts', '127.0.0.1'); 
} 
}
CAVEAT! 
FTP MODULE SIGNS IN BEFORE EVERY TEST
RUNNING THE TESTS!
GITHUB.COM/JVANDIJK/ZC14-CODECEPTION 
JOIND.IN/11997

More Related Content

PPTX
Crafting beautiful software
KEY
Symfony2 Building on Alpha / Beta technology
PDF
PHPSpec - the only Design Tool you need - 4Developers
PPTX
Hacking Your Way To Better Security - Dutch PHP Conference 2016
PDF
November Camp - Spec BDD with PHPSpec 2
PDF
PhpSpec 2.0 ilustrated by examples
PDF
You code sucks, let's fix it
PDF
Mocking Demystified
Crafting beautiful software
Symfony2 Building on Alpha / Beta technology
PHPSpec - the only Design Tool you need - 4Developers
Hacking Your Way To Better Security - Dutch PHP Conference 2016
November Camp - Spec BDD with PHPSpec 2
PhpSpec 2.0 ilustrated by examples
You code sucks, let's fix it
Mocking Demystified

What's hot (20)

PDF
Forget about Index.php and build you applications around HTTP - PHPers Cracow
KEY
Object Calisthenics Applied to PHP
PDF
The IoC Hydra - Dutch PHP Conference 2016
PDF
Learning Perl 6 (NPW 2007)
KEY
Unit testing with zend framework PHPBenelux
PDF
PHP for Adults: Clean Code and Object Calisthenics
PDF
Unit testing with zend framework tek11
PDF
Forget about index.php and build you applications around HTTP!
PDF
Design Patterns avec PHP 5.3, Symfony et Pimple
PDF
Silex meets SOAP & REST
DOCX
logic321
PDF
Learning Perl 6
PDF
Database Design Patterns
PDF
Business Rules with Brick
PDF
Data Validation models
PDF
Symfony2 - extending the console component
PDF
The IoC Hydra
PDF
The History of PHPersistence
PDF
Your code sucks, let's fix it
PDF
Storytelling By Numbers
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Object Calisthenics Applied to PHP
The IoC Hydra - Dutch PHP Conference 2016
Learning Perl 6 (NPW 2007)
Unit testing with zend framework PHPBenelux
PHP for Adults: Clean Code and Object Calisthenics
Unit testing with zend framework tek11
Forget about index.php and build you applications around HTTP!
Design Patterns avec PHP 5.3, Symfony et Pimple
Silex meets SOAP & REST
logic321
Learning Perl 6
Database Design Patterns
Business Rules with Brick
Data Validation models
Symfony2 - extending the console component
The IoC Hydra
The History of PHPersistence
Your code sucks, let's fix it
Storytelling By Numbers
Ad

Viewers also liked (6)

PDF
The Enterprise Wor/d/thy/Press
PDF
The Enterprise Wor/d/thy/Press
PDF
WordPress REST API hacking
PDF
TDD with PhpSpec
PDF
WordPress REST API hacking
PDF
Faire la conception en équipe sans architecte, non mais allô quoi ?
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
WordPress REST API hacking
TDD with PhpSpec
WordPress REST API hacking
Faire la conception en équipe sans architecte, non mais allô quoi ?
Ad

Similar to Refactoring using Codeception (20)

PDF
Codeception presentation
PDF
Acceptance testing in php with Codeception - Techmeetup Edinburgh
PPTX
Codeception
PDF
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
PDF
Testing TYPO3 Applications
PDF
Testing with Codeception (Webelement #30)
PDF
Testing mit Codeception: Full-stack testing PHP framework
PDF
Mykhailo Bodnarchuk "The history of the Codeception project"
KEY
Workshop unittesting
PDF
Unit testing after Zend Framework 1.8
PDF
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
PDF
Quality Assurance for PHP projects - ZendCon 2012
KEY
Workshop quality assurance for php projects tek12
PDF
Better Testing With PHP Unit
PDF
Testing with Codeception
PDF
Living With Legacy Code
PPTX
Code ceptioninstallation
PDF
PhpUnit - The most unknown Parts
PDF
Debugging: Rules And Tools - PHPTek 11 Version
PDF
Nashville Symfony Functional Testing
Codeception presentation
Acceptance testing in php with Codeception - Techmeetup Edinburgh
Codeception
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Testing TYPO3 Applications
Testing with Codeception (Webelement #30)
Testing mit Codeception: Full-stack testing PHP framework
Mykhailo Bodnarchuk "The history of the Codeception project"
Workshop unittesting
Unit testing after Zend Framework 1.8
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Quality Assurance for PHP projects - ZendCon 2012
Workshop quality assurance for php projects tek12
Better Testing With PHP Unit
Testing with Codeception
Living With Legacy Code
Code ceptioninstallation
PhpUnit - The most unknown Parts
Debugging: Rules And Tools - PHPTek 11 Version
Nashville Symfony Functional Testing

More from Jeroen van Dijk (12)

PDF
Beacons in Appcelerator Titanium
PDF
Teaming up WordPress API with Backbone.js in Titanium
PDF
Teaming up WordPress API with Backbone.js in Titanium
PDF
An app on the shoulders of giants
PDF
Zend Server: Not just a PHP stack
PDF
Liking Relevance - PHP North East 2014
PDF
To SQL or No(t)SQL - PHPNW12
PDF
To SQL or No(t)SQL - PFCongres 2012
PDF
Socializing a world of travel
PDF
Varnish, the high performance valhalla?
PPTX
Varnish, the high performance valhalla?
PPTX
Edge Side Includes in Zend Framework without Varnish
Beacons in Appcelerator Titanium
Teaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in Titanium
An app on the shoulders of giants
Zend Server: Not just a PHP stack
Liking Relevance - PHP North East 2014
To SQL or No(t)SQL - PHPNW12
To SQL or No(t)SQL - PFCongres 2012
Socializing a world of travel
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?
Edge Side Includes in Zend Framework without Varnish

Recently uploaded (20)

PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
MYSQL Presentation for SQL database connectivity
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Cloud computing and distributed systems.
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Big Data Technologies - Introduction.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
Review of recent advances in non-invasive hemoglobin estimation
Chapter 3 Spatial Domain Image Processing.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Advanced methodologies resolving dimensionality complications for autism neur...
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
MYSQL Presentation for SQL database connectivity
The AUB Centre for AI in Media Proposal.docx
Machine learning based COVID-19 study performance prediction
Cloud computing and distributed systems.
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
“AI and Expert System Decision Support & Business Intelligence Systems”
NewMind AI Monthly Chronicles - July 2025
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
NewMind AI Weekly Chronicles - August'25 Week I
Building Integrated photovoltaic BIPV_UPV.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Big Data Technologies - Introduction.pptx
Network Security Unit 5.pdf for BCA BBA.

Refactoring using Codeception

  • 7. NETHERLANDS UNITED KINGDOM BELGIUM GERMANY AMSTERDAM
  • 8. NETHERLANDS UNITED KINGDOM BELGIUM GERMANY AMSTERDAM NOT AMSTERDAM
  • 9. NETHERLANDS UNITED KINGDOM BELGIUM GERMANY AMERSFOORT
  • 12. THIS TALK IS NOT…
  • 13. THIS TALK IS NOT… REFACTORING DEPENDENCY INJECTION, DECOUPLING, ENCAPSULATION, TESTABLE CODE
  • 14. WHAT IS CODECEPTION? A SIMPLE BDD STYLE TESTING FRAMEWORK WHICH IS EASY TO READ, WRITE AND DEBUG
  • 15. YOU WRITE IN YOUR FAVORITE EDITOR
  • 16. COMPOSER INSTALL CODECEPTION/CODECEPTION VENDOR/BIN/CODECEPT BOOTSTRAP
  • 17. ACCEPTANCE.SUITE.YML class_name: AcceptanceTester modules: enabled: - PhpBrowser - AcceptanceHelper config: PhpBrowser: url: 'http://www.zendcon.com/'
  • 18. PAGE USED FOR TESTING
  • 19. CODECEPT GENERATE:CEST ACCEPTANCE HOME public function seeIfNameExists(AcceptanceTester $I) { $I->wantTo('see if conference name exists'); $I->amOnPage(‘/'); $I->click(‘#rt-logo‘); $I->see('zendcon'); }
  • 20. STEPS
  • 21. CODECEPT GENERATE:STEPOBJECT ACCEPTANCE <NAME> GENERATED FILE EXTENDS ACCEPTANCETESTER CLASS
  • 22. REUSE CODE FOR DIFFERENT TESTS class CompareSteps extends AcceptanceTester { public function seeIfNameExists() { $I = $this; $I->amOnPage('/'); $I->see('zendcon'); } } class MenuCest { public function seeIfNameExistsViaCCStep(CompareSteps $I) { $I->seeIfNameExists(); } }
  • 24. CODECEPT GENERATE:PAGEOBJECT ACCEPTANCE <NAME> GENERATED FILE IS JUST A CONTAINER
  • 25. PAGE OBJECT CONTAINER class HomePage { public static $URL = '/'; … // removed code for slide layout purposes public static function of(AcceptanceTester $I) { return new static($I); } public function see($value) { $I = $this->acceptanceTester; $I->amOnPage(self::$URL); $I->see($value); } }
  • 26. USE THE OBJECT IN A TEST public function seeIfNameExistsViaPageObject() { HomePage::of($this)->see('zendcon'); }
  • 28. MASTER !== RELEASE/NEXTGEN FROM A TECHNICAL PERSPECTIVE
  • 29. MASTER === RELEASE/NEXTGEN FROM A FUNCTIONAL PERSPECTIVE
  • 30. ATTENTION PLEASE LOST OF CODE COMING UP…
  • 31. OVERRIDE DEFAULT CRAWLER public function getHtmlFromContent(InnerBrowser $innerBrowser, $css) { $crawler = $this->getCrawler($innerBrowser); $selector = CssSelector::toXPath($css); $value = $crawler->filterXPath($selector); return $value->html(); } protected function getCrawler(InnerBrowser $innerBrowser) { $reflection = new ReflectionClass(get_class($innerBrowser)); $property = $reflection->getProperty('crawler'); $property->setAccessible(true); return $property->getValue($innerBrowser); }
  • 32. CREATE SECOND PHPBROWSER INSTANCE protected function getPhpBrowserByPage($page) { $phpBrowser = $this->getAlternatePhpBrowser(); $phpBrowser->amOnPage($page); return $phpBrowser; } protected function getAlternatePhpBrowser() { $config = Configuration::config(); $suite = Configuration::suiteSettings('acceptance', $config); $options = $suite['modules']['config']['PhpBrowser']; $options['url'] = $options['alternate-url']; $phpBrowser = new PhpBrowser($options)->_initialize(); $this->setProxyInGuzzle($phpBrowser->guzzle); return $phpBrowser; }
  • 33. GET HTML OF BOTH VERSIONS public function getHtml($page, $path) { $I = $this; $I->amOnPage($page); return $this->getHtmlFromContent( $I->fetchModule('PhpBrowser'), $path); } public function getAlternateHtml($page, $path) { return $this->getHtmlFromContent( $this->getPhpBrowserByPage($page), $path); }
  • 34. ADDING ALTERNATE URL class_name: AcceptanceTester modules: enabled: - PhpBrowser - AcceptanceHelper config: PhpBrowser: url: 'http://www.zendcon.com/' alternate-url: 'http://zendcon.com'
  • 35. COMPARING 2 VERSIONS IN 1 RUN public function seeSameOnVersions($page, $path, $altPath, $message) { $I = $this; list($left, $right) = $this->getContentFromVersions( $page, $path, $altPath); $I->seeEquals($left, $right, $message); } public function getContentFromVersions($page, $path, $altPath) { return array( $this->getHtml($page, $path), $this->getAlternateHtml($page, $altPath) ); }
  • 36. TEST PAGE HEADER public function seeIfPageHeaderIsIdentical(CompareSteps $I) { $I->seeSameOnVersions( HomePage::$URL, 'h2', 'h2', 'Homepage header not identical' ); }
  • 37. TEST SIGNUP FORM public function seeIfFormActionIsIdentical(CompareSteps $I) { $I->seeSameOnVersions( HomePage::$URL, '.rsformbox1', '.rsformbox1', 'Homepage signup form not identical' ); }
  • 38. TEST SIGNUP FORM public function seeIfFormActionIsIdentical(CompareSteps $I) { $I->seeSameOnVersions( HomePage::$URL, '.rsformbox1', '.rsformbox1', 'Homepage signup form not identical' ); } <div class="rsformbox1 title3"> - <form method=“post" id="userForm" action="http://www.zendcon.com/"> + <form method="post" id="userForm" action="http://zendcon.com/">
  • 44. class_name: ApiTester modules: enabled: - ApiHelper - PhpBrowser - REST config: PhpBrowser: url: https://api.github.com REST: url: https://api.github.com
  • 45. public function testGetGists(ApiTester $I) { $I->wantTo('see if we can get the gists listing'); $I->haveHttpHeader('Accept', 'application/vnd.github.beta+json'); $I->sendGet('/users/weierophinney/gists'); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); } public function testGetGist(ApiTester $I) { $I->wantTo('see if we can get a gist'); $I->haveHttpHeader('Accept', 'application/vnd.github.beta+json'); $I->sendGet('/gists/2c47c9d59f4a5214f0c3'); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); }
  • 47. /** * @env beta */ public function testGetOldVersionGist(ApiTester $I) { $I->wantTo('see if we can get a gist'); $I->haveHttpHeader('Accept', $I->getAcceptHeader()); $I->sendGet('/gists/2c47c9d59f4a5214f0c3'); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContainsJson( array('user' => array('login' => ‘weierophinney') )); }
  • 48. SPOT THE DIFFERENCE /** * @env version3 */ public function testGetOldVersionGist(ApiTester $I) { $I->wantTo('see if we can get a gist'); $I->haveHttpHeader('Accept', $I->getAcceptHeader()); $I->sendGet('/gists/2c47c9d59f4a5214f0c3'); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContainsJson( array('owner' => array('login' => ‘weierophinney') )); }
  • 49. SUITE CONFIG ADDITIONS env: beta: config: data: accept: application/vnd.github.beta+json version3: config: data: accept: application/vnd.github.v3+json
  • 50. CODECEPT RUN API —ENV BETA —ENV VERSION3 TESTING 2 API VERSION IN 1 RUN
  • 52. READY TO DIG DEEPER? USING MODULES
  • 53. CODECEPT GENERATE:SUITE USE YOUR IMAGINATION
  • 54. FILESYSTEM MODULE class MigrateHelper extends CodeceptionModule { public function seeIfLineExistsInFile($file, $line) { $filesystem = $this->getModule('Filesystem'); $filesystem->seeFileFound($file); $filesystem->seeInThisFile($line); } } class HostCest { public function testIfHostsFileIsConfigured(MigrateTester $I) { $I->seeIfLineExistsInFile('/etc/hosts', '127.0.0.1'); } }
  • 55. CLI MODULE class MigrateHelper extends CodeceptionModule { public function seeIfPortIsReachable($host, $port) { $cli = $this->getModule('Cli'); $cli->runShellCommand('nmap '.$host.' -Pn -p '.$port); $cli->seeInShellOutput($port.'/tcp open'); } } class HostCest { public function testIfPortReachable(MigrateTester $I) { $I->seeIfPortIsReachable('www.zendcon.com', 80); } }
  • 56. CLI MODULE class MigrateHelper extends CodeceptionModule { public function seeAddressIsMatchingIp($address, $ip) { $cli = $this->getModule('Cli'); $cli->runShellCommand('host '.$address); $cli->seeInShellOutput($address . ' has address '.$ip); } } class HostCest { public function testIfDnsCanBeResolved(MigrateTester $I) { $I->seeAddressIsMatchingIp('zendcon.com', '50.56.0.87'); } }
  • 57. FTP MODULE class MigrateHelper extends CodeceptionModule { public function seeContentsInRemoteFile($file, $line) { $server = $this->getModule('FTP'); $server->seeFileFound(basename($file), dirname($file)); $server->openFile($file); $server->seeInThisFile($line); } } class HostCest { public function testIfRemoteFileHasContents(MigrateTester $I) { $I->seeContentsInRemoteFile('/etc/hosts', '127.0.0.1'); } }
  • 58. CAVEAT! FTP MODULE SIGNS IN BEFORE EVERY TEST