SlideShare ist ein Scribd-Unternehmen logo
1 von 28
Downloaden Sie, um offline zu lesen
ZürichPHP UG 18.06.2015

Pascal Thormeier
Setup
Big Symfony2 project for large Swiss
company

Multiple attached APIs

Tests in both PHPUnit and Behat/PhantomJS

Gitlab CI and vagrant for development
ONCE UPON A TIME
History
Testing with manually created fixtures

Mocks had to be adjusted when APIs
changed

Using Guzzle's mock plugin

Symfony's profiler helped out quite a lot...
Mocking:

• Do API call you would like to mock

• Copy/paste response to JSON/XML file

• Adjust to test cases

• Re-do whole fixture when small things changed
History
Behat tests couldn't really be mocked

Built an application that proxies API calls
and runs in the back in an own container

Loads of problems with that solution
History
Switching to PHP-VCR

Behat testing and mocking became very
well possible

Old way of creating fixtures was no longer
necessary
History
WHAT ARE WE DOING
NOW?
Behat
Testing framework

Works with different so called drivers

Tests are written in Gherkin

We're using the Selenium2 and Symfony
Web drivers
Selenium
PhantomJS as headless browser

PHP -> node.js -> PHP

... which leads to a problem
Selenium
Two different, independent PHP processes

Which fixture should the application load?
Selenium
Let's just use a cookie.
Selenium
<?php	
class AcmeContext extends MinkContext 	
{	
const COOKIE_NAME = 'BehatCassetteName';	
!
// ...	
!
public function before(BeforeScenarioScope $scope)	
{	
$this->getSession()->setCookie(	
self::COOKIE_NAME,	
$this->getCassetteName($scope)	
);	
}	
!
// ...	
!
}
Selenium
<?php	
class AcmeContext extends MinkContext 	
{	
!
// ...	
!
public function getCasetteName($scope)	
{	
return 'fixtures/'	
. self::normalize($scope->getFeature()->getTitle())	
. '/'	
. self::normalize($scope->getScenario()->getTitle())	
;	
}	
!
public static function normalize($string)	
{	
return trim(preg_replace(	
'/[^a-zA-Z0-9]+/', '_', $string	
), '_');	
}	
!
// ...	
!
}
Gherkin
Feature: Some terse yet descriptive text of what is desired	
In order to realize a named business value	
As an explicit system actor	
I want to gain some beneficial outcome which furthers the goal	
!
Additional text...	
!
Scenario: Some determinable business situation	
Given some precondition	
And some other precondition	
When some action by the actor	
And some other action	
And yet another action	
Then some testable outcome is achieved	
And something else we can check happens too	
!
Scenario: A different situation	
...
Selenium
<?php	
// web/app_test.php - Remove this file while deployment!	
!
// ...	
!
// Execute standard SF2 stuff	
$kernel = new AppKernel('test', true);	
$kernel->loadClassCache();	
Request::enableHttpMethodParameterOverride();	
$request = Request::createFromGlobals();	
!
// Set up VCR with fixture name from cookie	
$fixture = $request->cookies->get(AcmeContext::COOKIE_NAME, null);	
if (!$fixture) {	
$fixture = AcmeContext::normalize($request->getUri());	
}	
VCR::turnOn(); 	
VCR::insertCassette('../tests/' . $fixture . '.json');	
!
// Execute standard SF2 stuff	
$response = $kernel->handle($request);	
$response->send();	
$kernel->terminate($request, $response);	
!
// Save the fixture	
VCR::eject();	
VCR::turnOff();
Selenium
Neat side effects:

• Developing without internet!

• Change API responses for development
Minor pitfall:

• PhantomJS doesn't send this cookie when
doing AJAX

• Fixtures for AJAX would be named after the
URL, which works but isn't as nice

• You have to set the cookie manually in JS again
Selenium
WebDriver
We want this in the SF WebDriver as well

Move it from app_test to AppKernel

Keep app_test.php as entry point for
PhantomJS
WebDriver
<?php	
class AppKernel extends Kernel	
{	
// ...	
public function handle(Request $request, ...)	
{	
if ('test' === $this->getEnvironment()) {	
$fixture = $request->cookies->get(	
AcmeContext::COOKIE_NAME, null	
);	
!
if (!$fixture) {	
$fixture = AcmeContext::normalize(	
$request->getUri()	
);	
}	
!
VCR::turnOn(); 	
VCR::insertCassette('../tests/' . $fixture . '.json');	
}	
!
return parent::handle($request, ...);	
}	
// ...	
}
WebDriver
Would only need minor adjustments to also
work in PHPUnit/Symfony WebTestCase
GitlabCI
CI is executing tests as well

Tests might not be mocked

Test will be mocked

Conflicts while making a new build
GitlabCI
<?php	
// ...	
!
if ($container->hasParameter('is_ci')) {	
VCR::configure()->setMode(VCR::MODE_NONE);	
}	
!
// ...
WRAP UP
Wrap up
PHP-VCR is awesome

But switching all fixtures to PHP-VCR might
be a lot of work

But you don't need to write them
yourselves anymore
Wrap up
Some pitfalls:

• Tests without fixtures

• Setup depending on framework might be difficult

• Not very transparent where data comes from
inside tests

• First test run to write all the fixtures is slow
Wrap up
Would highly recommend it because it
saves you a lot of time, work and nerves
Info
Info and documentation: http://php-
vcr.github.io

Source: https://github.com/php-vcr/php-vcr

VCR (ruby): https://github.com/vcr/vcr

Follow: @pthormeier and @adrian_philipp

Weitere ähnliche Inhalte

Was ist angesagt?

Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Puppet
 
CodeIgniter Ant Scripting
CodeIgniter Ant ScriptingCodeIgniter Ant Scripting
CodeIgniter Ant ScriptingAlbert Rosa
 
Code igniter unittest-part1
Code igniter unittest-part1Code igniter unittest-part1
Code igniter unittest-part1Albert Rosa
 
Flask With Server-Sent Event
Flask With Server-Sent EventFlask With Server-Sent Event
Flask With Server-Sent EventTencent
 
Futureproof angular 1.x applications - yannick houbrix
Futureproof angular 1.x  applications - yannick houbrixFutureproof angular 1.x  applications - yannick houbrix
Futureproof angular 1.x applications - yannick houbrixAxxes IT Consultancy
 
Managing Complexity with Module::Release
Managing Complexity with Module::ReleaseManaging Complexity with Module::Release
Managing Complexity with Module::Releasebrian d foy
 
Implement server push in flask framework
Implement server push in flask frameworkImplement server push in flask framework
Implement server push in flask frameworkChi-Chia Huang
 
Pitfalls in Performance Testing AxxesCC 06/2015
Pitfalls in Performance Testing AxxesCC 06/2015Pitfalls in Performance Testing AxxesCC 06/2015
Pitfalls in Performance Testing AxxesCC 06/2015Axxes IT Consultancy
 
Vagrant - the essence of DevOps in a tool
Vagrant - the essence of DevOps in a toolVagrant - the essence of DevOps in a tool
Vagrant - the essence of DevOps in a toolPaul Stack
 
GTLAB Overview
GTLAB OverviewGTLAB Overview
GTLAB Overviewmarpierc
 
Full stack, Full run, Full test
Full stack, Full run, Full testFull stack, Full run, Full test
Full stack, Full run, Full testTaras Slipets
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmineTimothy Oxley
 
Introducing Revel
Introducing RevelIntroducing Revel
Introducing RevelZhebr
 
Continuous integration with Git & CI Joe
Continuous integration with Git & CI JoeContinuous integration with Git & CI Joe
Continuous integration with Git & CI JoeShawn Price
 
Unit Testing with Jest
Unit Testing with JestUnit Testing with Jest
Unit Testing with JestMaayan Glikser
 
Server::Starter meets Java
Server::Starter meets JavaServer::Starter meets Java
Server::Starter meets JavaTokuhiro Matsuno
 

Was ist angesagt? (20)

Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
 
CodeIgniter Ant Scripting
CodeIgniter Ant ScriptingCodeIgniter Ant Scripting
CodeIgniter Ant Scripting
 
Code igniter unittest-part1
Code igniter unittest-part1Code igniter unittest-part1
Code igniter unittest-part1
 
Flask With Server-Sent Event
Flask With Server-Sent EventFlask With Server-Sent Event
Flask With Server-Sent Event
 
Ava unit test
Ava unit testAva unit test
Ava unit test
 
Cramp websockets
Cramp websocketsCramp websockets
Cramp websockets
 
Futureproof angular 1.x applications - yannick houbrix
Futureproof angular 1.x  applications - yannick houbrixFutureproof angular 1.x  applications - yannick houbrix
Futureproof angular 1.x applications - yannick houbrix
 
Managing Complexity with Module::Release
Managing Complexity with Module::ReleaseManaging Complexity with Module::Release
Managing Complexity with Module::Release
 
Implement server push in flask framework
Implement server push in flask frameworkImplement server push in flask framework
Implement server push in flask framework
 
C++ Production Debugging
C++ Production DebuggingC++ Production Debugging
C++ Production Debugging
 
Pitfalls in Performance Testing AxxesCC 06/2015
Pitfalls in Performance Testing AxxesCC 06/2015Pitfalls in Performance Testing AxxesCC 06/2015
Pitfalls in Performance Testing AxxesCC 06/2015
 
Vagrant - the essence of DevOps in a tool
Vagrant - the essence of DevOps in a toolVagrant - the essence of DevOps in a tool
Vagrant - the essence of DevOps in a tool
 
Capistrano
CapistranoCapistrano
Capistrano
 
GTLAB Overview
GTLAB OverviewGTLAB Overview
GTLAB Overview
 
Full stack, Full run, Full test
Full stack, Full run, Full testFull stack, Full run, Full test
Full stack, Full run, Full test
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmine
 
Introducing Revel
Introducing RevelIntroducing Revel
Introducing Revel
 
Continuous integration with Git & CI Joe
Continuous integration with Git & CI JoeContinuous integration with Git & CI Joe
Continuous integration with Git & CI Joe
 
Unit Testing with Jest
Unit Testing with JestUnit Testing with Jest
Unit Testing with Jest
 
Server::Starter meets Java
Server::Starter meets JavaServer::Starter meets Java
Server::Starter meets Java
 

Ähnlich wie PHP-VCR behat case study

Continous Delivering a PHP application
Continous Delivering a PHP applicationContinous Delivering a PHP application
Continous Delivering a PHP applicationJavier López
 
One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.Javier López
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.catPablo Godel
 
Altitude San Francisco 2018: Testing with Fastly Workshop
Altitude San Francisco 2018: Testing with Fastly WorkshopAltitude San Francisco 2018: Testing with Fastly Workshop
Altitude San Francisco 2018: Testing with Fastly WorkshopFastly
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesPavol Pitoňák
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidenceJohn Congdon
 
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Ondřej Machulda
 
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav DukhinFwdays
 
Python Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CIPython Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CIBruno Rocha
 
Monitoring kubernetes with prometheus
Monitoring kubernetes with prometheusMonitoring kubernetes with prometheus
Monitoring kubernetes with prometheusBrice Fernandes
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
Getting started with puppet and vagrant (1)
Getting started with puppet and vagrant (1)Getting started with puppet and vagrant (1)
Getting started with puppet and vagrant (1)Puppet
 
Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)HungWei Chiu
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Ryan Weaver
 
Javascript tdd byandreapaciolla
Javascript tdd byandreapaciollaJavascript tdd byandreapaciolla
Javascript tdd byandreapaciollaAndrea Paciolla
 
Using HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationUsing HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationCiaranMcNulty
 
Learn basic ansible using docker
Learn basic ansible using dockerLearn basic ansible using docker
Learn basic ansible using dockerLarry Cai
 
Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?Tobias Schneck
 
Symfony finally swiped right on envvars
Symfony finally swiped right on envvarsSymfony finally swiped right on envvars
Symfony finally swiped right on envvarsSam Marley-Jarrett
 

Ähnlich wie PHP-VCR behat case study (20)

Continous Delivering a PHP application
Continous Delivering a PHP applicationContinous Delivering a PHP application
Continous Delivering a PHP application
 
One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.cat
 
Altitude San Francisco 2018: Testing with Fastly Workshop
Altitude San Francisco 2018: Testing with Fastly WorkshopAltitude San Francisco 2018: Testing with Fastly Workshop
Altitude San Francisco 2018: Testing with Fastly Workshop
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile Devices
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidence
 
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
 
Mcollective introduction
Mcollective introductionMcollective introduction
Mcollective introduction
 
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
 
Python Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CIPython Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CI
 
Monitoring kubernetes with prometheus
Monitoring kubernetes with prometheusMonitoring kubernetes with prometheus
Monitoring kubernetes with prometheus
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
Getting started with puppet and vagrant (1)
Getting started with puppet and vagrant (1)Getting started with puppet and vagrant (1)
Getting started with puppet and vagrant (1)
 
Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
 
Javascript tdd byandreapaciolla
Javascript tdd byandreapaciollaJavascript tdd byandreapaciolla
Javascript tdd byandreapaciolla
 
Using HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationUsing HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless Integration
 
Learn basic ansible using docker
Learn basic ansible using dockerLearn basic ansible using docker
Learn basic ansible using docker
 
Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?
 
Symfony finally swiped right on envvars
Symfony finally swiped right on envvarsSymfony finally swiped right on envvars
Symfony finally swiped right on envvars
 

Kürzlich hochgeladen

Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 

PHP-VCR behat case study

  • 2. Setup Big Symfony2 project for large Swiss company Multiple attached APIs Tests in both PHPUnit and Behat/PhantomJS Gitlab CI and vagrant for development
  • 3. ONCE UPON A TIME
  • 4. History Testing with manually created fixtures Mocks had to be adjusted when APIs changed Using Guzzle's mock plugin Symfony's profiler helped out quite a lot...
  • 5. Mocking: • Do API call you would like to mock • Copy/paste response to JSON/XML file • Adjust to test cases • Re-do whole fixture when small things changed History
  • 6. Behat tests couldn't really be mocked Built an application that proxies API calls and runs in the back in an own container Loads of problems with that solution History
  • 7. Switching to PHP-VCR Behat testing and mocking became very well possible Old way of creating fixtures was no longer necessary History
  • 8. WHAT ARE WE DOING NOW?
  • 9. Behat Testing framework Works with different so called drivers Tests are written in Gherkin We're using the Selenium2 and Symfony Web drivers
  • 10. Selenium PhantomJS as headless browser PHP -> node.js -> PHP ... which leads to a problem
  • 11. Selenium Two different, independent PHP processes Which fixture should the application load?
  • 13. Selenium <?php class AcmeContext extends MinkContext { const COOKIE_NAME = 'BehatCassetteName'; ! // ... ! public function before(BeforeScenarioScope $scope) { $this->getSession()->setCookie( self::COOKIE_NAME, $this->getCassetteName($scope) ); } ! // ... ! }
  • 14. Selenium <?php class AcmeContext extends MinkContext { ! // ... ! public function getCasetteName($scope) { return 'fixtures/' . self::normalize($scope->getFeature()->getTitle()) . '/' . self::normalize($scope->getScenario()->getTitle()) ; } ! public static function normalize($string) { return trim(preg_replace( '/[^a-zA-Z0-9]+/', '_', $string ), '_'); } ! // ... ! }
  • 15. Gherkin Feature: Some terse yet descriptive text of what is desired In order to realize a named business value As an explicit system actor I want to gain some beneficial outcome which furthers the goal ! Additional text... ! Scenario: Some determinable business situation Given some precondition And some other precondition When some action by the actor And some other action And yet another action Then some testable outcome is achieved And something else we can check happens too ! Scenario: A different situation ...
  • 16. Selenium <?php // web/app_test.php - Remove this file while deployment! ! // ... ! // Execute standard SF2 stuff $kernel = new AppKernel('test', true); $kernel->loadClassCache(); Request::enableHttpMethodParameterOverride(); $request = Request::createFromGlobals(); ! // Set up VCR with fixture name from cookie $fixture = $request->cookies->get(AcmeContext::COOKIE_NAME, null); if (!$fixture) { $fixture = AcmeContext::normalize($request->getUri()); } VCR::turnOn(); VCR::insertCassette('../tests/' . $fixture . '.json'); ! // Execute standard SF2 stuff $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response); ! // Save the fixture VCR::eject(); VCR::turnOff();
  • 17. Selenium Neat side effects: • Developing without internet! • Change API responses for development
  • 18. Minor pitfall: • PhantomJS doesn't send this cookie when doing AJAX • Fixtures for AJAX would be named after the URL, which works but isn't as nice • You have to set the cookie manually in JS again Selenium
  • 19. WebDriver We want this in the SF WebDriver as well Move it from app_test to AppKernel Keep app_test.php as entry point for PhantomJS
  • 20. WebDriver <?php class AppKernel extends Kernel { // ... public function handle(Request $request, ...) { if ('test' === $this->getEnvironment()) { $fixture = $request->cookies->get( AcmeContext::COOKIE_NAME, null ); ! if (!$fixture) { $fixture = AcmeContext::normalize( $request->getUri() ); } ! VCR::turnOn(); VCR::insertCassette('../tests/' . $fixture . '.json'); } ! return parent::handle($request, ...); } // ... }
  • 21. WebDriver Would only need minor adjustments to also work in PHPUnit/Symfony WebTestCase
  • 22. GitlabCI CI is executing tests as well Tests might not be mocked Test will be mocked Conflicts while making a new build
  • 23. GitlabCI <?php // ... ! if ($container->hasParameter('is_ci')) { VCR::configure()->setMode(VCR::MODE_NONE); } ! // ...
  • 25. Wrap up PHP-VCR is awesome But switching all fixtures to PHP-VCR might be a lot of work But you don't need to write them yourselves anymore
  • 26. Wrap up Some pitfalls: • Tests without fixtures • Setup depending on framework might be difficult • Not very transparent where data comes from inside tests • First test run to write all the fixtures is slow
  • 27. Wrap up Would highly recommend it because it saves you a lot of time, work and nerves
  • 28. Info Info and documentation: http://php- vcr.github.io Source: https://github.com/php-vcr/php-vcr VCR (ruby): https://github.com/vcr/vcr Follow: @pthormeier and @adrian_philipp