SlideShare a Scribd company logo
1 of 110
Download to read offline
Practical intro to
Dave Hulbert
@dave1010
I like PhpSpec best because
● Talk to it like a human
● Encourages better code
● Can still use PHPUnit
○ Unit testing existing code
○ Functional / UI / integration tests
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 2
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 3
Contents
1. TDD in 72 seconds
2. Get up and running with PhpSpec
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 4
TDD
in 72 seconds
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 5
We write code that isn't needed
Writing wasteful code leads to:
● Bugs
● Lower productivity
● Difficulty in adding new features
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 6
TDD solves this
● TDD stands for "Tspecification Driven
Design"
● Work out what code would be useful,
before writing it
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 7
How we do TDD
Example of how your code will work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 8
Red
How we do TDD
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 9
Red Green
How we do TDD
Make code simpler and clearer,
without changing behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 10
Red Green Refactor
How we do TDD
Start again
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 11
Red Green Refactor
PhpSpec
setup
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 12
Setup (1 of 2)
$ mkdir demo
$ cd demo
$ mkdir src
$ composer require --dev phpspec/phpspec
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 13
Setup (2 of 2)
$ vim composer.json
...
"autoload": {
"psr-0": {"": "src"}
}
...
$ composer update --lock
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 14
Using
PhpSpec
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 15
How we do TDD
Example of how your code will work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 16
Red
Describe an object
$ vendor/bin/phpspec
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 17
Describe an object
$ vendor/bin/phpspec describe VendingMachine
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 18
Describe an object
$ vendor/bin/phpspec describe VendingMachine
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 19
Describe an object
$ vendor/bin/phpspec describe VendingMachine
Specification for VendingMachine created in
/home/dave/demo/spec/VendingMachineSpec.php.
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 20
Spec is generated automatically
$ tree
├── composer.json
├── composer.lock
├── spec
│ └── VendingMachineSpec.php
├── src
└── vendor
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 21
Spec is generated automatically
$ cat spec/VendingMachineSpec.php
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 22
Spec is generated automatically
$ cat spec/VendingMachineSpec.php
<?php
class VendingMachineSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('VendingMachine');
}
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 23
Run the specification
$ vendor/bin/phpspec run
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 24
Run the specification
$ vendor/bin/phpspec run
...
class VendingMachine does not exist.
1 specs
1 example (1 broken)
Do you want me to create `VendingMachine` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 25
Run the specification
$ vendor/bin/phpspec run
...
class VendingMachine does not exist.
1 specs
1 example (1 broken)
Do you want me to create `VendingMachine` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 26
Get PhpSpec to fix stuff for you
...
Do you want me to create `VendingMachine` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 27
Get PhpSpec to fix stuff for you
...
Do you want me to create `VendingMachine` for you?
[Y/n]
y
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 28
Get PhpSpec to fix stuff for you
Do you want me to create `VendingMachine` for you?
[Y/n]
y
Class VendingMachine created in
/home/dave/demo/src/VendingMachine.php.
1 specs
1 example (1 passed)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 29
Get PhpSpec to fix stuff for you
Do you want me to create `VendingMachine` for you?
[Y/n]
y
Class VendingMachine created in
/home/dave/demo/src/VendingMachine.php.
1 specs
1 example (1 passed)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 30
PhpSpec generates code
$ tree
├── composer.json
├── composer.lock
├── spec
│ └── VendingMachineSpec.php
├── src
│ └── VendingMachine.php
└── vendor
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 31
PhpSpec generates code
$ cat src/VendingMachine.php
<?php
class VendingMachine
{
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 32
How we do TDD
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 33
Red Green
How we do TDD
Make code simpler and clearer,
without changing behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 34
Red Green Refactor
How we do TDD
Start again
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 35
Red Green Refactor
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 36
How we do TDD
Example of how your code will work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 37
Red
Example of how your code will work
Example: it makes funds available
When I call
$this->insertCoin(20);
then
$this->availableFunds() should be 20
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 38
Example of how your code will work
Example: it makes funds available
When I call
$this->insertCoin(20);
then
$this->availableFunds() should be 20
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 39
Example of how your code will work
Example: it makes funds available
When I call
$this->insertCoin(20);
then
$this->availableFunds() should be 20
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 40
Example of how your code will work
Example: it makes funds available
When I call
$this->insertCoin(20);
then
$this->availableFunds() should be 20
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 41
Example of how your code will work
function it_makes_funds_available()
When I call
$this->insertCoin(20);
then
$this->availableFunds() should be 20
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 42
Example of how your code will work
function it_makes_funds_available()
When I call
$this->insertCoin(20);
then
$this->availableFunds() should be 20
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 43
Example of how your code will work
function it_makes_funds_available()
{
$this->insertCoin(20);
$this->availableFunds() should be 20
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 44
Example of how your code will work
function it_makes_funds_available()
{
$this->insertCoin(20);
$this->availableFunds() should be 20
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 45
Example of how your code will work
function it_makes_funds_available()
{
$this->insertCoin(20);
$this->availableFunds()->shouldBe(20);
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 46
Example of how your code will work
function it_makes_funds_available()
{
$this->insertCoin(20);
$this->availableFunds()->shouldBe(20);
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 47
Example of how your code will work
class VendingmachineSpec extends ObjectBehavior
{
...
function it_makes_funds_available()
{
$this->insertCoin(20);
$this->availableFunds()->shouldBe(20);
}
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 48
PhpSpec generates code
$ tree
├── composer.json
├── composer.lock
├── spec
│ └── VendingmachineSpec.php
├── src
│ └── VendingMachine.php
└── vendor
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 49
Run the specification
$ vendor/bin/phpspec run
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 50
Run the specification
$ vendor/bin/phpspec run
Method VendingMachine::insertCoin not found.
Do you want me to create `VendingMachine::insertCoin()
` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 51
Run the specification
$ vendor/bin/phpspec run
Method VendingMachine::insertCoin not found.
Do you want me to create `VendingMachine::insertCoin()
` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 52
Get PhpSpec to fix stuff for you
n
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 53
Get PhpSpec to fix stuff for you
y
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 54
Get PhpSpec to fix stuff for you
y
Method VendingMachine::insertCoin() has been created.
Method VendingMachine::availableFunds not found.
Do you want me to create `VendingMachine::
availableFunds()` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 55
Get PhpSpec to fix stuff for you
y
Method VendingMachine::insertCoin() has been created.
Method VendingMachine::availableFunds not found.
Do you want me to create `VendingMachine::
availableFunds()` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 56
Get PhpSpec to fix stuff for you
y
Method VendingMachine::insertCoin() has been created.
Method VendingMachine::availableFunds not found.
Do you want me to create `VendingMachine::
availableFunds()` for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 57
Get PhpSpec to fix stuff for you
y
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 58
Get PhpSpec to fix stuff for you
y
Method VendingMachine::availableFunds() has been
created.
expected [integer:20], but got null.
1 specs
2 examples (1 passed, 1 failed)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 59
Get PhpSpec to fix stuff for you
y
Method VendingMachine::availableFunds() has been
created.
expected [integer:20], but got null.
1 specs
2 examples (1 passed, 1 failed)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 60
Get PhpSpec to fix stuff for you
y
Method VendingMachine::availableFunds() has been
created.
expected [integer:20], but got null.
1 specs
2 examples (1 passed, 1 failed)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 61
How we do TDD
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 62
Red Green
Automatically fake return values
$ vendor/bin/phpspec run --fake
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 63
Automatically fake return values
$ vendor/bin/phpspec run --fake
Do you want me to make `VendingMachine::
availableFunds()` always return 20 for you?
[Y/n]
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 64
Automatically fake return values
y
Method VendingMachine::availableFunds() has been
modified.
1 specs
2 examples (2 passed)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 65
PhpSpec generates code
$ cat src/VendingMachine.php
<?php
class VendingMachine
{
public function insertCoin($argument1)
{
// TODO: write logic here
}
public function availableFunds()
{
return 20;
}
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 66
public function insertCoin($argument1)
{
// TODO: write logic here
}
public function availableFunds()
{
return 20;
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 67
How we do TDD
Make code simpler and clearer,
without changing behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 68
Red Green Refactor
public function insertCoin($argument1)
{
// TODO: write logic here
}
public function availableFunds()
{
return 20;
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 69
public function insertCoins(int $coin)
{
// TODO: write logic here
}
public function availableFunds() : int
{
return 20;
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 70
How we do TDD
Start again
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 71
Red Green Refactor
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 72
How we do TDD
Example of how your code will work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 73
Red
Use examples to describe behaviour
function it_accumulates_funds()
{
$this->insertCoin(20);
$this->insertCoin(50);
$this->availableFunds()->shouldBe(70);
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 74
Run the specification
$ vendor/bin/phpspec run
...
expected [integer:70], but got 20.
1 specs
3 examples (2 passed, 1 failed)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 75
public function insertCoin(int $coin)
{
// TODO: write logic here
}
public function availableFunds() : int
{
return 20;
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 76
private $funds = 0;
public function insertCoin(int $coin)
{
$this->funds = $this->funds + $coin;
}
public function availableFunds() : int
{
return $this->funds;
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 77
How we do TDD
Make code simpler and clearer,
without changing behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 78
Red Green Refactor
How we do TDD
Start again
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 79
Red Green Refactor
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 80
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 81
function it_uses_funds_when_buying(Catalog $catalog)
{
$catalog->howMuchIsA('kitten')->willReturn(30);
$this->insertCoin(50);
$this->buy('kitten');
$this->availableFunds()->shouldBe(20);
}
Use examples to describe behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 82
function it_uses_funds_when_buying(Catalog $catalog)
{
$catalog->howMuchIsA('kitten')->willReturn(30);
$this->insertCoin(50);
$this->buy('kitten');
$this->availableFunds()->shouldBe(20);
}
Use examples to describe behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 83
function it_uses_funds_when_buying(Catalog $catalog)
{
$catalog->howMuchIsA('kitten')->willReturn(30);
$this->insertCoin(50);
$this->buy('kitten');
$this->availableFunds()->shouldBe(20);
}
Use examples to describe behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 84
function let(Catalog $catalog)
{
$this->beConstructedWith($catalog);
}
Let $this be constructed with
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 85
$ vendor/bin/phpspec run
Would you like me to generate an interface `Catalog`
for you? [Y/n]
interface Catalog
{
}
PhpSpec generates interfaces
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 86
$ vendor/bin/phpspec run
Would you like me to generate a method signature
`Catalog::howMuchIsA()` for you? [Y/n]
interface Catalog
{
public function howMuchIsA($argument1);
}
PhpSpec generates interfaces
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 87
$ vendor/bin/phpspec run
Do you want me to create `VendingMachine::
__construct()` for you? [Y/n]
public function __construct($argument1)
{
// TODO: write logic here
}
PhpSpec generates code
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 88
private $catalog;
public function __construct(Catalog $catalog)
{
$this->catalog = $catalog;
}
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 89
public function buy($argument1)
{
// TODO: write logic here
}
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 90
public function buy(string $item)
{
$this->funds = $this->funds -
$this->catalog->howMuchIsA($item);
}
Minimum code to make it work
public function buy(string $item)
{
$price = $this->catalog->howMuchIsA($item);
$this->funds -= $price;
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 91
Make code simpler and clearer
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 92
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 93
function it_returns_coins(CoinReturn $coinReturn)
{
$this->insertCoin(5);
$this->returnCoins();
$coinReturn->returnPence(5)
->shouldHaveBeenCalled();
}
Use examples to describe behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 94
function it_returns_coins(CoinReturn $coinReturn)
{
$this->insertCoin(5);
$this->returnCoins();
$coinReturn->returnPence(5)
->shouldHaveBeenCalled();
}
Use examples to describe behaviour
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 95
function let(Catalog $catalog, CoinReturn $coinReturn)
{
$this->beConstructedWith($catalog, $coinReturn);
}
Let $this be constructed with
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 96
private $catalog;
public function __construct(
Catalog $catalog
) {
$this->catalog = $catalog;
}
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 97
private $catalog;
private $coinReturn;
public function __construct(
Catalog $catalog, CoinReturn $coinReturn
) {
$this->catalog = $catalog;
$this->coinReturn = $coinReturn;
}
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 98
public function returnCoins()
{
// TODO: write logic here
}
Minimum code to make it work
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 99
public function returnCoins()
{
$this->coinReturn->returnPence($this->funds);
}
Minimum code to make it work
Make code simpler and clearer
public function returnCoins()
{
$this->coinReturn->returnPence($this->funds);
}
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 100
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 101
PhpSpec is a design tool
● Behaviour of objects
● Object collaboration
(sending and receiving messages through interfaces)
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 102
PhpSpec does lots more
● More matchers: ->shouldHaveType()
● Matching exceptions: ->shouldThrow()
● Matching wildcard arguments: Argument::any()
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 103
PhpSpec does even more
● Custom matchers
● Code templates
● Extensions
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 104
4 Pro tips
1.
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 105
Refactor
No refactoring (slow to a standstill)
R G|R_ G_|R__ G__|R___ G___|R______ G______
Refactoring (keep up pace)
R G R|R G R|R G R|R G R|R G R
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 106
4 Pro tips
1. Refactor
2. Use interfaces when calling methods on
other objects
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 107
Refactor
4 Pro tips
1. Refactor
2. Use interfaces when calling methods on
other objects
3. Painful to spec means you have a bad design
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 108
Refactor
4 Pro tips
1. Refactor
2. Use interfaces when calling methods on
other objects
3. Painful to spec means you have a bad design
4. Refactor !
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 109
Refactor
Refactor
Thanks!
● Questions?
● joind.in/talk/f4771
Dave Hulbert, @dave1010
Engineering director, @wearebase
Organiser, @phpdorset
@dave1010 - #phpsc16 - joind.in/talk/f4771 - 110

More Related Content

What's hot

BDD with Behat and Symfony2
BDD with Behat and Symfony2BDD with Behat and Symfony2
BDD with Behat and Symfony2katalisha
 
Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)
Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)
Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)Michael Wales
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusIgnacio Martín
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormMichelangelo van Dam
 
Professional Refactoring
Professional RefactoringProfessional Refactoring
Professional RefactoringMayflower GmbH
 

What's hot (6)

BDD with Behat and Symfony2
BDD with Behat and Symfony2BDD with Behat and Symfony2
BDD with Behat and Symfony2
 
Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)
Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)
Introduction to CodeIgniter (RefreshAugusta, 20 May 2009)
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - Limenius
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStorm
 
Professional Refactoring
Professional RefactoringProfessional Refactoring
Professional Refactoring
 

Viewers also liked

Phpspec tips&amp;tricks
Phpspec tips&amp;tricksPhpspec tips&amp;tricks
Phpspec tips&amp;tricksFilip Golonka
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobCiaranMcNulty
 
Why you should be doing BDD
Why you should be doing BDDWhy you should be doing BDD
Why you should be doing BDDMateusz Zalewski
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
Behaviour driven development aka bdd
Behaviour driven development aka bddBehaviour driven development aka bdd
Behaviour driven development aka bddPrince Gupta
 
Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8Sam Becker
 
Implementing BDD at scale for agile and DevOps teams
Implementing BDD at scale for agile and DevOps teamsImplementing BDD at scale for agile and DevOps teams
Implementing BDD at scale for agile and DevOps teamsLaurent PY
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnitTuan Nguyen
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
Bdd. Automate your requirements
Bdd. Automate your requirementsBdd. Automate your requirements
Bdd. Automate your requirementsjugkaraganda
 
PHPUnit with Mocking and Crawling
PHPUnit with Mocking and CrawlingPHPUnit with Mocking and Crawling
PHPUnit with Mocking and CrawlingTrung x
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentationThanh Robi
 
Wellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testingWellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testingMarçal Berga
 
BDD with Behat and PHPSpec
BDD with Behat and PHPSpecBDD with Behat and PHPSpec
BDD with Behat and PHPSpecRob Ingram
 
Conscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPConscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPCiaranMcNulty
 

Viewers also liked (20)

Phpspec tips&amp;tricks
Phpspec tips&amp;tricksPhpspec tips&amp;tricks
Phpspec tips&amp;tricks
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the Job
 
Why you should be doing BDD
Why you should be doing BDDWhy you should be doing BDD
Why you should be doing BDD
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Automated tests to a REST API
Automated tests to a REST APIAutomated tests to a REST API
Automated tests to a REST API
 
Behaviour driven development aka bdd
Behaviour driven development aka bddBehaviour driven development aka bdd
Behaviour driven development aka bdd
 
Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8
 
Implementing BDD at scale for agile and DevOps teams
Implementing BDD at scale for agile and DevOps teamsImplementing BDD at scale for agile and DevOps teams
Implementing BDD at scale for agile and DevOps teams
 
Phpunit testing
Phpunit testingPhpunit testing
Phpunit testing
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnit
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Bdd. Automate your requirements
Bdd. Automate your requirementsBdd. Automate your requirements
Bdd. Automate your requirements
 
PHPUnit with Mocking and Crawling
PHPUnit with Mocking and CrawlingPHPUnit with Mocking and Crawling
PHPUnit with Mocking and Crawling
 
Automated tests
Automated testsAutomated tests
Automated tests
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
BDD UI testing
BDD UI testingBDD UI testing
BDD UI testing
 
Wellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testingWellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testing
 
99% is not enough
99% is not enough99% is not enough
99% is not enough
 
BDD with Behat and PHPSpec
BDD with Behat and PHPSpecBDD with Behat and PHPSpec
BDD with Behat and PHPSpec
 
Conscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPConscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHP
 

Similar to Practical intro to PhpSpec

Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceJesse Vincent
 
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 - #OpenWestJoshua Warren
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6Wim Godden
 
Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Maurizio Pelizzone
 
Advanced debugging techniques (PHP)
Advanced debugging techniques (PHP)Advanced debugging techniques (PHP)
Advanced debugging techniques (PHP)Patrick Allaert
 
Clear php reference
Clear php referenceClear php reference
Clear php referenceDamien Seguy
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceJesse Vincent
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php PresentationAlan Pinstein
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)Oleg Zinchenko
 
CodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHPCodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHPSteeven Salim
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010singingfish
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
Theory and practice – migrating your legacy code into our modern test drive...
Theory and practice – migrating your  legacy code into our modern test  drive...Theory and practice – migrating your  legacy code into our modern test  drive...
Theory and practice – migrating your legacy code into our modern test drive...Lars Jankowfsky
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015
Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015
Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015Joshua Warren
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоGeeksLab Odessa
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection SmellsMatthias Noback
 
Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8Ran Mizrahi
 

Similar to Practical intro to PhpSpec (20)

Let your tests drive your code
Let your tests drive your codeLet your tests drive your code
Let your tests drive your code
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
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
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6
 
Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress
 
Actions filters
Actions filtersActions filters
Actions filters
 
Advanced debugging techniques (PHP)
Advanced debugging techniques (PHP)Advanced debugging techniques (PHP)
Advanced debugging techniques (PHP)
 
Clear php reference
Clear php referenceClear php reference
Clear php reference
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)
 
CodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHPCodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHP
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Theory and practice – migrating your legacy code into our modern test drive...
Theory and practice – migrating your  legacy code into our modern test  drive...Theory and practice – migrating your  legacy code into our modern test  drive...
Theory and practice – migrating your legacy code into our modern test drive...
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015
Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015
Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection Smells
 
Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8
 

More from Dave Hulbert

Redevelop 2019 - Debugging our biases and intuition in software development
Redevelop 2019 - Debugging our biases and intuition in software developmentRedevelop 2019 - Debugging our biases and intuition in software development
Redevelop 2019 - Debugging our biases and intuition in software developmentDave Hulbert
 
Human brains are stupid
Human brains are stupidHuman brains are stupid
Human brains are stupidDave Hulbert
 
PhpSpec: practical introduction
PhpSpec: practical introductionPhpSpec: practical introduction
PhpSpec: practical introductionDave Hulbert
 
Balancing Technical Debt and Clean Code
Balancing Technical Debt and Clean CodeBalancing Technical Debt and Clean Code
Balancing Technical Debt and Clean CodeDave Hulbert
 
The benefit of sneezing code into an editor vs clean code
The benefit of sneezing code into an editor vs clean codeThe benefit of sneezing code into an editor vs clean code
The benefit of sneezing code into an editor vs clean codeDave Hulbert
 
Silex and Twig (PHP Dorset talk)
Silex and Twig (PHP Dorset talk)Silex and Twig (PHP Dorset talk)
Silex and Twig (PHP Dorset talk)Dave Hulbert
 
Bitcoin The cryptographic currency. Talk at BCBOMO6
Bitcoin The cryptographic currency. Talk at BCBOMO6Bitcoin The cryptographic currency. Talk at BCBOMO6
Bitcoin The cryptographic currency. Talk at BCBOMO6Dave Hulbert
 

More from Dave Hulbert (8)

Redevelop 2019 - Debugging our biases and intuition in software development
Redevelop 2019 - Debugging our biases and intuition in software developmentRedevelop 2019 - Debugging our biases and intuition in software development
Redevelop 2019 - Debugging our biases and intuition in software development
 
Human brains are stupid
Human brains are stupidHuman brains are stupid
Human brains are stupid
 
PhpSpec: practical introduction
PhpSpec: practical introductionPhpSpec: practical introduction
PhpSpec: practical introduction
 
Balancing Technical Debt and Clean Code
Balancing Technical Debt and Clean CodeBalancing Technical Debt and Clean Code
Balancing Technical Debt and Clean Code
 
The benefit of sneezing code into an editor vs clean code
The benefit of sneezing code into an editor vs clean codeThe benefit of sneezing code into an editor vs clean code
The benefit of sneezing code into an editor vs clean code
 
Silex and Twig (PHP Dorset talk)
Silex and Twig (PHP Dorset talk)Silex and Twig (PHP Dorset talk)
Silex and Twig (PHP Dorset talk)
 
Bitcoin The cryptographic currency. Talk at BCBOMO6
Bitcoin The cryptographic currency. Talk at BCBOMO6Bitcoin The cryptographic currency. Talk at BCBOMO6
Bitcoin The cryptographic currency. Talk at BCBOMO6
 
Base Homework
Base HomeworkBase Homework
Base Homework
 

Recently uploaded

DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 

Recently uploaded (20)

DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 

Practical intro to PhpSpec

  • 1. Practical intro to Dave Hulbert @dave1010
  • 2. I like PhpSpec best because ● Talk to it like a human ● Encourages better code ● Can still use PHPUnit ○ Unit testing existing code ○ Functional / UI / integration tests @dave1010 - #phpsc16 - joind.in/talk/f4771 - 2
  • 3. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 3
  • 4. Contents 1. TDD in 72 seconds 2. Get up and running with PhpSpec @dave1010 - #phpsc16 - joind.in/talk/f4771 - 4
  • 5. TDD in 72 seconds @dave1010 - #phpsc16 - joind.in/talk/f4771 - 5
  • 6. We write code that isn't needed Writing wasteful code leads to: ● Bugs ● Lower productivity ● Difficulty in adding new features @dave1010 - #phpsc16 - joind.in/talk/f4771 - 6
  • 7. TDD solves this ● TDD stands for "Tspecification Driven Design" ● Work out what code would be useful, before writing it @dave1010 - #phpsc16 - joind.in/talk/f4771 - 7
  • 8. How we do TDD Example of how your code will work @dave1010 - #phpsc16 - joind.in/talk/f4771 - 8 Red
  • 9. How we do TDD Minimum code to make it work @dave1010 - #phpsc16 - joind.in/talk/f4771 - 9 Red Green
  • 10. How we do TDD Make code simpler and clearer, without changing behaviour @dave1010 - #phpsc16 - joind.in/talk/f4771 - 10 Red Green Refactor
  • 11. How we do TDD Start again @dave1010 - #phpsc16 - joind.in/talk/f4771 - 11 Red Green Refactor
  • 12. PhpSpec setup @dave1010 - #phpsc16 - joind.in/talk/f4771 - 12
  • 13. Setup (1 of 2) $ mkdir demo $ cd demo $ mkdir src $ composer require --dev phpspec/phpspec @dave1010 - #phpsc16 - joind.in/talk/f4771 - 13
  • 14. Setup (2 of 2) $ vim composer.json ... "autoload": { "psr-0": {"": "src"} } ... $ composer update --lock @dave1010 - #phpsc16 - joind.in/talk/f4771 - 14
  • 15. Using PhpSpec @dave1010 - #phpsc16 - joind.in/talk/f4771 - 15
  • 16. How we do TDD Example of how your code will work @dave1010 - #phpsc16 - joind.in/talk/f4771 - 16 Red
  • 17. Describe an object $ vendor/bin/phpspec @dave1010 - #phpsc16 - joind.in/talk/f4771 - 17
  • 18. Describe an object $ vendor/bin/phpspec describe VendingMachine @dave1010 - #phpsc16 - joind.in/talk/f4771 - 18
  • 19. Describe an object $ vendor/bin/phpspec describe VendingMachine @dave1010 - #phpsc16 - joind.in/talk/f4771 - 19
  • 20. Describe an object $ vendor/bin/phpspec describe VendingMachine Specification for VendingMachine created in /home/dave/demo/spec/VendingMachineSpec.php. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 20
  • 21. Spec is generated automatically $ tree ├── composer.json ├── composer.lock ├── spec │ └── VendingMachineSpec.php ├── src └── vendor @dave1010 - #phpsc16 - joind.in/talk/f4771 - 21
  • 22. Spec is generated automatically $ cat spec/VendingMachineSpec.php @dave1010 - #phpsc16 - joind.in/talk/f4771 - 22
  • 23. Spec is generated automatically $ cat spec/VendingMachineSpec.php <?php class VendingMachineSpec extends ObjectBehavior { function it_is_initializable() { $this->shouldHaveType('VendingMachine'); } } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 23
  • 24. Run the specification $ vendor/bin/phpspec run @dave1010 - #phpsc16 - joind.in/talk/f4771 - 24
  • 25. Run the specification $ vendor/bin/phpspec run ... class VendingMachine does not exist. 1 specs 1 example (1 broken) Do you want me to create `VendingMachine` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 25
  • 26. Run the specification $ vendor/bin/phpspec run ... class VendingMachine does not exist. 1 specs 1 example (1 broken) Do you want me to create `VendingMachine` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 26
  • 27. Get PhpSpec to fix stuff for you ... Do you want me to create `VendingMachine` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 27
  • 28. Get PhpSpec to fix stuff for you ... Do you want me to create `VendingMachine` for you? [Y/n] y @dave1010 - #phpsc16 - joind.in/talk/f4771 - 28
  • 29. Get PhpSpec to fix stuff for you Do you want me to create `VendingMachine` for you? [Y/n] y Class VendingMachine created in /home/dave/demo/src/VendingMachine.php. 1 specs 1 example (1 passed) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 29
  • 30. Get PhpSpec to fix stuff for you Do you want me to create `VendingMachine` for you? [Y/n] y Class VendingMachine created in /home/dave/demo/src/VendingMachine.php. 1 specs 1 example (1 passed) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 30
  • 31. PhpSpec generates code $ tree ├── composer.json ├── composer.lock ├── spec │ └── VendingMachineSpec.php ├── src │ └── VendingMachine.php └── vendor @dave1010 - #phpsc16 - joind.in/talk/f4771 - 31
  • 32. PhpSpec generates code $ cat src/VendingMachine.php <?php class VendingMachine { } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 32
  • 33. How we do TDD Minimum code to make it work @dave1010 - #phpsc16 - joind.in/talk/f4771 - 33 Red Green
  • 34. How we do TDD Make code simpler and clearer, without changing behaviour @dave1010 - #phpsc16 - joind.in/talk/f4771 - 34 Red Green Refactor
  • 35. How we do TDD Start again @dave1010 - #phpsc16 - joind.in/talk/f4771 - 35 Red Green Refactor
  • 36. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 36
  • 37. How we do TDD Example of how your code will work @dave1010 - #phpsc16 - joind.in/talk/f4771 - 37 Red
  • 38. Example of how your code will work Example: it makes funds available When I call $this->insertCoin(20); then $this->availableFunds() should be 20 @dave1010 - #phpsc16 - joind.in/talk/f4771 - 38
  • 39. Example of how your code will work Example: it makes funds available When I call $this->insertCoin(20); then $this->availableFunds() should be 20 @dave1010 - #phpsc16 - joind.in/talk/f4771 - 39
  • 40. Example of how your code will work Example: it makes funds available When I call $this->insertCoin(20); then $this->availableFunds() should be 20 @dave1010 - #phpsc16 - joind.in/talk/f4771 - 40
  • 41. Example of how your code will work Example: it makes funds available When I call $this->insertCoin(20); then $this->availableFunds() should be 20 @dave1010 - #phpsc16 - joind.in/talk/f4771 - 41
  • 42. Example of how your code will work function it_makes_funds_available() When I call $this->insertCoin(20); then $this->availableFunds() should be 20 @dave1010 - #phpsc16 - joind.in/talk/f4771 - 42
  • 43. Example of how your code will work function it_makes_funds_available() When I call $this->insertCoin(20); then $this->availableFunds() should be 20 @dave1010 - #phpsc16 - joind.in/talk/f4771 - 43
  • 44. Example of how your code will work function it_makes_funds_available() { $this->insertCoin(20); $this->availableFunds() should be 20 } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 44
  • 45. Example of how your code will work function it_makes_funds_available() { $this->insertCoin(20); $this->availableFunds() should be 20 } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 45
  • 46. Example of how your code will work function it_makes_funds_available() { $this->insertCoin(20); $this->availableFunds()->shouldBe(20); } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 46
  • 47. Example of how your code will work function it_makes_funds_available() { $this->insertCoin(20); $this->availableFunds()->shouldBe(20); } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 47
  • 48. Example of how your code will work class VendingmachineSpec extends ObjectBehavior { ... function it_makes_funds_available() { $this->insertCoin(20); $this->availableFunds()->shouldBe(20); } } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 48
  • 49. PhpSpec generates code $ tree ├── composer.json ├── composer.lock ├── spec │ └── VendingmachineSpec.php ├── src │ └── VendingMachine.php └── vendor @dave1010 - #phpsc16 - joind.in/talk/f4771 - 49
  • 50. Run the specification $ vendor/bin/phpspec run @dave1010 - #phpsc16 - joind.in/talk/f4771 - 50
  • 51. Run the specification $ vendor/bin/phpspec run Method VendingMachine::insertCoin not found. Do you want me to create `VendingMachine::insertCoin() ` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 51
  • 52. Run the specification $ vendor/bin/phpspec run Method VendingMachine::insertCoin not found. Do you want me to create `VendingMachine::insertCoin() ` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 52
  • 53. Get PhpSpec to fix stuff for you n @dave1010 - #phpsc16 - joind.in/talk/f4771 - 53
  • 54. Get PhpSpec to fix stuff for you y @dave1010 - #phpsc16 - joind.in/talk/f4771 - 54
  • 55. Get PhpSpec to fix stuff for you y Method VendingMachine::insertCoin() has been created. Method VendingMachine::availableFunds not found. Do you want me to create `VendingMachine:: availableFunds()` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 55
  • 56. Get PhpSpec to fix stuff for you y Method VendingMachine::insertCoin() has been created. Method VendingMachine::availableFunds not found. Do you want me to create `VendingMachine:: availableFunds()` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 56
  • 57. Get PhpSpec to fix stuff for you y Method VendingMachine::insertCoin() has been created. Method VendingMachine::availableFunds not found. Do you want me to create `VendingMachine:: availableFunds()` for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 57
  • 58. Get PhpSpec to fix stuff for you y @dave1010 - #phpsc16 - joind.in/talk/f4771 - 58
  • 59. Get PhpSpec to fix stuff for you y Method VendingMachine::availableFunds() has been created. expected [integer:20], but got null. 1 specs 2 examples (1 passed, 1 failed) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 59
  • 60. Get PhpSpec to fix stuff for you y Method VendingMachine::availableFunds() has been created. expected [integer:20], but got null. 1 specs 2 examples (1 passed, 1 failed) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 60
  • 61. Get PhpSpec to fix stuff for you y Method VendingMachine::availableFunds() has been created. expected [integer:20], but got null. 1 specs 2 examples (1 passed, 1 failed) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 61
  • 62. How we do TDD Minimum code to make it work @dave1010 - #phpsc16 - joind.in/talk/f4771 - 62 Red Green
  • 63. Automatically fake return values $ vendor/bin/phpspec run --fake @dave1010 - #phpsc16 - joind.in/talk/f4771 - 63
  • 64. Automatically fake return values $ vendor/bin/phpspec run --fake Do you want me to make `VendingMachine:: availableFunds()` always return 20 for you? [Y/n] @dave1010 - #phpsc16 - joind.in/talk/f4771 - 64
  • 65. Automatically fake return values y Method VendingMachine::availableFunds() has been modified. 1 specs 2 examples (2 passed) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 65
  • 66. PhpSpec generates code $ cat src/VendingMachine.php <?php class VendingMachine { public function insertCoin($argument1) { // TODO: write logic here } public function availableFunds() { return 20; } } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 66
  • 67. public function insertCoin($argument1) { // TODO: write logic here } public function availableFunds() { return 20; } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 67
  • 68. How we do TDD Make code simpler and clearer, without changing behaviour @dave1010 - #phpsc16 - joind.in/talk/f4771 - 68 Red Green Refactor
  • 69. public function insertCoin($argument1) { // TODO: write logic here } public function availableFunds() { return 20; } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 69
  • 70. public function insertCoins(int $coin) { // TODO: write logic here } public function availableFunds() : int { return 20; } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 70
  • 71. How we do TDD Start again @dave1010 - #phpsc16 - joind.in/talk/f4771 - 71 Red Green Refactor
  • 72. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 72
  • 73. How we do TDD Example of how your code will work @dave1010 - #phpsc16 - joind.in/talk/f4771 - 73 Red
  • 74. Use examples to describe behaviour function it_accumulates_funds() { $this->insertCoin(20); $this->insertCoin(50); $this->availableFunds()->shouldBe(70); } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 74
  • 75. Run the specification $ vendor/bin/phpspec run ... expected [integer:70], but got 20. 1 specs 3 examples (2 passed, 1 failed) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 75
  • 76. public function insertCoin(int $coin) { // TODO: write logic here } public function availableFunds() : int { return 20; } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 76
  • 77. private $funds = 0; public function insertCoin(int $coin) { $this->funds = $this->funds + $coin; } public function availableFunds() : int { return $this->funds; } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 77
  • 78. How we do TDD Make code simpler and clearer, without changing behaviour @dave1010 - #phpsc16 - joind.in/talk/f4771 - 78 Red Green Refactor
  • 79. How we do TDD Start again @dave1010 - #phpsc16 - joind.in/talk/f4771 - 79 Red Green Refactor
  • 80. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 80
  • 81. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 81 function it_uses_funds_when_buying(Catalog $catalog) { $catalog->howMuchIsA('kitten')->willReturn(30); $this->insertCoin(50); $this->buy('kitten'); $this->availableFunds()->shouldBe(20); } Use examples to describe behaviour
  • 82. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 82 function it_uses_funds_when_buying(Catalog $catalog) { $catalog->howMuchIsA('kitten')->willReturn(30); $this->insertCoin(50); $this->buy('kitten'); $this->availableFunds()->shouldBe(20); } Use examples to describe behaviour
  • 83. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 83 function it_uses_funds_when_buying(Catalog $catalog) { $catalog->howMuchIsA('kitten')->willReturn(30); $this->insertCoin(50); $this->buy('kitten'); $this->availableFunds()->shouldBe(20); } Use examples to describe behaviour
  • 84. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 84 function let(Catalog $catalog) { $this->beConstructedWith($catalog); } Let $this be constructed with
  • 85. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 85 $ vendor/bin/phpspec run Would you like me to generate an interface `Catalog` for you? [Y/n] interface Catalog { } PhpSpec generates interfaces
  • 86. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 86 $ vendor/bin/phpspec run Would you like me to generate a method signature `Catalog::howMuchIsA()` for you? [Y/n] interface Catalog { public function howMuchIsA($argument1); } PhpSpec generates interfaces
  • 87. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 87 $ vendor/bin/phpspec run Do you want me to create `VendingMachine:: __construct()` for you? [Y/n] public function __construct($argument1) { // TODO: write logic here } PhpSpec generates code
  • 88. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 88 private $catalog; public function __construct(Catalog $catalog) { $this->catalog = $catalog; } Minimum code to make it work
  • 89. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 89 public function buy($argument1) { // TODO: write logic here } Minimum code to make it work
  • 90. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 90 public function buy(string $item) { $this->funds = $this->funds - $this->catalog->howMuchIsA($item); } Minimum code to make it work
  • 91. public function buy(string $item) { $price = $this->catalog->howMuchIsA($item); $this->funds -= $price; } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 91 Make code simpler and clearer
  • 92. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 92
  • 93. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 93 function it_returns_coins(CoinReturn $coinReturn) { $this->insertCoin(5); $this->returnCoins(); $coinReturn->returnPence(5) ->shouldHaveBeenCalled(); } Use examples to describe behaviour
  • 94. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 94 function it_returns_coins(CoinReturn $coinReturn) { $this->insertCoin(5); $this->returnCoins(); $coinReturn->returnPence(5) ->shouldHaveBeenCalled(); } Use examples to describe behaviour
  • 95. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 95 function let(Catalog $catalog, CoinReturn $coinReturn) { $this->beConstructedWith($catalog, $coinReturn); } Let $this be constructed with
  • 96. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 96 private $catalog; public function __construct( Catalog $catalog ) { $this->catalog = $catalog; } Minimum code to make it work
  • 97. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 97 private $catalog; private $coinReturn; public function __construct( Catalog $catalog, CoinReturn $coinReturn ) { $this->catalog = $catalog; $this->coinReturn = $coinReturn; } Minimum code to make it work
  • 98. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 98 public function returnCoins() { // TODO: write logic here } Minimum code to make it work
  • 99. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 99 public function returnCoins() { $this->coinReturn->returnPence($this->funds); } Minimum code to make it work
  • 100. Make code simpler and clearer public function returnCoins() { $this->coinReturn->returnPence($this->funds); } @dave1010 - #phpsc16 - joind.in/talk/f4771 - 100
  • 101. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 101
  • 102. PhpSpec is a design tool ● Behaviour of objects ● Object collaboration (sending and receiving messages through interfaces) @dave1010 - #phpsc16 - joind.in/talk/f4771 - 102
  • 103. PhpSpec does lots more ● More matchers: ->shouldHaveType() ● Matching exceptions: ->shouldThrow() ● Matching wildcard arguments: Argument::any() @dave1010 - #phpsc16 - joind.in/talk/f4771 - 103
  • 104. PhpSpec does even more ● Custom matchers ● Code templates ● Extensions @dave1010 - #phpsc16 - joind.in/talk/f4771 - 104
  • 105. 4 Pro tips 1. @dave1010 - #phpsc16 - joind.in/talk/f4771 - 105
  • 106. Refactor No refactoring (slow to a standstill) R G|R_ G_|R__ G__|R___ G___|R______ G______ Refactoring (keep up pace) R G R|R G R|R G R|R G R|R G R @dave1010 - #phpsc16 - joind.in/talk/f4771 - 106
  • 107. 4 Pro tips 1. Refactor 2. Use interfaces when calling methods on other objects @dave1010 - #phpsc16 - joind.in/talk/f4771 - 107 Refactor
  • 108. 4 Pro tips 1. Refactor 2. Use interfaces when calling methods on other objects 3. Painful to spec means you have a bad design @dave1010 - #phpsc16 - joind.in/talk/f4771 - 108 Refactor
  • 109. 4 Pro tips 1. Refactor 2. Use interfaces when calling methods on other objects 3. Painful to spec means you have a bad design 4. Refactor ! @dave1010 - #phpsc16 - joind.in/talk/f4771 - 109 Refactor Refactor
  • 110. Thanks! ● Questions? ● joind.in/talk/f4771 Dave Hulbert, @dave1010 Engineering director, @wearebase Organiser, @phpdorset @dave1010 - #phpsc16 - joind.in/talk/f4771 - 110