unit testing in php

50
Unit Testing in PHP Rudolph Jakob Heuser [email protected] http://www.slideshare.net/jakobo

Upload: jakob-heuser

Post on 11-Nov-2014

3.085 views

Category:

Technology


4 download

DESCRIPTION

Talk given at Silicon Valley LAMP Meetup Aug 28, 2008

TRANSCRIPT

Page 1: Unit Testing in PHP

Unit Testing in PHP

Rudolph Jakob [email protected]

http://www.slideshare.net/jakobo

Page 2: Unit Testing in PHP

Who Is This Guy?

Sr. Software Engineer

PHP, JS, CSS

Python for kicks

Hates “echo” debugging

Page 3: Unit Testing in PHP

A Unit Test

Page 4: Unit Testing in PHP

public function testActionTakenIsInJob() { return $this->assertRegex($this->job->post, '/action_taken='.self::ACTION_TAKEN.'/'); } public function testTypeIsGeneratorInJob() { return $this->assertRegex($this->job->post, '/type=generator/'); } public function testGeneratorIsNamedInJob() { return $this->assertRegex($this->job->post, '/generator='.self::ACTION_TAKEN.'/'); } public function testActingUserIdIsNamedInJob() { return $this->assertRegex($this->job->post, '/acting_user_id='.self::ACTING_USER.'/'); } public function testURLIsInJob() { return $this->assertEqual($this->job->url, DataFeed::JOB_URL); } public function testStartTimeIsInJob() { return $this->assertEqual($this->job->start, self::TIME_NOW); }

Page 5: Unit Testing in PHP
Page 6: Unit Testing in PHP

A Unit Test Simplified

• A set of rules

• Predictable Dependancies

• Input / Output

Page 7: Unit Testing in PHP

A contract between adeveloper and their code

Page 8: Unit Testing in PHP

Ready to Use

SnapTest

PHPUnit

Testilence

SimpleTest

Page 9: Unit Testing in PHP

Why Test?

Page 10: Unit Testing in PHP

<?php

//...echo 'a';var_dump($file);var_dump($result);// ...echo 'b';var_dump($result);// ...echo 'c';

Page 11: Unit Testing in PHP
Page 12: Unit Testing in PHP

<?php

class Rube_Goldberg { // ... protected function iDontEvenKnowWhatThisDoesYet() { // ... } public function iAddedThisInterfaceItemJustInCase() { // ... }}

Page 13: Unit Testing in PHP
Page 14: Unit Testing in PHP
Page 15: Unit Testing in PHP
Page 16: Unit Testing in PHP
Page 17: Unit Testing in PHP

• Helps us debug

• Helps us refactor safely

• Keeps us from over engineering

• Long term saves time and money

Page 18: Unit Testing in PHP

Before

During

After

Always Test

Page 19: Unit Testing in PHP

What to Test?

Page 20: Unit Testing in PHP

Unit: the smallest testable part of an application

File Include Function Class Method

Page 21: Unit Testing in PHP

Ignore the Obvious

<?php

class Foo { protected $bar; public function setBar($baz) { $this->bar = $baz; }}

Page 22: Unit Testing in PHP

How do we Test?

Page 23: Unit Testing in PHP

An Example:The Game of Darts

Page 24: Unit Testing in PHP

Simple Darts Rules

• Start at 501 Points

• Goal is to get to 0

• 3 throws results in a score

• Must finish on 0 exactly

Page 25: Unit Testing in PHP

The “TDD” Concept

1. Decide the next “How Should it Work”

2. Write the Test

3. Verify the Failure

4. Write the Code

5. Verify the Success

Page 26: Unit Testing in PHP

The “TDD” Concept

• A Dart Game should start at 501 points

• If I ask a new dart game its score, it should tell me 501

• new DartGame() (constructor) and getScore() are required

Page 27: Unit Testing in PHP

<?php

class DartGame_Test extends Snap_UnitTestCase { public function setUp() {} public function tearDown() {} public function testGameStartsAt501() { $game = new DartGame(); return $this->assertEqual($game->getScore(), 501); }}

Page 28: Unit Testing in PHP

jakobo ~/Desktop/testing> ~/development/snaptest/snaptest.sh ./F/Users/jakobo/Desktop/testing/code/tests/base.stest.php had a fatal error: Fatal error: Class 'DartGame' not found in /Users/jakobo/Desktop/testing/code/tests/base.stest.php on line 8

______________________________________________________________________Total Cases: 0Total Tests: 1Total Pass: 0Total Defects: 0Total Failures: 1Total Skips: 0Total Todo: 0jakobo ~/Desktop/testing>

Page 29: Unit Testing in PHP

<?php

class DartGame { public function getScore() { return 501; }}

Page 30: Unit Testing in PHP

jakobo ~/Desktop/testing> ~/development/snaptest/snaptest.sh ./.______________________________________________________________________Total Cases: 1Total Tests: 1Total Pass: 1Total Defects: 0Total Failures: 0Total Skips: 0Total Todo: 0jakobo ~/Desktop/testing>

Page 31: Unit Testing in PHP

Back to Design

• A turn is 3 throws

• Two di!erent ways to score a turn

Page 32: Unit Testing in PHP

score() Interface

1. $game->score($one, $two, $three)

2. $game->score($one);$game->score($two);$game->score($three);

Page 33: Unit Testing in PHP

<?php

require dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'dartgame.class.php';

class DartGame_Test extends Snap_UnitTestCase { public function setUp() {} public function tearDown() {} public function testGameStartsAt501() { $game = new DartGame(); return $this->assertEqual($game->getScore(), 501); } public function testScore10and10and10CreatesScoreOf471() { $game = new DartGame(); $game->score(10, 10, 10); return $this->assertEqual($game->getScore(), 471); }}

Page 34: Unit Testing in PHP

jakobo ~/Desktop/testing> ~/development/snaptest/snaptest.sh ./.F/Users/jakobo/Desktop/testing/code/tests/base.stest.php had a fatal error: Fatal error: Call to undefined method DartGame::score() in /Users/jakobo/Desktop/testing/code/tests/base.stest.php on line 16

______________________________________________________________________Total Cases: 1Total Tests: 2Total Pass: 1Total Defects: 0Total Failures: 1Total Skips: 0Total Todo: 0jakobo ~/Desktop/testing>

Page 35: Unit Testing in PHP

<?php

class DartGame { public function getScore() { return 501; } public function score($one, $two, $three) {}}

Page 36: Unit Testing in PHP

jakobo ~/Desktop/testing> ~/development/snaptest/snaptest.sh ./F.Equal (==) assertion failed. [int(471) != int(501)] in method: testScore10and10and10CreatesScoreOf471 in class: DartGame_Test in file: /Users/jakobo/Desktop/testing/code/tests/base.stest.php______________________________________________________________________Total Cases: 1Total Tests: 2Total Pass: 1Total Defects: 0Total Failures: 1Total Skips: 0Total Todo: 0jakobo ~/Desktop/testing>

Page 37: Unit Testing in PHP

<?php

class DartGame { protected $score; public function __construct() { $this->score = 501; } public function getScore() { return $this->score; } public function score($one, $two, $three) { $this->score = $this->score - $one - $two - $three; }}

Page 38: Unit Testing in PHP

jakobo ~/Desktop/testing> ~/development/snaptest/snaptest.sh ./..______________________________________________________________________Total Cases: 1Total Tests: 2Total Pass: 2Total Defects: 0Total Failures: 0Total Skips: 0Total Todo: 0jakobo ~/Desktop/testing>

Page 39: Unit Testing in PHP

Ending Exactly On 0

If score goes below 0, don’t count

Page 40: Unit Testing in PHP

<?php

require dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'dartgame.class.php';

class DartGame_Test extends Snap_UnitTestCase { public function setUp() {} public function tearDown() {} public function testGameStartsAt501() { $game = new DartGame(); return $this->assertEqual($game->getScore(), 501); } public function testScore10and10and10CreatesScoreOf471() { $game = new DartGame(); $game->score(10, 10, 10); return $this->assertEqual($game->getScore(), 471); } public function testScoreGoingBelowZeroLeavesScoreAboveZero() { $game = new DartGame(); $game->score(60, 60, 60); $game->score(60, 60, 60); $game->score(60, 60, 60); // should not be applied return $this->assertEqual($game->getScore(), 141); }}

Page 41: Unit Testing in PHP

jakobo ~/Desktop/testing> ~/development/snaptest/snaptest.sh ./F..Equal (==) assertion failed. [int(141) != int(-39)] in method: testScoreGoingBelowZeroLeavesScoreAboveZero in class: DartGame_Test in file: /Users/jakobo/Desktop/testing/code/tests/base.stest.php______________________________________________________________________Total Cases: 1Total Tests: 3Total Pass: 2Total Defects: 0Total Failures: 1Total Skips: 0Total Todo: 0jakobo ~/Desktop/testing>

Page 42: Unit Testing in PHP

<?php

class DartGame { protected $score; public function __construct() { $this->score = 501; } public function getScore() { return $this->score; } public function score($one, $two, $three) { $score = $this->score - $one - $two - $three; if ($score >= 0) { $this->score = $score; } }}

Page 43: Unit Testing in PHP

jakobo ~/Desktop/testing> ~/development/snaptest/snaptest.sh ./...______________________________________________________________________Total Cases: 1Total Tests: 3Total Pass: 3Total Defects: 0Total Failures: 0Total Skips: 0Total Todo: 0jakobo ~/Desktop/testing>

Page 44: Unit Testing in PHP

And Then We...

• Validation for score(), bounding

• Obscure rules (checking out)

• Same process again

Page 45: Unit Testing in PHP

More Cool Stuff

• Mock Objects: “Fake” objects for dependancies

• Asserting Call Counts

• Expectations (For Call Counts and Mocks)

Page 46: Unit Testing in PHP

Get Testing

SnapTesthttp://www.snaptest.net

PHPUnithttp://www.phpunit.de

Testilencehttp://www.testilence.org

SimpleTesthttp://www.simpletest.org

Page 47: Unit Testing in PHP
Page 48: Unit Testing in PHP

Unit Testing in PHP

Rudolph Jakob [email protected]

http://www.slideshare.net/jakobo

Page 49: Unit Testing in PHP

LicenseThis presentation is presented under the Creative Commons Attribution Share-Alike License

You are free:

to share, copy, distribute, or transmit this work

to remix and adapt this work

Under the following conditions:

Attribution: You must attribute the work that uses material under this license to the original licensor (but not in a way that suggests or implies they endorse you or your use of the work)

Share Alike: If you alter, transform, or build upon the work, you may distribute the resulting work only under the same, similar, or compatible license.

Any of the above conditions can be waived with permission from the copyright holder.

http://creativecommons.org/licenses/by-sa/3.0/us/