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

Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdfAndrey Devyatkin
 
AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...
AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...
AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...Bert Jan Schrijver
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jNeo4j
 
The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024Artur Skowroński
 
Advantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxAdvantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxRTS corp
 
Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxAS Design & AST.
 
Revolutionize Your Video Editing with InVideo.io: A Comprehensive Review
Revolutionize Your Video Editing with InVideo.io: A Comprehensive ReviewRevolutionize Your Video Editing with InVideo.io: A Comprehensive Review
Revolutionize Your Video Editing with InVideo.io: A Comprehensive Reviewjw364beach
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
OpenMetadata Community Meeting - 4th April, 2024
OpenMetadata Community Meeting - 4th April, 2024OpenMetadata Community Meeting - 4th April, 2024
OpenMetadata Community Meeting - 4th April, 2024OpenMetadata
 
What are the core components of Azure Data Engineer courses.docx
What are the core components of Azure Data Engineer courses.docxWhat are the core components of Azure Data Engineer courses.docx
What are the core components of Azure Data Engineer courses.docxkzayra69
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxUnderstanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxSasikiranMarri
 
ETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBU
ETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBUETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBU
ETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBUsamruddhijedgule2004
 
full course of software engineering mid term.pdf
full course of software engineering mid term.pdffull course of software engineering mid term.pdf
full course of software engineering mid term.pdfAbdul salam
 
Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...
Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...
Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...Piyovi
 
oracle 23c new features for developer and dba
oracle 23c new features for developer and dbaoracle 23c new features for developer and dba
oracle 23c new features for developer and dbaRemote DBA Services
 
Business Analyzopedia - Your Pocket Gita for Business Analysis
Business Analyzopedia - Your Pocket Gita for Business AnalysisBusiness Analyzopedia - Your Pocket Gita for Business Analysis
Business Analyzopedia - Your Pocket Gita for Business AnalysisDEEPRAJ PATHAK
 

Recently uploaded (20)

Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
 
AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...
AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...
AmsterdamJUG April 2024 - Going serverless with Quarkus GraalVM native images...
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
 
The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024
 
Advantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxAdvantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptx
 
Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptx
 
Revolutionize Your Video Editing with InVideo.io: A Comprehensive Review
Revolutionize Your Video Editing with InVideo.io: A Comprehensive ReviewRevolutionize Your Video Editing with InVideo.io: A Comprehensive Review
Revolutionize Your Video Editing with InVideo.io: A Comprehensive Review
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
OpenMetadata Community Meeting - 4th April, 2024
OpenMetadata Community Meeting - 4th April, 2024OpenMetadata Community Meeting - 4th April, 2024
OpenMetadata Community Meeting - 4th April, 2024
 
What are the core components of Azure Data Engineer courses.docx
What are the core components of Azure Data Engineer courses.docxWhat are the core components of Azure Data Engineer courses.docx
What are the core components of Azure Data Engineer courses.docx
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxUnderstanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
 
ETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBU
ETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBUETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBU
ETE PPT.pdf LMMKLMKLMLKMLLMJKBHJBHBNUIHBU
 
full course of software engineering mid term.pdf
full course of software engineering mid term.pdffull course of software engineering mid term.pdf
full course of software engineering mid term.pdf
 
Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...
Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...
Explore the Three Main Types of Logistics - Inbound Logistics, Outbound Logis...
 
oracle 23c new features for developer and dba
oracle 23c new features for developer and dbaoracle 23c new features for developer and dba
oracle 23c new features for developer and dba
 
Business Analyzopedia - Your Pocket Gita for Business Analysis
Business Analyzopedia - Your Pocket Gita for Business AnalysisBusiness Analyzopedia - Your Pocket Gita for Business Analysis
Business Analyzopedia - Your Pocket Gita for Business Analysis
 

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