Getting started with TDD - Confoo 2014

50 %
50 %
Information about Getting started with TDD - Confoo 2014
Technology

Published on February 27, 2014

Author: EricHogue

Source: slideshare.net

Description

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

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/

Add a comment

Related presentations

Related pages

Sessions (2014) | ConFoo.ca

Sessions; Training; Speakers; Activities; Venue; ... Getting Started With TDD. Eric Hogue PHP. ... ConFoo 2014 sponsored by.
Read more

Top 20 | ConFoo.ca

Top 20. 1 50 Frontend Performance Beginner to Expert to Crazy Person. Philip Tellis Performance HTML/CSS. ... 13 37 Getting Started With TDD. Eric Hogue PHP.
Read more

Getting Started with Unit Testing Part 1 | Visual Studio ...

Something went wrong getting user information from Channel 9. ... Jun 04, 2014 at 8:25AM By ... Getting Started with Unit Testing ...
Read more

TDD with AngularJS - Speaker Deck - Share Presentations ...

TDD with AngularJS by Mike Tierney. ... (TDD). While we will ... Getting Started With D3. Oct 22, 2014 by Mike Tierney.
Read more

PowerShell Magazine » Get started with Pester (PowerShell ...

23 March 2014 at 2:03pm […] ... ... Get started with Pester, PowerShell unit testing framework ... Getting started ...
Read more

Getting started with memoQ translator pro - September 2014 ...

Getting Started with memoQ translator pro. Skip navigation Upload. Sign in. ... memoQ server 2014: How to translate 10,000 words in ten minutes ...
Read more

Perforce 2014.1 Getting Started with P4V

26 Perforce 2014.1 Getting Started with P4V Next Steps This guide helps you to start working with files using P4V and points out important basic
Read more

Confoo 2012 : TDD and getting paid | Anthony Dahanne's blog

Confoo 2012 : TDD and getting paid. ... The steps to get you started with TDD : ... Article suivant Confoo 2012 : ...
Read more