Top Banner
Behavior & Specication Driven Development in PHP Presented by Joshua Warren
94

Behavior & Specification Driven Development in PHP - #OpenWest

Aug 15, 2015

Download

Technology

Joshua Warren
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Behavior & Specification Driven Development in PHP - #OpenWest

Behavior & Specification Driven Development in PHP

Presented by Joshua Warren

Page 2: Behavior & Specification Driven Development in PHP - #OpenWest

OR:

Page 3: Behavior & Specification Driven Development in PHP - #OpenWest

I heard you like to code, so let’s write code that writes code while

you code.

Page 4: Behavior & Specification Driven Development in PHP - #OpenWest
Page 5: Behavior & Specification Driven Development in PHP - #OpenWest

About Me

Page 6: Behavior & Specification Driven Development in PHP - #OpenWest

PHP DeveloperWorking with PHP since 1999

Page 7: Behavior & Specification Driven Development in PHP - #OpenWest

Founder & CEOFounded Creatuity in 2008

PHP Development Firm

Focused on the Magento platform

Tink, a Creatuity shareholder

Page 8: Behavior & Specification Driven Development in PHP - #OpenWest

JoshuaWarren.com

@JoshuaSWarren

Page 9: Behavior & Specification Driven Development in PHP - #OpenWest

IMPORTANT!

• joind.in/14065

• Download slides

• Post comments

• Leave a rating!

Page 10: Behavior & Specification Driven Development in PHP - #OpenWest

What You Need To Know

ASSUMPTIONS

Page 11: Behavior & Specification Driven Development in PHP - #OpenWest

Today we assume you’re a PHP developer.

Page 12: Behavior & Specification Driven Development in PHP - #OpenWest

That you are familiar with test driven development.

Page 13: Behavior & Specification Driven Development in PHP - #OpenWest

And that you’ve at least tried PHPUnit, Selenium or another testing tool.

Page 14: Behavior & Specification Driven Development in PHP - #OpenWest

BDD - no, the B does not stand for beer, despite what a Brit might tell you

Behavior Driven Development

Page 15: Behavior & Specification Driven Development in PHP - #OpenWest

Think of BDD as stepping back a level from TDD.

Page 17: Behavior & Specification Driven Development in PHP - #OpenWest

TDD generally deals with functional units.

Page 18: Behavior & Specification Driven Development in PHP - #OpenWest

BDD steps back a level to consider complete features.

Page 19: Behavior & Specification Driven Development in PHP - #OpenWest

In BDD, you write feature files in the form of user stories that you test against.

Page 20: Behavior & Specification Driven Development in PHP - #OpenWest

BDD uses a ubiquitous language - basically, a language that business stakeholders, project managers, developers

and our automated tools can all understand.

Page 21: Behavior & Specification Driven Development in PHP - #OpenWest

Sample Behat Feature File

Feature: Laravel Test In order to demonstrate Laravel and Behat As a user I need to be able to visit the homepage of a new Laravel app Scenario: Homepage Given I am on the homepage Then I should see "Laravel 5"

Page 22: Behavior & Specification Driven Development in PHP - #OpenWest

Behat

Page 23: Behavior & Specification Driven Development in PHP - #OpenWest

We implement BDD in PHP with a tool called Behat

Page 24: Behavior & Specification Driven Development in PHP - #OpenWest

Behat is a free, open source tool designed for BDD and PHP

Page 25: Behavior & Specification Driven Development in PHP - #OpenWest

behat.org

Page 26: Behavior & Specification Driven Development in PHP - #OpenWest

SpecBDD - aka, Testing Tongue Twisters

Specification Behavior Driven Development

Page 27: Behavior & Specification Driven Development in PHP - #OpenWest

Before you write a line of code, you write a specification for how that code should work

Page 28: Behavior & Specification Driven Development in PHP - #OpenWest

Focuses you on architectural decisions up-front

Page 29: Behavior & Specification Driven Development in PHP - #OpenWest

PHPSpec

Page 30: Behavior & Specification Driven Development in PHP - #OpenWest

Open Source tool for specification driven development in PHP

Page 31: Behavior & Specification Driven Development in PHP - #OpenWest

www.phpspec.net

Page 32: Behavior & Specification Driven Development in PHP - #OpenWest

Why Use Behat and PHPSpec?

Page 33: Behavior & Specification Driven Development in PHP - #OpenWest

These tools allow you to focus exclusively on logic

Page 34: Behavior & Specification Driven Development in PHP - #OpenWest

Helps build functional testing coverage

Page 35: Behavior & Specification Driven Development in PHP - #OpenWest

Guides planning and ensuring that all stakeholders are in agreement

Page 36: Behavior & Specification Driven Development in PHP - #OpenWest

Let’s Build Something!

Page 37: Behavior & Specification Driven Development in PHP - #OpenWest

… what we’re building …

Page 38: Behavior & Specification Driven Development in PHP - #OpenWest

Setting up Our Project

Page 39: Behavior & Specification Driven Development in PHP - #OpenWest

Setup a Laravel 5 project

Page 40: Behavior & Specification Driven Development in PHP - #OpenWest

Run composer require —dev

behat/behat

behat/mink

behat/mink-extensions

laracasts/behat-laravel-extension

phpspec/phpspec

benconstable/phpspec-laravel

Page 41: Behavior & Specification Driven Development in PHP - #OpenWest

Run:

vendor/bin/behat —init

Page 42: Behavior & Specification Driven Development in PHP - #OpenWest

Create /behat.yaml

default: extensions: Laracasts\Behat: ~ Behat\MinkExtension\ServiceContainer\MinkExtension: default_session: laravel laravel: ~

Page 43: Behavior & Specification Driven Development in PHP - #OpenWest

Create /phpspec.yamlsuites:

main:

namespace: App

psr4_prefix: App

src_path: app

extensions:

- PhpSpec\Laravel\Extension\LaravelExtension

Page 44: Behavior & Specification Driven Development in PHP - #OpenWest

Features

Page 45: Behavior & Specification Driven Development in PHP - #OpenWest

features/fitbit.featureFeature: Fitbit IntegrationIn order to obtain Fitbit dataAs a userI need to be able to authenticate with Fitbit

Scenario: Not yet authenticated Given I am not logged in as “[email protected]” When I go to "/fitbit/" Then I should see "Please authenticate"

Page 46: Behavior & Specification Driven Development in PHP - #OpenWest

vendor/bin/behat —append-snippets

Scenario: Not yet authenticated:6 Given I am not logged in as “[email protected] When I go to "/fitbit/" Then I should see "Please authenticate" 1 scenario (1 undefined) 3 steps (1 undefined, 2 skipped) 0m0.48s (11.00Mb)

u features/bootstrap/FeatureContext.php - `I am not logged in as` definition added

Page 47: Behavior & Specification Driven Development in PHP - #OpenWest

Behat’s written code for us!

Page 48: Behavior & Specification Driven Development in PHP - #OpenWest

/features/bootstrap/FeatureContext.php

/** * @Given I am not logged in as :arg1 */public function iAmNotLoggedInAs($arg1){ throw new PendingException(); }

Page 49: Behavior & Specification Driven Development in PHP - #OpenWest

Behat writes just enough to get us show us where to add our logic.

Page 50: Behavior & Specification Driven Development in PHP - #OpenWest

Behat expects us to add logic to this function to detect the user is not logged in.

Page 51: Behavior & Specification Driven Development in PHP - #OpenWest

Before we do that, let’s finish out our feature file.

Page 52: Behavior & Specification Driven Development in PHP - #OpenWest

features/fitbit.feature continuedScenario: I have authenticatedGiven I am logged in as “[email protected]” When I go to "/fitbit/"Then I should see "Welcome back"

Scenario: I have sleep dataGiven I am logged in as “[email protected]” When I go to "/fitbit/sleep/"Then I should see "Sleep Report"

Page 53: Behavior & Specification Driven Development in PHP - #OpenWest

Run vendor/bin/behat —append-snippets one more time

Page 54: Behavior & Specification Driven Development in PHP - #OpenWest

Now, let’s fill in the logic Behat needs us to add.

Page 55: Behavior & Specification Driven Development in PHP - #OpenWest

/features/bootstrap/FeatureContext.php

/** * @Given I am not logged in as :email */public function iAmNotLoggedInAs($email) { // We completely log out // Destroy the previous session if (Session::isStarted()) { Session::regenerate(true); } else { Session::start(); } }

Page 56: Behavior & Specification Driven Development in PHP - #OpenWest

/features/bootstrap/FeatureContext.phppublic function iAmLoggedInAs($email) { // Destroy the previous session if (Session::isStarted()) { Session::regenerate(true); } else { Session::start(); } // Login the user and since the driver and this code now // share a session this will also login the driver session $user = User::where('email', $email)->firstOrFail(); Auth::login($user); // Save the session data to disk or to memcache Session::save(); // Hack for Selenium // Before setting a cookie the browser needs to be launched if ($this->getSession()->getDriver() instanceof \Behat\Mink\Driver\Selenium2Driver) { $this->visit('login'); } // Get the session identifier for the cookie $encryptedSessionId = Crypt::encrypt(Session::getId()); $cookieName = Session::getName(); // Set the cookie $minkSession = $this->getSession(); $minkSession->setCookie($cookieName, $encryptedSessionId); }

Page 57: Behavior & Specification Driven Development in PHP - #OpenWest

We run vendor/bin/behat once more

Page 58: Behavior & Specification Driven Development in PHP - #OpenWest

vendor/bin/behat…

Scenario: I have sleep data Given I am logged in as "[email protected]" When I go to "/fitbit/sleep/" Then I should see "Sleep Report" The text "Sleep Report" was not found anywhere in the text of the current page. (Behat\Mink\Exception\ResponseTextException)

--- Failed scenarios: features/fitbit.feature:6 features/fitbit.feature:11 features/fitbit.feature:16

Page 59: Behavior & Specification Driven Development in PHP - #OpenWest

A perfect failure!

Page 60: Behavior & Specification Driven Development in PHP - #OpenWest

These failures show us that Behat is testing our app properly, and now we just need to write the

application logic.

Page 61: Behavior & Specification Driven Development in PHP - #OpenWest

Specifications

Page 62: Behavior & Specification Driven Development in PHP - #OpenWest

Now we write specifications for how our Fitbit class should work.

Page 63: Behavior & Specification Driven Development in PHP - #OpenWest

These specifications should provide the logic to deliver the results that Behat is testing for.

Page 64: Behavior & Specification Driven Development in PHP - #OpenWest

vendor/bin/phpspec describe Fitbit

Specification for Fitbit created in <project root>/spec/FitbitSpec.php

Page 65: Behavior & Specification Driven Development in PHP - #OpenWest

PHPSpec generates a basic spec file for us

Page 66: Behavior & Specification Driven Development in PHP - #OpenWest

spec/FitbitSpec.phpnamespace spec; use PhpSpec\ObjectBehavior; use Prophecy\Argument; class FitbitSpec extends ObjectBehavior{ function it_is_initializable() { $this->shouldHaveType('Fitbit'); } }

Page 67: Behavior & Specification Driven Development in PHP - #OpenWest

This default spec tells PHPSpec to expect a class named Fitbit.

Page 68: Behavior & Specification Driven Development in PHP - #OpenWest

Now we add a bit more to the file so PHPSpec will understand what this class should do.

Page 69: Behavior & Specification Driven Development in PHP - #OpenWest

spec/FitbitSpec.php continuedfunction it_connects_to_fitbit($email) { $this->connect($email)->shouldReturn('Success'); } function it_returns_sleep_data($email) { $this->sleepData($email)->shouldReturn([8, 8, 8, 8, 8]); }

Page 70: Behavior & Specification Driven Development in PHP - #OpenWest

Now we run PHPSpec once more…

Page 71: Behavior & Specification Driven Development in PHP - #OpenWest

vendor/bin/phpspec run 10 ! is initializable (142ms) class Fitbit does not exist. 15 ! connects to fitbit (100ms) class Fitbit does not exist. 20 ! returns sleep data class Fitbit does not exist.

---- broken examples

Fitbit 10 ! is initializable (142ms) class Fitbit does not exist.

Fitbit 15 ! connects to fitbit (100ms) class Fitbit does not exist.

Fitbit 20 ! returns sleep data class Fitbit does not exist.

1 specs 3 examples (3 broken)

Page 72: Behavior & Specification Driven Development in PHP - #OpenWest

Lots of failures…

Page 73: Behavior & Specification Driven Development in PHP - #OpenWest

But wait a second - PHPSpec prompts us!

Page 74: Behavior & Specification Driven Development in PHP - #OpenWest

Do you want me to create `Fitbit` for you? [Y/n]

Page 75: Behavior & Specification Driven Development in PHP - #OpenWest

PHPSpec will create the class and the methods for us!

Page 76: Behavior & Specification Driven Development in PHP - #OpenWest

This is very powerful with frameworks like Laravel and Magento, which have PHPSpec plugins that help PHPSpec know where class files should be

located.

Page 77: Behavior & Specification Driven Development in PHP - #OpenWest

Fitbit.php - class Fitbit {

function connect($email) { // TODO: write logic here} function sleepData($email) { // TODO: write logic here}

Page 78: Behavior & Specification Driven Development in PHP - #OpenWest

And now, the easy part…

Page 79: Behavior & Specification Driven Development in PHP - #OpenWest

Implementation

Page 80: Behavior & Specification Driven Development in PHP - #OpenWest

Implement logic in the new Fitbit class in the locations directed by PHPSpec

Page 81: Behavior & Specification Driven Development in PHP - #OpenWest

Tie that logic into views in our application.

Page 82: Behavior & Specification Driven Development in PHP - #OpenWest

Once we’re done with the implementation, we move on to…

Page 83: Behavior & Specification Driven Development in PHP - #OpenWest

Testing

Page 84: Behavior & Specification Driven Development in PHP - #OpenWest

Once we’re done, running phpspec run should return green

Page 85: Behavior & Specification Driven Development in PHP - #OpenWest

Once phpspec returns green, run behat, which should return green as well

Page 86: Behavior & Specification Driven Development in PHP - #OpenWest

We now know that our new feature is working correctly without needing to open a web browser

Page 87: Behavior & Specification Driven Development in PHP - #OpenWest

PHPSpec gives us confidence that the application logic was implemented correctly.

Page 88: Behavior & Specification Driven Development in PHP - #OpenWest

Behat gives us confidence that the feature is being displayed properly to users.

Page 89: Behavior & Specification Driven Development in PHP - #OpenWest

Success!

Page 90: Behavior & Specification Driven Development in PHP - #OpenWest

The purpose of this talk is to get you hooked on Behat & PHPSpec and show you how easy it is to

get started.

Page 91: Behavior & Specification Driven Development in PHP - #OpenWest

Behat and PHPSpec are both powerful tools

Page 92: Behavior & Specification Driven Development in PHP - #OpenWest

PHPSpec can be used at a very granular level to ensure your application logic works correctly

Page 93: Behavior & Specification Driven Development in PHP - #OpenWest

Next week, setup Behat and PHPSpec on one of your projects and take it for a quick test by

implementing one short feature.

Page 94: Behavior & Specification Driven Development in PHP - #OpenWest

Keep In Touch!

• joind.in/14065

• @JoshuaSWarren

• JoshuaWarren.com