SlideShare uma empresa Scribd logo
1 de 123
Baixar para ler offline
by your friend:
!
Ryan Weaver
@weaverryan
Behavioral Driven Development
with Behat
GrPhpDev FTW Meetup
KnpUniversity.com

github.com/weaverryan
• Lead for the Symfony documentation

!
• KnpLabs US - Symfony consulting, training, 

Kumbaya

!
• Writer for KnpUniversity.com

screencasts
Who is this Hipster?
!
!
!
!
!
!
• Husband of the much more

talented @leannapelham
Plan, Work, Miscommunicate,
Panic, Put out Fires, Repeat!
Intro
(aka Project Work)
The Typical Project
How the customer explained it
http://www.projectcartoon.com
How the project leader understood it
http://www.projectcartoon.com
How the programmer wrote it
http://www.projectcartoon.com
What the customer really needed
http://www.projectcartoon.com
... and my personal favorite
What the beta testers received
http://www.projectcartoon.com
Computer Science?
https://www.flickr.com/photos/diueine/3604050776
Where it breaks down...
womp womp
Different roles,
different languages,
miscommunication
@weaverryan
One
@weaverryan
Two
Your code and business
values may not align
I've just dreamt up this
cool new feature that we
should implement!
!
Why? Because it's cool!
@weaverryan
Three
Over-planning, under-planning,
planning...?
https://www.flickr.com/photos/tambako/4175456498
Act 1
!
Getting down with BDD
Evolution of Test-Driven
Development
@weaverryan
“Behaviour” is a more
useful word, than “test”
© Dan North, 2003
@weaverryan
Evolution of Test-Driven
Development
≈ Unit Tests
≈ Functional
Tests
@weaverryan
Specification BDD
http://www.phpspec.net
Scenario-oriented BDD
(Story BDD)
@weaverryan
Let’s create a single
vocabulary and process
product
owners
business
analysts
project
managers
developers
QA
@weaverryan
product
owners
business
analysts
project
managers
developers
QA
... for planning, implementing,
and testing a feature
@weaverryan
product
owners
business
analysts
project
managers
developers
QA
... with a focus on the
*behavior* of the feature
@weaverryan
Solution
1. Define business value for the features

2. Prioritize features by their business value

3. Describe them with readable scenarios

4. And only then - implement them
Act 2
!
Gherkin
A project consists of
many features
@weaverryan
These need to be planned,
written and shared
@weaverryan
@weaverryan
Gherkin
==
a structured language to
describe a feature
Feature: {custom_title}	
In order to {A}	
As a {B}	
I need to {C}
• {A} - the benefit or value of the feature
• {B} - the role (or person) who will benefit
• {C} - short feature description
| The person “writing” this feature - the “I”
@weaverryan
Solution
1. Define
!
2. Prioritize
!
3. Describe
!
4. And only then -
1. Define business value for the features
Feature: I18n	
In order to read news in french	
As a french user	
I need to be able to switch locale
read news in French
@weaverryan
Feature: I18n	
In order to read news in french	
As a french user	
I need to be able to switch locale
read news in French
The business value
@weaverryan
Feature: I18n	
In order to read news in french	
As a french user	
I need to be able to switch locale
read news in French
The person who benefits
+
The “author” of this feature
@weaverryan
Feature: I18n	
In order to read news in french	
As a french user	
I need to be able to switch locale
read news in French
Description of the feature, the
action the person will take
@weaverryan
@weaverryan
Solution
1. Define
!
2. Prioritize
!
3. Describe
!
4. And only then -
2. Prioritize features by their business value
Prioritize...
1) Feature: News admin panel	
!
2) Feature: I18n	
!
3) Feature: News list API
@weaverryan
1. Define
!
2. Prioritize
!
3. Describe
!
4. And only then -
Solution
3. Describe them with readable scenarios
Feature: News admin panel	
In order to maintain a list of news	
As a site administrator	
I need to be able to edit news
Scenario: Add new article	
Given I am on the "/admin/news" page	
When I click "New Article"	
And I fill in "Title" with "Learned BDD"	
And I press "Save"	
Then I should see "A new article was added"
Scenarios
Given
!
Defines the initial state of the system for the
scenario
Scenario: Add new article	
Given I am on the "/admin/news" page	
When I click "New Article"	
And I fill in "Title" with "Learned BDD"	
And I press "Save"	
Then I should see "A new article was added"
Scenarios
When
!
Describes the action taken by the person/role
Scenario: Add new article	
Given I am on the "/admin/news" page	
When I click "New Article"	
And I fill in "Title" with "Learned BDD"	
And I press "Save"	
Then I should see "A new article was added"
Scenarios
Then
!
Describes the observable system state after
the action has been performed
Scenario: Add new article	
Given I am on the "/admin/news" page	
When I click "New Article"	
And I fill in "Title" with "Learned BDD"	
And I press "Save"	
Then I should see "A new article was added"
Scenarios
And/But
!
Can be added to create multiple
Given/When/Then lines
Scenario: Add new article	
Given I am on the "/admin/news" page	
When I click "New Article"	
And I fill in "Title" with "Learned BDD"	
And I press "Save"	
Then I should see "A new article was added"
Example #2
Scenario: List available articles	
Given there are 5 news articles	
And I am on the "/admin" page	
When I click "News Administration"	
Then I should see 5 news articles
Gherkin
gives us a consistent language
for describing features and
their scenarios
... now let’s turn them into
tests!
http://bit.ly/behatch-t
Act 3
Having a standard way of
describing features is cool...
... executing those sentences
as functional tests is just
*AWESOME*
@weaverryan
What is Behat?
Behat does one simple thing:
** each line in a scenario is called a “step”
Behat “executes” your scenarios, reading each
step and calling the function associated with it
It Maps Each step** to a PHP Callback
Installing Behat
Behat is just a library that
can be installed easily in any
project via Composer
New to Composer? Free screencast cures it!	

KnpUniversity.com/screencast/composer
In your project directory...
1) Download Composer
$> curl -s http://getcomposer.org/installer | php
2) Create (or update) composer.json for Behat
bit.ly/behat3-composer!
{	
"require": {	
"behat/behat": "~3.0"	
}	
}
bit.ly/behat3-composer
In your project directory...
1) Download Composer
$> curl -s http://getcomposer.org/installer | php
2) Create (or update) composer.json for Behat
http://bit.ly/behat3-composer
3) Download Behat libraries
$> php composer.phar update
o/ Woo!
The most important product
of the installation is an
executable vendor/bin/behat
file
@weaverryan
To use Behat in a project you need:
!
!
1) Actual *.feature files to be executed

2) A FeatureContext.php file that holds the
PHP callbacks for each step

3) (optional) A behat.yml configuration file
$> php vendor/bin/behat --init
<?php	
// features/bootstrap/FeatureContext.php



use BehatBehatContextSnippetAcceptingContext;

use BehatGherkinNodePyStringNode;

use BehatGherkinNodeTableNode;



/**

* Behat context class.

*/

class FeatureContext implements SnippetAcceptingContext

{

}

<?php	
// features/bootstrap/FeatureContext.php



use BehatBehatContextSnippetAcceptingContext;

use BehatGherkinNodePyStringNode;

use BehatGherkinNodeTableNode;



/**

* Behat context class.

*/

class FeatureContext implements SnippetAcceptingContext

{

}

Nothing Interesting here
yet...
Pretend you’re testing the
“ls” program
1) Describe your Feature
Feature: ls
features/ls.feature
In order to see the directory structure
As a UNIX user
I need to be able to list the current
directory's contents
2) Your First Scenario
“If you have two files in a directory,
and you're running the command -
you should see them listed.”
Scenario: List 2 files in a directory
Write in the natural voice of “a UNIX user”
Given I have a file named "foo"
And I have a file named "bar"
When I run "ls"
Then I should see "foo" in the output
And I should see "bar" in the output
features/ls.feature
3) Run Behat
$> php vendor/bin/behat
Behat tries
to find a
method in
FeatureContext
for each step
Matching is
done with
simple wildcards
For each step that
doesn’t have a matching
method, Behat prints
code to copy into
FeatureContext
class FeatureContext extends BehatContext	
{	
/** @Given I have a file named :file */

public function iHaveAFileNamed($file)

{

	 	 throw new PendingException();

	 	 }



	 	 /** @When I run :command */

	 	 public function iRun($command)

	 	 {

	 	 throw new PendingException();

	 	 }	
// ...	
}
4) Copy in the new Definitions
Quoted text
maps to a
method
argument
5) Make the definitions do
what they need to
/**	
* @Given I have a file named :file	
*/	
public function iHaveAFileNamed($file) {	
touch($file);	
}	
!
/**	
* @Given I have a directory named :dir	
*/	
public function iHaveADirectoryNamed($dir) {	
mkdir($dir);	
}
/**	
* @When I run :command	
*/	
public function iRun($command) {	
exec($command, $output);	
$this->output = trim(implode("n", $output));	
}	
!
/**	
* @Then I should see :string in the output	
*/	
public function iShouldSeeInTheOutput($string) {	
if (strpos($this->output, $string) === false) {	
throw new Exception(‘Did not see’.$string);	
);	
}
See the full FeatureContext
class:
!
http://bit.ly/behat-ls-feature
Scenario Step
Definition
Given I have a file named “foo”
pattern
public function iHaveAFileNamed($file) {
do work
Pass/Fail: Each step is a “test”, which passes
*unless* an exception is thrown
touch($file);
@Given I have a file named :file
What Behat *does*
Creating files and directories in
FeatureContext is nice...
but wouldn’t it be really cool
to command a browser, fill out
forms and check the output?
Act 4
!
Mink
https://www.flickr.com/photos/15016964@N02/5696367600
Mink!
http://mink.behat.org/
• A standalone library to use PHP to 

command a “browser”

• One easy API that can be used to 

command Selenium, Goutte, ZombieJS, etc
@weaverryan
A sample of Mink
use BehatMinkDriverGoutteDriver;	
use BehatMinkSession;	
!
// change *only* this line to run	
// in Selenium, etc	
$driver = new GoutteDriver();	
$session = new Session($driver);
// visit a page	
$session->visit('http://behat.org');
echo 'URL : '.$session->getCurrentUrl();
echo 'Status: '.$session->getStatusCode();
$page = $session->getPage();
// drill down into the page	
$ele = $page->find('css', 'li:nth-child(4) a');
echo 'Link text is: '.$ele->getText();	
echo 'href is: '.$ele->getAttribute('href');
// click the link	
// (you can also fill out forms)	
$ele->click();
Mink inside FeatureContext
=>
Dangerous Combo for
Functional Testing
http://mink.behat.org/@weaverryan
Behat Mink
Integration
MinkExtension
• An “Extension” is like a Behat plugin

• The MinkExtension makes using Mink 

inside Behat a matter of configuration
@weaverryan
Install Mink & MinkExtension
$> php composer.phar update
• Update composer.json to include
> Mink
> MinkExtension
> Goutte and Selenium2 Drivers for Mink
http://bit.ly/behat-mink-composer

• Update the vendor libraries
{	
"require": {	
"behat/behat": "~3.0",	
"behat/mink-extension": "~2.0@dev",	
"behat/mink-goutte-driver": "~1.0",	
"behat/mink-selenium2-driver": "~1.1"	
}	
}	
http://bit.ly/behat-mink-composer
Goal:
!
To easily use Mink inside
FeatureContext
@weaverryan
Bootstrap MinkExtension
behat.yml is the Behat configuration file and
can contain much more than you see here
# behat.yml

default:

extensions:

BehatMinkExtension:

goutte: ~

selenium2: ~

# The base URL you're testing

base_url: http://en.wikipedia.org/
http://bit.ly/behat-yml
@weaverryan
Extend MinkContext
use BehatMinkExtensionContextRawMinkContext;



/**

* Behat context class.

*/

class FeatureContext extends RawMinkContext
Extending RawMinkContext gives us...
Access to a Mink Session
class FeatureContext extends RawMinkContext	
{	
public function doSomething()	
{	
$session = $this->getSession();	
$session->visit('http://behat.org');	
}	
!
// ...	
}
Our custom definitions can now
command a browser!
@weaverryan
More! Add MinkContext
# behat.yml

default:

extensions:	
# ...	
suites:

default:

contexts:

- FeatureContext

- BehatMinkExtensionContextMinkContext

Behat now parses definitions from *our*
class *and* this MinkContext class
We inherit a pile of great
definitions
the -dl option prints all current definitions
Before adding MinkContext:
After adding MinkContext:
In other words:
We can write some tests for
our app without writing any
PHP code
Suppose we’re testing
Wikipedia.org
# features/wikipedia.feature	
Feature: Search	
In order to see a word definition	
As a website user	
I need to be able to search for a word
These 4 definitions all come
packaged with MinkContext
Scenario: Searching for a page that does exist	
Given I am on "/wiki/Main_Page"	
When I fill in "search" with "Behavior Driven Development"	
And I press "searchButton"	
Then I should see "agile software development"
Celebration!
Act 5
!
JavaScript
https://www.flickr.com/photos/yoanngd/10669976224
Let’s try another scenario
!
Auto-Completion!
# features/wikipedia.feature
Scenario: Searching for a page with autocompletion	
Given I am on "/wiki/Main_Page"	
When I fill in "search" with "Behavior Driv"	
Then I should see "Behavior Driven Development"
http://en.wikipedia.org/wiki/The_Scream
Can we run this so that
JavaScript works?
Add @javascript
# ...	
!
@javascript	
Scenario: Searching for a page with autocompletion	
Given I am on "/wiki/Main_Page"	
When I fill in "search" with "Behavior Driv"	
Then I should see "Behavior Driven Development”	
!
!
!
Add @javascript
# ...	
!
@javascript	
Scenario: Searching for a page with autocompletion	
Given I am on "/wiki/Main_Page"	
When I fill in "search" with "Behavior Driv"	
Then I should see "Behavior Driven Development”	
!
!
!
Yep, that’s all you do!
Download and start Selenium
$> wget http://selenium-
release.storage.googleapis.com/2.42/selenium-
server-standalone-2.42.2.jar	
!
!
$> java -jar selenium-server-standalone-2.42.2.jar
Re-run the tests
Yes, add only 1 line of code
to run a test in Selenium
(you can also use phantomjs)
Your Turn!
https://www.flickr.com/photos/dtelegraph/5907116936
0) Decide Behat 2 or 3
* Behat 3 is stable, and documentation

is decent (install + config are the big

differences)
!
* Behat 2 is stable, long-term supported
and not too different from 3
1) Install Behat (v2)
http://knpuniversity.com/screencast/behat
... and learn more about what you can do
with Mink: http://mink.behat.org/
2) Write features for your app!
3) high-five your teammates
https://www.flickr.com/photos/nickwebb/3904325807
GrPhpDev FTW Meetup
Thanks!
Ryan Weaver
@weaverryan
KnpUniversity.com
PHP, Behat, Twig, OO, etc Tutorial Screencasts
Ryan Weaver
@weaverryan
... and we love west MI!
@weaverryan
KnpUniversity.com

Mais conteúdo relacionado

Mais procurados

Symfony2: Get your project started
Symfony2: Get your project startedSymfony2: Get your project started
Symfony2: Get your project started
Ryan Weaver
 
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger
 
Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::SynchronyFast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
Kyle Drake
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
True-Vision
 
Introduction to puppet
Introduction to puppetIntroduction to puppet
Introduction to puppet
Habeeb Rahman
 

Mais procurados (20)

Puppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet at GitHub / ChatOps
Puppet at GitHub / ChatOps
 
Symfony2: Get your project started
Symfony2: Get your project startedSymfony2: Get your project started
Symfony2: Get your project started
 
Paragraphs at drupal 8.
Paragraphs at drupal 8.Paragraphs at drupal 8.
Paragraphs at drupal 8.
 
Jumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin ProgrammingJumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin Programming
 
10 Laravel packages everyone should know
10 Laravel packages everyone should know10 Laravel packages everyone should know
10 Laravel packages everyone should know
 
Mastering Grunt
Mastering GruntMastering Grunt
Mastering Grunt
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
 
Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:winConsole Apps: php artisan forthe:win
Console Apps: php artisan forthe:win
 
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
 
Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::SynchronyFast, concurrent ruby web applications with EventMachine and EM::Synchrony
Fast, concurrent ruby web applications with EventMachine and EM::Synchrony
 
Getting root with benign app store apps vsecurityfest
Getting root with benign app store apps vsecurityfestGetting root with benign app store apps vsecurityfest
Getting root with benign app store apps vsecurityfest
 
Learning from the Best jQuery Plugins
Learning from the Best jQuery PluginsLearning from the Best jQuery Plugins
Learning from the Best jQuery Plugins
 
Intro to WordPress Plugin Development
Intro to WordPress Plugin DevelopmentIntro to WordPress Plugin Development
Intro to WordPress Plugin Development
 
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and GulpOptimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
 
Ako na vlastne WP temy
Ako na vlastne WP temyAko na vlastne WP temy
Ako na vlastne WP temy
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
 
Introduction to puppet
Introduction to puppetIntroduction to puppet
Introduction to puppet
 
All the Laravel things: up and running to making $$
All the Laravel things: up and running to making $$All the Laravel things: up and running to making $$
All the Laravel things: up and running to making $$
 
SocketStream
SocketStreamSocketStream
SocketStream
 

Destaque

What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
D
 
Data localization and translation
Data localization and translationData localization and translation
Data localization and translation
Motti Danino
 
Logical reasoning number series
Logical reasoning number seriesLogical reasoning number series
Logical reasoning number series
Praveesh Palakeel
 
Cmp104 lec 7 algorithm and flowcharts
Cmp104 lec 7 algorithm and flowchartsCmp104 lec 7 algorithm and flowcharts
Cmp104 lec 7 algorithm and flowcharts
kapil078
 

Destaque (20)

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...
 
Behavioral driven development with Behat
Behavioral driven development with BehatBehavioral driven development with Behat
Behavioral driven development with Behat
 
Microservice Teststrategie mit Symfony2
Microservice Teststrategie mit Symfony2Microservice Teststrategie mit Symfony2
Microservice Teststrategie mit Symfony2
 
A soa approximation on symfony
A soa approximation on symfonyA soa approximation on symfony
A soa approximation on symfony
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
Number Series: How To Solve Questions with Short Tricks
Number Series: How To Solve Questions with Short TricksNumber Series: How To Solve Questions with Short Tricks
Number Series: How To Solve Questions with Short Tricks
 
Data localization and translation
Data localization and translationData localization and translation
Data localization and translation
 
"Internationalisation with PHP and Intl" source code
"Internationalisation with PHP and Intl" source code"Internationalisation with PHP and Intl" source code
"Internationalisation with PHP and Intl" source code
 
Php Docs
Php DocsPhp Docs
Php Docs
 
Number series
Number seriesNumber series
Number series
 
Multi language for php with gettext
Multi language for php with gettextMulti language for php with gettext
Multi language for php with gettext
 
Handling multibyte CSV files in PHP
Handling multibyte CSV files in PHPHandling multibyte CSV files in PHP
Handling multibyte CSV files in PHP
 
The Big Documentation Extravaganza
The Big Documentation ExtravaganzaThe Big Documentation Extravaganza
The Big Documentation Extravaganza
 
Problem Solving with Algorithms and Data Structures
Problem Solving with Algorithms and Data StructuresProblem Solving with Algorithms and Data Structures
Problem Solving with Algorithms and Data Structures
 
People code events flowchart
People code events flowchartPeople code events flowchart
People code events flowchart
 
Internationalisation with PHP and Intl
Internationalisation with PHP and IntlInternationalisation with PHP and Intl
Internationalisation with PHP and Intl
 
Logical reasoning number series
Logical reasoning number seriesLogical reasoning number series
Logical reasoning number series
 
Computer Science Engineering : Data structure & algorithm, THE GATE ACADEMY
Computer Science Engineering : Data structure & algorithm, THE GATE ACADEMYComputer Science Engineering : Data structure & algorithm, THE GATE ACADEMY
Computer Science Engineering : Data structure & algorithm, THE GATE ACADEMY
 
Microservice architecture
Microservice architectureMicroservice architecture
Microservice architecture
 
Cmp104 lec 7 algorithm and flowcharts
Cmp104 lec 7 algorithm and flowchartsCmp104 lec 7 algorithm and flowcharts
Cmp104 lec 7 algorithm and flowcharts
 

Semelhante a Grand Rapids PHP Meetup: Behavioral Driven Development with Behat

Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
Joshua Warren
 

Semelhante a Grand Rapids PHP Meetup: Behavioral Driven Development with Behat (20)

Behat - Drupal South 2018
Behat  - Drupal South 2018Behat  - Drupal South 2018
Behat - Drupal South 2018
 
BDD, Behat & Drupal
BDD, Behat & DrupalBDD, Behat & Drupal
BDD, Behat & Drupal
 
Easy contributable internationalization process with Sphinx @ pyconsg2015
Easy contributable internationalization process with Sphinx @ pyconsg2015Easy contributable internationalization process with Sphinx @ pyconsg2015
Easy contributable internationalization process with Sphinx @ pyconsg2015
 
Python Requirements File How to Create Python requirements.txt
Python Requirements File How to Create Python requirements.txtPython Requirements File How to Create Python requirements.txt
Python Requirements File How to Create Python requirements.txt
 
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
 
Easy contributable internationalization process with Sphinx @ PyCon APAC 2016
Easy contributable internationalization process with Sphinx @ PyCon APAC 2016Easy contributable internationalization process with Sphinx @ PyCon APAC 2016
Easy contributable internationalization process with Sphinx @ PyCon APAC 2016
 
PHP
PHPPHP
PHP
 
Easy contributable internationalization process with Sphinx @ pyconmy2015
Easy contributable internationalization process with Sphinx @ pyconmy2015Easy contributable internationalization process with Sphinx @ pyconmy2015
Easy contributable internationalization process with Sphinx @ pyconmy2015
 
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For Youpnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
 
Make an Instant Website with Webhooks
Make an Instant Website with WebhooksMake an Instant Website with Webhooks
Make an Instant Website with Webhooks
 
Demystifying Maven
Demystifying MavenDemystifying Maven
Demystifying Maven
 
Offline of web applications
Offline of web applicationsOffline of web applications
Offline of web applications
 
Offline for web - Frontend Dev Conf Minsk 2014
Offline for web - Frontend Dev Conf Minsk 2014Offline for web - Frontend Dev Conf Minsk 2014
Offline for web - Frontend Dev Conf Minsk 2014
 
REPORT ON AUDIT COURSE PYTHON BY SANA 2.pdf
REPORT ON AUDIT COURSE PYTHON BY SANA 2.pdfREPORT ON AUDIT COURSE PYTHON BY SANA 2.pdf
REPORT ON AUDIT COURSE PYTHON BY SANA 2.pdf
 
Orangescrum In App Chat Add-on User Manual
Orangescrum In App Chat Add-on User ManualOrangescrum In App Chat Add-on User Manual
Orangescrum In App Chat Add-on User Manual
 
Easy contributable internationalization process with Sphinx (PyCon APAC 2015 ...
Easy contributable internationalization process with Sphinx (PyCon APAC 2015 ...Easy contributable internationalization process with Sphinx (PyCon APAC 2015 ...
Easy contributable internationalization process with Sphinx (PyCon APAC 2015 ...
 
OpenNTF Blast from ILUG 2007
OpenNTF Blast from ILUG 2007OpenNTF Blast from ILUG 2007
OpenNTF Blast from ILUG 2007
 
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit SoftwaretestsEffizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
 
TYPO3 at UNESCO.org
TYPO3 at UNESCO.orgTYPO3 at UNESCO.org
TYPO3 at UNESCO.org
 
Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
 

Mais de Ryan Weaver

Doctrine2 In 10 Minutes
Doctrine2 In 10 MinutesDoctrine2 In 10 Minutes
Doctrine2 In 10 Minutes
Ryan Weaver
 

Mais de Ryan Weaver (13)

The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
 
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreSymfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Silex: Microframework y camino fácil de aprender Symfony
Silex: Microframework y camino fácil de aprender SymfonySilex: Microframework y camino fácil de aprender Symfony
Silex: Microframework y camino fácil de aprender Symfony
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
 
A PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 appA PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 app
 
Symony2 A Next Generation PHP Framework
Symony2 A Next Generation PHP FrameworkSymony2 A Next Generation PHP Framework
Symony2 A Next Generation PHP Framework
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
 
Being Dangerous with Twig (Symfony Live Paris)
Being Dangerous with Twig (Symfony Live Paris)Being Dangerous with Twig (Symfony Live Paris)
Being Dangerous with Twig (Symfony Live Paris)
 
Doctrine2 In 10 Minutes
Doctrine2 In 10 MinutesDoctrine2 In 10 Minutes
Doctrine2 In 10 Minutes
 
Dependency Injection: Make your enemies fear you
Dependency Injection: Make your enemies fear youDependency Injection: Make your enemies fear you
Dependency Injection: Make your enemies fear you
 
The Art of Doctrine Migrations
The Art of Doctrine MigrationsThe Art of Doctrine Migrations
The Art of Doctrine Migrations
 

Último

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
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
 

Grand Rapids PHP Meetup: Behavioral Driven Development with Behat