Spec BDD with PHPSpec
Quality?
Quality
- External – what matters most for the customer.
- Internal – the maintainability of the source code.
Development Cycle
Refactoring
The process of restructuring existing code without changing external behavior.
TDD vs Spec BDD
Test
Specify
Test Method
Example
Assert
Expect
The difference is the language!
PHPUnit vs PHPSpec
$this->assertEquals(0, $result); // PHPUnit
$result->shoulBe(0); // PHPSpec
It's not only about the language
$ phpunit CommandTest.php
PHPUnit 3.7.28 by Sebastian Bergmann.
PHP Fatal error: Class 'Command' not found
in Tests/TestCommand.php on line 8
public function testCanAbortUpload()
{
$transfer = $this->getMockedTransfer();
$model = $this->getMockBuilder('Guzzle\Service\Resource\Model')
->disableOriginalConstructor()
->getMock();
$command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
->disableOriginalConstructor()
->getMock();
$command->expects($this->any())
->method('getResult')
->will($this->returnValue($model));
$transfer->expects($this->any())
->method('getAbortCommand')
->will($this->returnValue($command));
$transfer->abort();
$this->assertTrue($this->readAttribute($transfer, 'stopped'));
}
I want tool that is
- My friend
- Fun to use
- Does not get in the way
What is PHPSpec?
PHPSpec is a development tool, designed to help you achieve clean and working PHP code by using a technique derived from test-first development called (spec) behaviour driven development, or SpecBDD.
phpspec.net
Matchers
- Identity
- Comparison
- Throw
- Type
- ObjectState
- Count
- Scalar
- Inline
Identity
$this->getRating()->shouldBe(5);
$this->getTitle()->shouldBeEqualTo("Star Wars");
$this->getReleaseDate()->shouldReturn(233366400);
===
Comparison
$this->getRating()->shouldBeLike('5');
==
Throw
$this->shouldThrow('\InvalidArgumentException')->duringSetRating(-3);
$this->shouldThrow('\InvalidArgumentException')->during('setRating', array(-3));
$this->shouldThrow(new \InvalidArgumentException("Invalid rating"))->during('setRating', array(-3));
Type
$this->shouldHaveType('Movie');
$this->shouldReturnAnInstanceOf('Movie');
$this->shouldBeAnInstanceOf('Movie');
$this->shouldImplement('Movie');
Object State
$this->shouldBeAvailableOnCinemas();
$this->shouldHaveSoundtrack();
Count
$this->getItems()->shouldHaveCount(3);
Scalar
$this->getTitle()->shouldBeString();
$this->getPrice()->shouldBeFloat();
$this->getItems()->shouldBeArray();
Inline
class MovieSpec extends ObjectBehavior
{
function it_should_have_some_specific_options_by_default()
{
$this->getOptions()->shouldHaveKey('username');
$this->getOptions()->shouldHaveValue('diegoholiveira');
}
public function getMatchers()
{
return [
'haveKey' => function($subject, $key) {
return array_key_exists($key, $subject);
},
'haveValue' => function($subject, $value) {
return in_array($value, $subject);
},
];
}
}
Formatters
- progress
- html
- pretty
- junit
- dot
Stubs
$converter
->convert(80, 'USD')
->willReturn(106.54)
;
Mocks
$converter
->convert(80, 'USD')
->shouldBeCalled()
;
Let and let go
class ConverterSpec extends ObjectBehavior
{
function let(ExchangeRate $exchangeRate)
{
$this->beConstructedWith($exchangeRate);
}
function letgo()
{
// release any resource
}
}
Templates
- specification
- class
- method
Templates
- {project_directory}/.phpspec/{template_name}.tpl
- {home_directory}/.phpspec/{template_name}.tpl
- Use the default template
Templates
- %filepath% the file path of the class
- %name% the class name
- %namespace% the class namespace
- %namespace_block% the formatted class namespace
Templates
<?php
/**
* This file is part of the T-Day talk.
*
* @author PHPSpec developers
*/
namespace %namespace%;
class %name%
{
}
.phpspec/class.tpl
Spec BDD with PHPSpec
By Saša Stamenković
Spec BDD with PHPSpec
- 4,157