TDD, a starting point

Preview:

DESCRIPTION

A PHP perspective on why start using tdd in a PHP project

Citation preview

TDD, a starting pointA PHP perspective...

Francesco Fullone, Ideato.itff AT ideato.it

Who am I

Francesco Fullone aka Fullo

- PHP developer since 1999

- President

- and Open Source Evangelist

- CEO @

- Nerd and geek

TDD ?

Test Driven Development

Why test the code?

Developers are humans, Humans are error-prone.

Software changes and grows.

We need to confirm that the code is working after any changes.

xUNIT TDD approach.

PHPUnit.de

Easy to writeEasy to read

IsolatedComposable

An example: The bowling kata

(courtesy grabbed from Sebastian Bergmann)

10 frames

2 rolls to knock down the 10 pins Score for a frame is the number of pins knocked down

Bonus for a spare (all 10 pins knocked down in two tries): next roll Bonus for a strike (all 10 pins knocked down in one try): next two rolls Extra rolls for spare or strike in the 10th frame

<?phprequire_once 'BowlingGame.php';

class BowlingGameTest extends PHPUnit_Framework_TestCase{

}?>

<?phprequire_once 'BowlingGame.php';

class BowlingGameTest extends PHPUnit_Framework_TestCase{

public function testScoreForGutterGameIs0(){

}

}

<?phprequire_once 'BowlingGame.php';

class BowlingGameTest extends PHPUnit_Framework_TestCase{

public function testScoreForGutterGameIs0(){

$game = new BowlingGame;for ($i = 0; $i < 20; $i++) {

$game->roll(0);}

$this->assertEquals(0, $game->score());}

}

fullo@teletran ~ % phpunit --skeleton-class BowlingGameTestPHPUnit 3.4.2 by Sebastian Bergmann.Wrote skeleton for "BowlingGame" to "BowlingGame.php".

<?phpclass BowlingGame{

public function roll() { // Remove the following line when you

// implement this method.

throw new RuntimeException('Not yet implemented.'); }

public function score() {

// Remove the following line when you // implement this method.

throw new RuntimeException('Not yet implemented.'); }}

fullo@teletran ~ % phpunit BowlingGameTestPHPUnit 3.4.2 by Sebastian Bergmann.

E

Time: 0 seconds

There was 1 error:

1) BowlingGameTest::testScoreForGutterGameIs0RuntimeException: Not yet implemented./home/fullo/BowlingGame.php:10/home/fullo/BowlingGameTest.php:11

FAILURES!Tests: 1, Assertions: 0, Errors: 1.

<?phpclass BowlingGame{

public function roll($pins) { }

public function score() {

return 0; }}?>

fullo@teletran ~ % phpunit --colors BowlingGameTestPHPUnit 3.4.2 by Sebastian Bergmann.

.

Time: 0 seconds

OK (1 test, 1 assertion)

We have to write the tests when the code is

fresh.

<?phprequire_once 'BowlingGame.php';

class BowlingGameTest extends PHPUnit_Framework_TestCase{

// …

public function testScoreForAllOnesIs20(){

$game = new BowlingGame;

for ($i = 0; $i < 20; $i++) { $game->roll(1); }

$this->assertEquals(20, $game->score());}

}

fullo@teletran ~ % phpunit –colors BowlingGameTestPHPUnit 3.4.2 by Sebastian Bergmann.

.F

Time: 0 seconds

There was 1 failure:

1) BowlingGameTest::testScoreForAllOnesIs20Failed asserting that <integer:0> matches expected value <integer:20>./home/fullo/BowlingGameTest.php:25

FAILURES!Tests: 2, Assertions: 2, Failures: 1.

<?phpclass BowlingGame{

protected $rolls = array();

public function roll($pins) { $this->rolls[] = $pins; }

public function score() {

return array_sum($this->rolls); } }

<?phprequire_once 'BowlingGame.php';

class BowlingGameTest extends PHPUnit_Framework_TestCase{

// …

public function testScoreForOneSpareAnd3Is16(){

$game = new BowlingGame;

$game->roll(5); $game->roll(5); $game->roll(3);

// a function to to roll X times $this->rollMany(17, 0); $this->assertEquals(16, $game->score());

}

}

fullo@teletran ~ % phpunit –colors BowlingGameTestPHPUnit 3.4.2 by Sebastian Bergmann.

..F

Time: 0 seconds

There was 1 failure:

1) BowlingGameTest::testScoreForOneSpareAnd3is16Failed asserting that <integer:13> matches expected value <integer:16>./home/fullo/BowlingGameTest.php:33

FAILURES!Tests: 2, Assertions: 2, Failures: 1.

Tests can serve as an executable

specification.

fullo@teletran ~ % phpunit --testdox BowlingGameTestPHPUnit 3.4.2 by Sebastian Bergmann.

BowlingGame [x] Score for gutter game is 0 [ ] Score for all ones is 20 [ ] Score for one spare and 3 is 16 [ ] Score for one strike and 3 and 4 is 24 [ ] Score for perfect game is 300

Why Unit Test.

To write only clean and useful code.

To easily iterate in development design.

To check for regressions.

?

For more info see Sebastian Bergmann's Bowling Kata

Workshop!

http://www.slideshare.net/sebastian_bergmann/quality-assurance-in-

php-projects-2164371

Francesco Fulloneff AT ideato.itskype: ffullone

via Quinto Bucci 20547023 Cesena (FC)

info AT ideato.itwww.ideato.it