SlideShare une entreprise Scribd logo
1  sur  60
Télécharger pour lire hors ligne
REFACTORING USING CODECEPTION
$I->CANSEE(‘JEROEN’, ‘#VANDIJK’)
$I->USETWITTER(‘@JRVANDIJK’)
$I->AM(‘PHPBNL’, ‘.BOARD-MEMBER’)
$I->WORK(‘#ENRISE’)
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

Contenu connexe

Tendances

Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowKacper Gunia
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)brian d foy
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsGuilherme Blanco
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Kacper Gunia
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6 brian d foy
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Business Rules with Brick
Business Rules with BrickBusiness Rules with Brick
Business Rules with Brickbrian d foy
 
Symfony2 - extending the console component
Symfony2 - extending the console componentSymfony2 - extending the console component
Symfony2 - extending the console componentHugo Hamon
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Storytelling By Numbers
Storytelling By NumbersStorytelling By Numbers
Storytelling By NumbersMichael King
 

Tendances (20)

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

En vedette

The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Faire la conception en équipe sans architecte, non mais allô quoi ?
Faire la conception en équipe sans architecte, non mais allô quoi ?Faire la conception en équipe sans architecte, non mais allô quoi ?
Faire la conception en équipe sans architecte, non mais allô quoi ?Ly-Jia Goldstein
 

En vedette (6)

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

Similaire à Refactoring using Codeception

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.8Michelangelo van Dam
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Jakub Zalas
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 

Similaire à Refactoring using Codeception (20)

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
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 

Plus de Jeroen van Dijk

Beacons in Appcelerator Titanium
Beacons in Appcelerator TitaniumBeacons in Appcelerator Titanium
Beacons in Appcelerator TitaniumJeroen van Dijk
 
Teaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumTeaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumJeroen van Dijk
 
Teaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumTeaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumJeroen van Dijk
 
An app on the shoulders of giants
An app on the shoulders of giantsAn app on the shoulders of giants
An app on the shoulders of giantsJeroen van Dijk
 
Zend Server: Not just a PHP stack
Zend Server: Not just a PHP stackZend Server: Not just a PHP stack
Zend Server: Not just a PHP stackJeroen van Dijk
 
Liking Relevance - PHP North East 2014
Liking Relevance - PHP North East 2014Liking Relevance - PHP North East 2014
Liking Relevance - PHP North East 2014Jeroen van Dijk
 
To SQL or No(t)SQL - PHPNW12
To SQL or No(t)SQL - PHPNW12To SQL or No(t)SQL - PHPNW12
To SQL or No(t)SQL - PHPNW12Jeroen van Dijk
 
To SQL or No(t)SQL - PFCongres 2012
To SQL or No(t)SQL - PFCongres 2012To SQL or No(t)SQL - PFCongres 2012
To SQL or No(t)SQL - PFCongres 2012Jeroen van Dijk
 
Socializing a world of travel
Socializing a world of travelSocializing a world of travel
Socializing a world of travelJeroen van Dijk
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Jeroen van Dijk
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Jeroen van Dijk
 
Edge Side Includes in Zend Framework without Varnish
Edge Side Includes in Zend Framework without VarnishEdge Side Includes in Zend Framework without Varnish
Edge Side Includes in Zend Framework without VarnishJeroen van Dijk
 

Plus de Jeroen van Dijk (12)

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

Dernier

Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 

Dernier (20)

Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 

Refactoring using Codeception

  • 6.
  • 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