phpspec: practical introduction

41
Practical intro to using PhpSpec Dave Hulbert @dave1010

Upload: david-hulbert

Post on 28-Jan-2018

651 views

Category:

Software


0 download

TRANSCRIPT

Practical intro to using PhpSpec

Dave Hulbert@dave1010

Hello

O/

Dave Hulbert

@dave1010 @wearebase @phpdorset

Contents

● Part 1: TDD in 60 seconds● Part 2: PhpSpec setup● Part 3: Using PhpSpec

What is TDD?

1) Write a failing test (red)

2) Write the minimum amount of code to pass the test (green)

3) Refactor (restructure code, without changing its behaviour)

Why TDD?

● Don't write code that isn't needed● Write fewer bugs● Write more maintainable code● Be more productive

PhpSpec!

Why PhpSpec?

● Modern● Nicer API than PHPUnit● More helpful ● Encourages better code

PhpSpec is not

● For legacy code● For acceptance tests● For functional / UI / integration tests

$ mkdir phpspec-demo$ cd phpspec-demo$ composer require --dev phpspec/phpspec$ alias spec=./vendor/bin/phpspec

Setup

$ vim composer.json $ cat composer.json { "require-dev": { "phpspec/phpspec": "^2.3" }, "autoload": { "psr-0": {"": "src"} }}$ mkdir src$ composer update --lock

Setup

$ spec list...Available commands: describe Creates a specification for a class help Displays help for a command list Lists commands run Runs specifications

Features

Blog example

$ spec desc Blog

Specification for Blog created in /home/dave/phpspec-demo/spec/BlogSpec.php.

Write a spec

Empty spec

Run the spec

Code generation

Code generation

Write 1st example in BlogSpec

Run it

Failing test (red)

100% generated code

Passing example

Green

Refactor

● Rename method/variable● Extract/inline method/variable● Replace loop with collection● Replace conditional with polymorphism● Replace inheritance with delegation

Blogs need some Posts

Give the blog some posts

Tell Blog about PostRepository

Make it pass

PhpSpec MatchersshouldReturn('hello')shouldThrow(\Exception::class) ->duringSetCount(-1)shouldHaveType(User::class)shouldHaveCount(3)shouldBeString()shouldBeInt()shouldBePublished() → isPublished()shouldHaveContent() → hasContent()

Stub

Used to provide data

Messages coming into thesystem under specification (SUS)

Stubs vs Mocks / Spies

Mock / Spy

Used to match behaviour

Messages coming out of the SUS

Talking to other objects

Talking to other objects

Stubs vs Mocks / Spies

Pro tips

● Use interfaces if you want to talk to collaborators

● Refactor the SUS and the specs

● Don't be afraid to delete specs when they're not helpful

● Painful to spec means you have a bad design● Use PhpSpec to design how objects talk to each other (internal

behaviour)

● Use PHPUnit to write tests (eg integration)

● Use Behat to specify external behaviour

Thanks!

Questions / comments

@dave1010