• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Unittests für Dummies
 

Unittests für Dummies

on

  • 2,755 views

Refactoring, Agile Entwicklung, Continuous Integration – all diese für nachhaltigen Erfolg wichtigen Vorgehensweisen setzen Erfahrung mit Unit Testing voraus. Abseits von den üblichen ...

Refactoring, Agile Entwicklung, Continuous Integration – all diese für nachhaltigen Erfolg wichtigen Vorgehensweisen setzen Erfahrung mit Unit Testing voraus. Abseits von den üblichen "Bowling"-Beispielen möchten wir gerne einen Crashkurs inkl. Best Practices für das erfolgreiche Unit Testing durchführen. Anhand eines Beispielprojekts auf Basis des Zend Frameworks werden wir nach der Installation von PHPUnit auf allen Notebooks gemeinsam eine kleine Applikation aufbauen, die durchgehend Test-driven entwickelt wird.

Statistics

Views

Total Views
2,755
Views on SlideShare
2,752
Embed Views
3

Actions

Likes
1
Downloads
11
Comments
0

3 Embeds 3

http://www.insidephp.com 1
http://www.slideshare.net 1
http://10.150.200.76 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Unittests für Dummies Unittests für Dummies Presentation Transcript

    • Unit Testing für Dummies 15.11.2009 Lars Jankowfsky, swoodoo AG Thorsten Rinne, Mayflower GmbH
    • About me: PHP, C++, Developer, Software Architect since 1992 PHP since 1998 Many successful projects from 2 to 20 developers Running right now three projects using eXtreme Programming CTO and (Co-)Founder swoodoo AG (Co-)Founder OXID eSales AG
    • About me: Diplom-Informatiker (FH) Certified Scrum Master Zend Certified Engineer PHP since 1999 Many successful projects from 2 to 6 developers using Scrum, eXtreme Programming, Crystal Clear Senior Developer / Team Lead at Mayflower GmbH Master of phpMyFAQ
    • (c) spackletoe http://www.flickr.com/photos/spackletoe/90811910/) (c) aboutpixel.de
    • Unit Tests? PHPUnit Fixtures Stubs Pitfalls
    • PHPUnit http://www.phpunit.de/
    • PHPUnit PHPUnit phpunit myTest user@workshop:/var/www/thorsten-zfguestbook/tests/ application$ phpunit controllers_PostsControllerTest
    • Fixtures
    • Fixtures Fixtures Make sure that tests don‘t alter fixture Fixture is FIXture if you feel creating fixtures is too much work - refactor more! Do never let tests leave altered tests
    • Fixtures the Ruby way... Fixtures Ruby uses YAML www.yaml.org PHP YAML support done by using Syck Syck = YAML + fast http://whytheluckystiff.net/syck/ http://www.frontalaufprall.com/2008/05/05/php-unit- database-fixtures-the-ruby-way/
    • YAML loading Fixtures public static function create($fileName) { $fileName = 'Fixtures'.DIRECTORY_SEPARATOR.$fileName; ob_start(); include $fileName; $fileContents = ob_get_contents(); ob_clean(); $yamlData = syck_load($fileContents); return $yamlData; }
    • YAML storing Fixtures public static function load($fixtures, $tableName) { if (is_array($fixtures) && count($fixtures)) { foreach ($fixtures as $fixture) { if (is_array($fixture) && is_array(current($fixture))) { Fixtures::load($fixture, $tableName); } $fields = array_keys($fixture); $statement = "INSERT INTO $tableName (" . implode(', ', $fields) . ") VALUES (:" . implode(", :", $fields) . ")"; $stmt = self::$_db->prepare($statement); if (count($fixture)) { foreach ($fixture as $key => $value ) { $stmt->bindValue(':'.$key, $value); } } $stmt->execute(); self::$_usedTables[$tableName] = $tableName; } } }
    • YAML - cleanup Fixtures if (!empty(self::$_usedTables)) { foreach (array_reverse(self::$_usedTables) as $tableName) { self::$_db->execute("TRUNCATE TABLE $tableName"); } }
    • Fixtures the other side ... Fixtures manual fixtures are too much work use a test database think about automatic creation of YAML files
    • Stubs
    • Mocking stubs? Stubs Unittesting is about testing a unit of work, not a complete workflow isolates your code from external dependencies can be done with PHPUnit, but you don‘t need to
    • Mocking stubs The PHPUnit way Stubs /** * A simple stub providing a simple result directly instead of using the database */ class UserModelStub extends UserModel { public getUserCount() { return 10; } } UserModelStub extends PHPUnit_Framework_Testcase { public function testGetUserCount() { $stub = $this->getMock(‘UserModel‘); $stub->expects($this->any())->method(‘getUserCount‘)->will($this- >returnValue(10)); } }
    • Pitfalls
    • Code the unit test first. Pitfalls OOP, public, private Globals Superglobals Sessions Cookies
    • Dependencies ... Pitfalls Separate logic from view create accessors, add all parameters in calls
    • Dependency Example Pitfalls class displayUserDetails() { /** * Processes input and sends user first name, last name to display; */ function show() { global $dbLink; global $templateEngine; $itemId = (int) $_REQUEST['user_id']; $firstName = $dbLink->getOne("select first_name from users where id = $itemId"); $lastName = $dbLink->getOne("select last_name from users where id = $itemId"); $templateEngine->addTemplateVar('firstName', $firstName); $templateEngine->addTemplateVar('lastName', $lastName); $templateEngine->display(); } }
    • Dependency Example Pitfalls /** * A view class responsible for displaying user details. */ class userView() { /** * Loads user object and sends first name, last name to display */ public function show() { $userId = $this->_inputProcessor->getParameter("user_id"); $this->templateEngine->addTemplateVar('user', $this->model->loadUser(userId)); $this->templateEngine->display(); } } /** * And the corresponding model */ class userModel() { public function loadUser($userId) { $user = new User( $userId ); return array('firstName' => $user->getFirstName(), 'lastName' => $user->getLastName()); } }
    • STOP
    • Layer Example Pitfalls class someOtherClass { var $setting; function calculateSomething($a, $b) { return $a+$b; } } class myOldNastyClass { function needToTestThisFunction() { $class = new someOtherClass(); $z = $_GET['input']; // .... return $class->calculateSomething( $class->setting, $z); } }
    • Layer Example Pitfalls class someOtherClass { private $setting; public function calculateSomething($a, $b) { return $a+$b; } public function setSetting($set) { $this->setting = $set; } public function getSetting() { return $this->setting; } } class myInput { public function getParameter($name) { return $_GET[$name]; } } class myOldNastyClass { private $input; // set e.g. in constructor public function needToTestThisFunction(someOtherClass &$class, $z) { $z = $input->getParameter('input'); // .... return $class->calculateSomething( $class->getSetting(), $z); } }
    • (c) istockphoto
    • „Questions?“