November Camp - Spec BDD with PHPSpec 2

73
Spec BDD WITH PHPSPEC 2 N ovember C amp S tockholm 22/11/2013 flickr.com/arnolouise/3252847397/

description

My slides on PHPSpec 2 from Symfony November Camp Stockholm. www.symfony.se/november-camp/

Transcript of November Camp - Spec BDD with PHPSpec 2

Page 1: November Camp - Spec BDD with PHPSpec 2

Spec BDD WITH PHPSPEC 2

November Camp Stockholm 22/11/2013flickr.com/arnolouise/3252847397/

Page 2: November Camp - Spec BDD with PHPSpec 2

Kacper Gunia @cakper

Software Engineer @SensioLabsUK

Symfony Certified Developer

Polish Symfony Community

Silesian PHP User Group

Page 3: November Camp - Spec BDD with PHPSpec 2

Software Quality

flickr.com/adforce1/2462794123/

Page 4: November Camp - Spec BDD with PHPSpec 2

INTERNAL Quality

flickr.com/ensh/5084228263/

Page 5: November Camp - Spec BDD with PHPSpec 2

EXTERNAL Quality

flickr.com/arselectronicacenter/8695704856/

Page 6: November Camp - Spec BDD with PHPSpec 2

INTERNAL vs

EXTERNAL

Page 7: November Camp - Spec BDD with PHPSpec 2

It’s NOT VS

Page 8: November Camp - Spec BDD with PHPSpec 2

It’s AND

Page 9: November Camp - Spec BDD with PHPSpec 2

InnerNAL And

EXTERNAL

flickr.com/pmiaki/6768810175/

Page 10: November Camp - Spec BDD with PHPSpec 2

How to ensure quality?

Test

Page 11: November Camp - Spec BDD with PHPSpec 2

How to test?

Automate

Page 12: November Camp - Spec BDD with PHPSpec 2

So you WRITE your code…

Page 13: November Camp - Spec BDD with PHPSpec 2

…and your tests

Page 14: November Camp - Spec BDD with PHPSpec 2

HOW DARE YOU?

Page 15: November Camp - Spec BDD with PHPSpec 2

are YOU sure Tests ARE

correct?

Page 16: November Camp - Spec BDD with PHPSpec 2

Test Driven Development

Page 17: November Camp - Spec BDD with PHPSpec 2

Red

GreenRefactor

Page 18: November Camp - Spec BDD with PHPSpec 2

BUT…

Page 19: November Camp - Spec BDD with PHPSpec 2

flickr.com/ucumari/580865728/

test Something that doesn’t

exists?

Page 20: November Camp - Spec BDD with PHPSpec 2

Test In TDD means

Specification

Page 21: November Camp - Spec BDD with PHPSpec 2

Specification describes

Behavior

Page 22: November Camp - Spec BDD with PHPSpec 2

BeHavior Driven Development

Page 23: November Camp - Spec BDD with PHPSpec 2

Naming Conventions

Tools

IMPROVED

Page 24: November Camp - Spec BDD with PHPSpec 2

TDD v2.0

‘TDD DONE RIGHT’

Page 25: November Camp - Spec BDD with PHPSpec 2

Story BDD &

Spec BDD

Page 26: November Camp - Spec BDD with PHPSpec 2

description of business-targeted

application behavior

STORY BDD

Page 27: November Camp - Spec BDD with PHPSpec 2

specification for low-level

implementation

SPEC BDD

Page 28: November Camp - Spec BDD with PHPSpec 2

Failing Scenario

Failing Spec

RefacTORPassing

Spec

Passing Scenario

Story BDD

SPEC BDD

Page 29: November Camp - Spec BDD with PHPSpec 2

Failing Scenario

Failing Spec

RefacTORPassing

Spec

Passing Scenario

External quality

INTERNAL QUALITY

Page 30: November Camp - Spec BDD with PHPSpec 2

BEHAT (Story BDD)

& PHPSpec

(Spec BDD)

Page 31: November Camp - Spec BDD with PHPSpec 2

BEHAT (Story BDD)

& PHPSpec

(Spec BDD)

Page 32: November Camp - Spec BDD with PHPSpec 2

FRAMEWORK SPEC BDD CREATED BY

@_MD & @EVERZET

PHPSPEC 2

Page 33: November Camp - Spec BDD with PHPSpec 2

Bundled With Mocking Framework - Prophecy

PHPSPEC 2

Page 34: November Camp - Spec BDD with PHPSpec 2

BUT…

Page 35: November Camp - Spec BDD with PHPSpec 2

WHY NOT PHPUNIT?

Page 36: November Camp - Spec BDD with PHPSpec 2

PHPUNIT Is A

TESTING TOOL

Page 37: November Camp - Spec BDD with PHPSpec 2

PHPSPEC Is A

DESIGN TOOL

Page 38: November Camp - Spec BDD with PHPSpec 2

EVIDENCE?

Page 39: November Camp - Spec BDD with PHPSpec 2

PHPUNIT

Page 40: November Camp - Spec BDD with PHPSpec 2

PHPSPEC

Page 41: November Camp - Spec BDD with PHPSpec 2

Differences?

Page 42: November Camp - Spec BDD with PHPSpec 2

tEST Suite

Specification

Page 43: November Camp - Spec BDD with PHPSpec 2

tEST

EXAMPLE

Page 44: November Camp - Spec BDD with PHPSpec 2

Assertion

expectation

Page 45: November Camp - Spec BDD with PHPSpec 2
Page 46: November Camp - Spec BDD with PHPSpec 2

class  MovieSpec  extends  ObjectBehavior  {          function  it_returns_movie_title()          {                  $this-­‐>getTitle()                            -­‐>shouldReturn('Star  Wars');          }  }

Page 47: November Camp - Spec BDD with PHPSpec 2

Matchers

Page 48: November Camp - Spec BDD with PHPSpec 2

IDENTITY MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_is_a_great_movie()      {          $this-­‐>getRating()-­‐>shouldBe(5);                        $this-­‐>getTitle()                    -­‐>shouldBeEqualTo('Star  Wars');                            $this-­‐>getReleaseDate()                    -­‐>shouldReturn(233366400);      }  }

Page 49: November Camp - Spec BDD with PHPSpec 2

COMPARISON MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_is_great_movie()      {          $this-­‐>getRating()-­‐>shouldBeLike('5');      }  }

Page 50: November Camp - Spec BDD with PHPSpec 2

THROW MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_does_not_allow_negative_ratings()      {          $this              -­‐>shouldThrow('\InvalidArgumentException')            -­‐>duringSetRating(-­‐3);      }  }

Page 51: November Camp - Spec BDD with PHPSpec 2

THROW MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_does_not_allow_negative_ratings()      {          $this-­‐>shouldThrow(                  new  \InvalidArgumentException(                      "Invalid  rating”                  )              )-­‐>during('setRating',  array(-­‐3));          }  }

Page 52: November Camp - Spec BDD with PHPSpec 2

TYPE MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_is_a_movie()      {          $this-­‐>shouldHaveType('Movie');          $this-­‐>shouldReturnAnInstanceOf('Movie');          $this-­‐>shouldBeAnInstanceOf('Movie');          $this-­‐>shouldImplement('Movie');      }  }

Page 53: November Camp - Spec BDD with PHPSpec 2

OBJECT-STATE MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_is_available_on_cinemas()      {          $this-­‐>shouldBeAvailableOnCinemas();      }  }  !class  Movie  {      public  function  isAvailableOnCinemas()      {  return  true;  }<?php  }

Page 54: November Camp - Spec BDD with PHPSpec 2

OBJECT-STATE MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_has_a_soundtrack()      {          $this-­‐>shouldHaveSoundtrack();      }  }  !class  Movie  {      public  function  hasSoundtrack()      {  return  true;  }  }

Page 55: November Camp - Spec BDD with PHPSpec 2

COUNT MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_has_one_director()      {          $this-­‐>getDirectors()-­‐>shouldHaveCount(1);      }  }

Page 56: November Camp - Spec BDD with PHPSpec 2

SCALAR MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_has_a_string_as_title()      {          $this-­‐>getTitle()-­‐>shouldBeString();      }  !    function  it_has_an_array_as_cast()      {          $this-­‐>getCast()-­‐>shouldBeArray();      }  }

Page 57: November Camp - Spec BDD with PHPSpec 2

INLINE MATCHER

class  MovieSpec  extends  ObjectBehavior  {      function  it_has_default_options()      {          $this-­‐>getOptions()-­‐>shouldHaveKey('username');      }  !    public  function  getMatchers()      {          return  [              'haveKey'  =>  function($subject,  $key)  {                  return  array_key_exists($key,  $subject);              }          ];      }  }

Page 58: November Camp - Spec BDD with PHPSpec 2

BUT…

Page 59: November Camp - Spec BDD with PHPSpec 2

Software Design is about

Messaging

Page 60: November Camp - Spec BDD with PHPSpec 2

TEST DOUBLES

Page 61: November Camp - Spec BDD with PHPSpec 2

DUMMIES

class  CinemaSpec  extends  ObjectBehavior  {      /**        *  @param  BoxOffice  $boxOffice        */      function  it_is_a_cinema($boxOffice)      {          $this-­‐>beConstructedWith($boxOffice);          $this-­‐>shouldHaveType('Cinema');      }  }

Page 62: November Camp - Spec BDD with PHPSpec 2

STUBS

class  CinemaSpec  extends  ObjectBehavior  {      /**        *  @param  Movie  $movie        */      function  it_displays_big_movie_title($movie)      {          $movie-­‐>getTitle()                      -­‐>willReturn('Star  Wars’);  !        $this-­‐>displayTitle($movie)                    -­‐>shouldReturn('<h1>Star  Wars</h1>');      }  }

Page 63: November Camp - Spec BDD with PHPSpec 2

MOCKS

class  CinemaSpec  extends  ObjectBehavior  {      /**        *  @param  DvdPlayer  $dvdPlayer        *  @param  MovieDisc  $movieDisc        */      function  it_plays_movie($dvdPlayer,  $movieDisc)      {          $dvdPlayer-­‐>playDisc($movieDisc)                              -­‐>shouldBeCalled();  !        $this-­‐>setPlayer($dvdPlayer);          $this-­‐>playMovie($movieDisc);      }  }

Page 64: November Camp - Spec BDD with PHPSpec 2

SPIES

class  CinemaSpec  extends  ObjectBehavior  {      /**        *  @param  DvdPlayer  $dvdPlayer        *  @param  MovieDisc  $movieDisc        */      function  it_plays_movie($dvdPlayer,  $movieDisc)      {          $this-­‐>setPlayer($dvdPlayer);          $this-­‐>playMovie($movieDisc);  !        $dvdPlayer-­‐>playDisc($movieDisc)                              -­‐>shouldHaveBeenCalled();      }  }

Page 65: November Camp - Spec BDD with PHPSpec 2

SET UP & TEAR DOWN

class  CinemaSpec  extends  ObjectBehavior  {          /**            *  @param  BoxOffice  $boxOffice            */          function  let($boxOffice)          {                  $this-­‐>beConstructedWith($boxOffice);          }  !        function  letGo()          {                  $this-­‐>tellPeopleToGoHome();          }  }

Page 66: November Camp - Spec BDD with PHPSpec 2

BUT…

Page 67: November Camp - Spec BDD with PHPSpec 2

HOW TO ‘DESIGN’?

Page 68: November Camp - Spec BDD with PHPSpec 2

1. WRITE NO PRODUCTION CODE EXCEPT TO PASS A FAILING TEST

2. WRITE ONLY ENOUGH OF A TEST TO DEMONSTRATE A FAILURE

3. WRITE ONLY ENOUGH PRODUCTION CODE TO PASS A TEST

THREE RULES OF TDD

Page 69: November Camp - Spec BDD with PHPSpec 2

1. Passes all the tests 2. Express every idea we need to

express 3. Contains no duplication 4. Minimized the number of classes,

methods and other moving parts

4 RULES OF SIMPLE DESIGN

Page 70: November Camp - Spec BDD with PHPSpec 2

1. CODE SMELLS 2. TEST SMELLS 3. DRY SMELLS 4. …and others

SMELLS

Page 71: November Camp - Spec BDD with PHPSpec 2

And?

Page 72: November Camp - Spec BDD with PHPSpec 2

QUICK START

{          "require-­‐dev":  {                  "phpspec/phpspec":  "2.0.*@dev"          },          "config":  {                  "bin-­‐dir":  "bin"          },          "autoload":  {"psr-­‐0":  {"":  "src"}}  }

http://phpspec.net/

Page 73: November Camp - Spec BDD with PHPSpec 2

THANK YOU!

JOIND.IN/10130

?