88
Getting Started With TDD Eric Hogue - @ehogue Confoo - 2014-02-27

Getting started with TDD - Confoo 2014

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Getting started with TDD - Confoo 2014

Getting Started With TDDEric Hogue - @ehogue

Confoo - 2014-02-27

Page 2: Getting started with TDD - Confoo 2014

TDD

Page 3: Getting started with TDD - Confoo 2014

Where should I Start?

Page 4: Getting started with TDD - Confoo 2014

1. Unit tests2. Test Driven Development3. What’s next?

Page 5: Getting started with TDD - Confoo 2014

Unit Tests

Page 6: Getting started with TDD - Confoo 2014

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

Page 7: Getting started with TDD - Confoo 2014

Don’t Cross boundaries

Page 8: Getting started with TDD - Confoo 2014

Tools

● SimpleTest● atoum● PHPT● PHPUnit

Page 9: Getting started with TDD - Confoo 2014
Page 10: Getting started with TDD - Confoo 2014

Installation - Phar

$ wget

https://phar.phpunit.de/phpunit.phar

$ chmod +x phpunit.phar

$ mv phpunit.phar /usr/local/bin/phpunit

Page 11: Getting started with TDD - Confoo 2014

Installation - Pear

pear config-set auto_discover 1

pear install pear.phpunit.de/PHPUnit

Page 12: Getting started with TDD - Confoo 2014

Installation - Composer

# composer.json

{

"require-dev": {

"phpunit/phpunit": "3.7.*"

}

}

$ composer install

Page 13: Getting started with TDD - Confoo 2014

PHPUnit

FactorialTest.php

<?php

class FactorialTest extends

\PHPUnit_Framework_TestCase {

}

Page 14: Getting started with TDD - Confoo 2014

public function testSomething() {

}

/** @test */

public function somethingElse() {

}

Page 15: Getting started with TDD - Confoo 2014

● Arrange● Act● Assert

Page 16: Getting started with TDD - Confoo 2014

Arrange

/** @test */

public function factOf1() {

$factorial = new Factorial;

}

Page 17: Getting started with TDD - Confoo 2014

Act

/** @test */

public function factOf1() {

$factorial = new Factorial;

$result = $factorial->fact(1);

}

Page 18: Getting started with TDD - Confoo 2014

Assert

/** @test */

public function factOf1() {

$factorial = new Factorial;

$result = $factorial->fact(1);

$this->assertSame(1, $result);

}

Page 19: Getting started with TDD - Confoo 2014

PHPUnit Assertions

● $this->assertTrue();● $this->assertEquals();● $this->assertSame();● $this->assertContains();● $this->assertNull();● $this->assertRegExp();● ...

Page 20: Getting started with TDD - Confoo 2014

Preparing For Your Tests

setup() -> Before every teststeardown() -> After every tests

setUpBeforeClass() + tearDownAfterClass()Once per test case

Page 21: Getting started with TDD - Confoo 2014

phpunit.xml

<phpunit bootstrap="bootstrap.php"

colors="true"

strict="true"

verbose="true"

>

...

</phpunit>

Page 22: Getting started with TDD - Confoo 2014

phpunit.xml

<phpunit>

<testsuites>

<testsuite name="My Test Suite">

<directory>path</directory>

<file>path</file>

<exclude>path</exclude>

</testsuite>

</testsuites>

</phpunit>

Page 23: Getting started with TDD - Confoo 2014
Page 24: Getting started with TDD - Confoo 2014

TDD

Page 25: Getting started with TDD - Confoo 2014

Red - Green - Refactor

Red Write a failing test

Page 26: Getting started with TDD - Confoo 2014

Red - Green - Refactor

GreenMake it pass

Page 27: Getting started with TDD - Confoo 2014

Red - Green - Refactor

RefactorFix any shortcuts you took

Page 28: Getting started with TDD - Confoo 2014

/** @test */

public function create() {

$this->assertNotNull(new Factorial);

}

Page 29: Getting started with TDD - Confoo 2014

class Factorial {

}

Page 30: Getting started with TDD - Confoo 2014

/** @test */

public function factOf1() {

$facto = new Factorial;

$this->assertSame(1,

$facto->fact(1));

}

Page 31: Getting started with TDD - Confoo 2014

public function fact($number) {

return 1;

}

Page 32: Getting started with TDD - Confoo 2014

Duplication

public function create() {

$this->assertNotNull(new Factorial);

}

public function factOf1() {

$facto = new Factorial;

...

Page 33: Getting started with TDD - Confoo 2014

public function setup() {

$this->facto = new Factorial;

}

/** @test */

public function factOf1() {

$this->assertSame(1,

$this->facto->fact(1));

}

Page 34: Getting started with TDD - Confoo 2014

/** @test */

public function factOf2() {

$this->assertSame(2,

$this->facto->fact(2));

}

Page 35: Getting started with TDD - Confoo 2014

public function fact($number) {

return $number;

}

Page 36: Getting started with TDD - Confoo 2014

More duplication/** @test */

public function factOf1() {

$this->assertSame(1,

$this->facto->fact(1));

}

/** @test */

public function factOf2() {

$this->assertSame(2,

$this->facto->fact(2));

}

Page 37: Getting started with TDD - Confoo 2014

public function factDataProvider() {

return array(

array(1, 1),

array(2, 2),

);

}

Page 38: Getting started with TDD - Confoo 2014

/**

* @test

* @dataProvider factDataProvider

*/

public function factorial($number,

$expected) {

...

Page 39: Getting started with TDD - Confoo 2014

…$result =

$this->facto->fact($number);

$this->assertSame($expected,

$result);

}

Page 40: Getting started with TDD - Confoo 2014

public function factDataProvider() {

…array(2, 2),

array(3, 6),

...

Page 41: Getting started with TDD - Confoo 2014

public function fact($number) {

if ($number < 2) return 1;

return $number *

$this->fact($number - 1);

}

Page 42: Getting started with TDD - Confoo 2014

It’s a lot of work

Page 43: Getting started with TDD - Confoo 2014
Page 44: Getting started with TDD - Confoo 2014

Dependencies

Page 45: Getting started with TDD - Confoo 2014

Problems

class Foo {

public function __construct() {

$this->bar = new Bar;

}

}

Page 46: Getting started with TDD - Confoo 2014

Dependency Injection

Page 47: Getting started with TDD - Confoo 2014

Setter Injection

class Foo {

public function setBar(Bar $bar) {

$this->bar = $bar;

}

public function doSomething() {

// Use $this->bar

}

}

Page 48: Getting started with TDD - Confoo 2014

Constructor Injection

class Foo {

public function __construct(

Bar $bar) {

$this->bar = $bar;

}

public function doSomething() {

// Use $this->bar

}

}

Page 49: Getting started with TDD - Confoo 2014

Pass the dependency directly

class Foo {

public function doSomething(

Bar $bar) {

// Use $bar

}

}

Page 50: Getting started with TDD - Confoo 2014

File System

Page 51: Getting started with TDD - Confoo 2014

vfsStream

Virtual Files System

composer.json

"require-dev": {

"mikey179/vfsStream": "*"

},

Page 52: Getting started with TDD - Confoo 2014

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'));

Page 53: Getting started with TDD - Confoo 2014

Reading a file

$struct = array(

'subDir' => array('test.txt'

=> 'content')

);

$root = vfsStream::setup('root',

null, $struct);

$parentDir = $root->url('root');

...

Page 54: Getting started with TDD - Confoo 2014

Reading a file

$content = file_get_contents(

$parentDir . '/subDir/test.txt');

$this->assertSame('content',

$content);

Page 55: Getting started with TDD - Confoo 2014

Databases

Page 56: Getting started with TDD - Confoo 2014

Mocks

Replaces a dependency

● PHPUnit mocks● Mockery● Phake

Page 57: Getting started with TDD - Confoo 2014

Creation

$mock = $this->getMock('\NS\Class');

Page 58: Getting started with TDD - Confoo 2014

Creation

$mock = $this->getMock('\NS\Class');

Or

$mock = $this->getMockBuilder

('\Namespace\Class')

->disableOriginalConstructor()

->getMock();

Page 59: Getting started with TDD - Confoo 2014

$mock->expects($this->once())

->method('methodName')

Page 60: Getting started with TDD - Confoo 2014

$mock->expects($this->once())

->method('methodName')

->with(1, 'aa', $this->anything())

Page 61: Getting started with TDD - Confoo 2014

$mock->expects($this->once())

->method('methodName')

->with(1, 'aa', $this->anything())

->will($this->returnValue(10));

Page 62: Getting started with TDD - Confoo 2014

Mocking PDO

$statement = $this->getMockBuilder

('\PDOStatement')

->getMock();

$statement->expects($this->once())

->method('execute')

->will($this->returnValue(true));

...

Page 63: Getting started with TDD - Confoo 2014

...

$statement->expects($this->once())

->method('fetchAll')

->will(

$this->returnValue(

array(array('id' => 123))

)

);

...

Page 64: Getting started with TDD - Confoo 2014

$this->getMockBuilder('\PDO')

->getMock();

Page 65: Getting started with TDD - Confoo 2014

…$pdo = $this->getMockBuilder(

'\stdClass')

->setMethods(array('prepare'))

->getMock();

$pdo->expects($this->once())

->method('prepare')

->will(

$this->returnValue($statement));

Page 66: Getting started with TDD - Confoo 2014

class PDOMock extends \PDO {

public function __construct() {}

}

$pdo = $this->getMockBuilder

('\PDOMock')

->getMock();

Page 67: Getting started with TDD - Confoo 2014

mysql_*

Page 68: Getting started with TDD - Confoo 2014

DbUnit Extension

extends PHPUnit_Extensions_Database_TestCase

public function getConnection() {

$pdo = new PDO('sqlite::memory:');

return $this->

createDefaultDBConnection(

$pdo, ':memory:');

}

Page 69: Getting started with TDD - Confoo 2014

public function getDataSet() {

return $this->

createFlatXMLDataSet('file');

}

Page 70: Getting started with TDD - Confoo 2014

API

Page 71: Getting started with TDD - Confoo 2014

● Wrap all call into a class○ Zend\Http○ Guzzle○ Simple class that uses curl

● Mock the class○ Return the wanted xml/json

Page 72: Getting started with TDD - Confoo 2014

Pros and Cons

Page 73: Getting started with TDD - Confoo 2014

Pros

● Less regressions

Page 74: Getting started with TDD - Confoo 2014

Pros

● Less regressions● Trust

Page 75: Getting started with TDD - Confoo 2014

Pros

● Less regressions● Trust● Low coupling

Page 76: Getting started with TDD - Confoo 2014

Pros

● Less regressions● Trust● Low coupling● Simple Design

Page 77: Getting started with TDD - Confoo 2014

Cons

● Takes longer

Page 78: Getting started with TDD - Confoo 2014

“If it doesn't have to work, I can get it done a lot faster!”- Kent Beck

Page 79: Getting started with TDD - Confoo 2014

Cons

● Takes longer● Can be hard to sell to managers

Page 80: Getting started with TDD - Confoo 2014

Cons

● Takes longer● Can be hard to sell to managers● It’s hard

Page 81: Getting started with TDD - Confoo 2014

Prochaines étapes?

Page 82: Getting started with TDD - Confoo 2014

Continuous Testing - Guard

Page 83: Getting started with TDD - Confoo 2014

Continuous Integration

Page 84: Getting started with TDD - Confoo 2014

Continuous Integration

● Run your tests automatically ○ Unit Tests○ Acceptance Tests○ Performance Tests○ ...

Page 85: Getting started with TDD - Confoo 2014

Continuous Integration

● Run your tests automatically ○ Unit Tests○ Acceptance Tests○ Performance Tests○ …

● Check Standards○ phpcs

Page 86: Getting started with TDD - Confoo 2014

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

Page 87: Getting started with TDD - Confoo 2014

Twitter:@ehogue

Blog:http://erichogue.ca/

Slides: http://www.slideshare.net/EricHogue

Questions

Page 88: Getting started with TDD - Confoo 2014

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/