• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Getting started with TDD - Confoo 2014
 

Getting started with TDD - Confoo 2014

on

  • 680 views

Introduction to Test Driven Development. I gave that talk on February 2014 at Confoo.

Introduction to Test Driven Development. I gave that talk on February 2014 at Confoo.

Statistics

Views

Total Views
680
Views on SlideShare
673
Embed Views
7

Actions

Likes
4
Downloads
8
Comments
0

1 Embed 7

http://confoo.ca 7

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

    Getting started with TDD - Confoo 2014 Getting started with TDD - Confoo 2014 Presentation Transcript

    • Getting Started With TDD Eric Hogue - @ehogue Confoo - 2014-02-27
    • TDD
    • Where should I Start?
    • 1. Unit tests 2. Test Driven Development 3. What’s next?
    • Unit Tests
    • Unit Test a method by which individual units of source code [...] are tested to determine if they are fit for use http://en.wikipedia.org/wiki/Unit_testing
    • Don’t Cross boundaries
    • Tools ● ● ● ● SimpleTest atoum PHPT PHPUnit
    • Installation - Phar $ wget https://phar.phpunit.de/phpunit.phar $ chmod +x phpunit.phar $ mv phpunit.phar /usr/local/bin/phpunit
    • Installation - Pear pear config-set auto_discover 1 pear install pear.phpunit.de/PHPUnit
    • Installation - Composer # composer.json { "require-dev": { "phpunit/phpunit": "3.7.*" } } $ composer install
    • PHPUnit FactorialTest.php <?php class FactorialTest extends PHPUnit_Framework_TestCase { }
    • public function testSomething() { } /** @test */ public function somethingElse() { }
    • ● Arrange ● Act ● Assert
    • Arrange /** @test */ public function factOf1() { $factorial = new Factorial; }
    • Act /** @test */ public function factOf1() { $factorial = new Factorial; $result = $factorial->fact(1); }
    • Assert /** @test */ public function factOf1() { $factorial = new Factorial; $result = $factorial->fact(1); $this->assertSame(1, $result); }
    • PHPUnit Assertions ● ● ● ● ● ● ● $this->assertTrue(); $this->assertEquals(); $this->assertSame(); $this->assertContains(); $this->assertNull(); $this->assertRegExp(); ...
    • Preparing For Your Tests setup() -> Before every tests teardown() -> After every tests setUpBeforeClass() + tearDownAfterClass() Once per test case
    • phpunit.xml <phpunit bootstrap="bootstrap.php" colors="true" strict="true" verbose="true" > ... </phpunit>
    • phpunit.xml <phpunit> <testsuites> <testsuite name="My Test Suite"> <directory>path</directory> <file>path</file> <exclude>path</exclude> </testsuite> </testsuites> </phpunit>
    • TDD
    • Red - Green - Refactor Red Write a failing test
    • Red - Green - Refactor Green Make it pass
    • Red - Green - Refactor Refactor Fix any shortcuts you took
    • /** @test */ public function create() { $this->assertNotNull(new Factorial); }
    • class Factorial { }
    • /** @test */ public function factOf1() { $facto = new Factorial; $this->assertSame(1, $facto->fact(1)); }
    • public function fact($number) { return 1; }
    • Duplication public function create() { $this->assertNotNull(new Factorial); } public function factOf1() { $facto = new Factorial; ...
    • public function setup() { $this->facto = new Factorial; } /** @test */ public function factOf1() { $this->assertSame(1, $this->facto->fact(1)); }
    • /** @test */ public function factOf2() { $this->assertSame(2, $this->facto->fact(2)); }
    • public function fact($number) { return $number; }
    • More duplication /** @test */ public function factOf1() { $this->assertSame(1, $this->facto->fact(1)); } /** @test */ public function factOf2() { $this->assertSame(2, $this->facto->fact(2)); }
    • public function factDataProvider() { return array( array(1, 1), array(2, 2), ); }
    • /** * @test * @dataProvider factDataProvider */ public function factorial($number, $expected) { ...
    • … $result = $this->facto->fact($number); $this->assertSame($expected, $result); }
    • public function factDataProvider() { … array(2, 2), array(3, 6), ...
    • public function fact($number) { if ($number < 2) return 1; return $number * $this->fact($number - 1); }
    • It’s a lot of work
    • Dependencies
    • Problems class Foo { public function __construct() { $this->bar = new Bar; } }
    • Dependency Injection
    • Setter Injection class Foo { public function setBar(Bar $bar) { $this->bar = $bar; } public function doSomething() { // Use $this->bar } }
    • Constructor Injection class Foo { public function __construct( Bar $bar) { $this->bar = $bar; } public function doSomething() { // Use $this->bar } }
    • Pass the dependency directly class Foo { public function doSomething( Bar $bar) { // Use $bar } }
    • File System
    • vfsStream Virtual Files System composer.json "require-dev": { "mikey179/vfsStream": "*" },
    • Check if a folder was created $root = vfsStream::setup('dir'); $parentDir = $root->url('dir'); //Code creating sub folder $SUT->createDir($parentDir, 'test'); $this->assertTrue( $root->hasChild('test'));
    • Reading a file $struct = array( 'subDir' => array('test.txt' => 'content') ); $root = vfsStream::setup('root', null, $struct); $parentDir = $root->url('root'); ...
    • Reading a file … $content = file_get_contents( $parentDir . '/subDir/test.txt'); $this->assertSame('content', $content);
    • Databases
    • Mocks Replaces a dependency ● PHPUnit mocks ● Mockery ● Phake
    • Creation $mock = $this->getMock('NSClass');
    • Creation $mock = $this->getMock('NSClass'); Or $mock = $this->getMockBuilder ('NamespaceClass') ->disableOriginalConstructor() ->getMock();
    • $mock->expects($this->once()) ->method('methodName')
    • $mock->expects($this->once()) ->method('methodName') ->with(1, 'aa', $this->anything())
    • $mock->expects($this->once()) ->method('methodName') ->with(1, 'aa', $this->anything()) ->will($this->returnValue(10));
    • Mocking PDO $statement = $this->getMockBuilder ('PDOStatement') ->getMock(); $statement->expects($this->once()) ->method('execute') ->will($this->returnValue(true)); ...
    • ... $statement->expects($this->once()) ->method('fetchAll') ->will( $this->returnValue( array(array('id' => 123)) ) ); ...
    • $this->getMockBuilder('PDO') ->getMock();
    • … $pdo = $this->getMockBuilder( 'stdClass') ->setMethods(array('prepare')) ->getMock(); $pdo->expects($this->once()) ->method('prepare') ->will( $this->returnValue($statement));
    • class PDOMock extends PDO { public function __construct() {} } $pdo = $this->getMockBuilder ('PDOMock') ->getMock();
    • mysql_*
    • DbUnit Extension extends PHPUnit_Extensions_Database_TestCase public function getConnection() { $pdo = new PDO('sqlite::memory:'); return $this-> createDefaultDBConnection( $pdo, ':memory:'); }
    • public function getDataSet() { return $this-> createFlatXMLDataSet('file'); }
    • API
    • ● Wrap all call into a class ○ ZendHttp ○ Guzzle ○ Simple class that uses curl ● Mock the class ○ Return the wanted xml/json
    • Pros and Cons
    • Pros ● Less regressions
    • Pros ● Less regressions ● Trust
    • Pros ● Less regressions ● Trust ● Low coupling
    • Pros ● ● ● ● Less regressions Trust Low coupling Simple Design
    • Cons ● Takes longer
    • “If it doesn't have to work, I can get it done a lot faster!” - Kent Beck
    • Cons ● Takes longer ● Can be hard to sell to managers
    • Cons ● Takes longer ● Can be hard to sell to managers ● It’s hard
    • Prochaines étapes?
    • Continuous Testing - Guard
    • Continuous Integration
    • Continuous Integration ● Run your tests automatically ○ ○ ○ ○ Unit Tests Acceptance Tests Performance Tests ...
    • Continuous Integration ● Run your tests automatically ○ ○ ○ ○ Unit Tests Acceptance Tests Performance Tests … ● Check Standards ○ phpcs
    • Continuous Integration ● Run your tests automatically ○ ○ ○ ○ Unit Tests Acceptance Tests Performance Tests … ● Check Standards ○ phpcs ● Check for "code smells" ○ phpcpd ○ PHP Depend ○ PHP Mess Detector
    • Questions Twitter: @ehogue Blog: http://erichogue.ca/ Slides: http://www. slideshare.net/EricHogue
    • Credits ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● Paul - http://www.flickr.com/photos/pauldc/4626637600/in/photostream/ JaseMan - http://www.flickr.com/photos/bargas/3695903512/ mt 23 - http://www.flickr.com/photos/32961941@N03/3166085824/ Adam Melancon - http://www.flickr.com/photos/melancon/348974082/ Zhent_ - http://www.flickr.com/photos/zhent/574472488/in/faves-96579472@N07/ Ryan Vettese - http://www.flickr.com/photos/rvettese/383453435/ shindoverse - http://www.flickr.com/photos/shindotv/3835363999/ Eliot Phillips - http://www.flickr.com/photos/hackaday/5553713944/ World Bank Photo Collection - http://www.flickr.com/photos/worldbank/8262750458/ Steven Depolo - http://www.flickr.com/photos/stevendepolo/3021193208/ Deborah Austin - http://www.flickr.com/photos/littledebbie11/4687828358/ tec_estromberg - http://www.flickr.com/photos/92334668@N07/11122773785/ nyuhuhuu - http://www.flickr.com/photos/nyuhuhuu/4442144329/ Damián Navas - http://www.flickr.com/photos/wingedwolf/5471047557/ Improve It - http://www.flickr.com/photos/improveit/1573943815/