77
Commencer avec le TDD Eric Hogue - @ehogue Confoo - 2014-02-27 1

Commencer avec le TDD

Embed Size (px)

Citation preview

Commencer avec le TDDEric Hogue - @ehogue

Confoo - 2014-02-27

1

TDD2

Où commencer?

3

Tests unitaires

4

Tests unitaires

est une procédure permettant de vérifier le bon fonctionnement d'une partie précise d'un logiciel ou d'une portion d'un programme (appelée « unité » ou « module »).

http://fr.wikipedia.org/wiki/Test_unitaire

5

Ne pas traverser de frontières

6

Outils

● SimpleTest● atoum● PHPT● PHPUnit

7

8

Installation - Phar

$ wget

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

$ chmod +x phpunit.phar

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

9

Installation - Composer

# composer.json

{

"require-dev": {

"phpunit/phpunit": "4.5.*"

}

}

$ composer install

10

PHPUnit

FactorialTest.php

<?php

class FactorialTest extends

\PHPUnit_Framework_TestCase {

}

11

public function testSomething() {

}

/** @test */

public function somethingElse() {

}

12

● Arrange● Act● Assert

13

Arrange

/** @test */

public function factOf1() {

$factorial = new Factorial;

}

14

Act

/** @test */

public function factOf1() {

$factorial = new Factorial;

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

}

15

Assert

/** @test */

public function factOf1() {

$factorial = new Factorial;

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

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

}

16

PHPUnit Assertions

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

17

Preparing For Your Tests

setup() -> Avant chaque testteardown() -> Après chaque test

setUpBeforeClass() + tearDownAfterClass()Une fois par test

18

19

TDD20

3 règles du TDD - Uncle Bob

● You are not allowed to write any production code unless it is to make a failing unit test pass.

● You are not allowed to write any more of a unit test than is sufficient to fail; ○ and compilation failures are failures.

● You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd21

Red - Green - Refactor

Red Écrire un test qui échoue

22

Red - Green - Refactor

GreenLe faire passer

23

Red - Green - Refactor

RefactorRégler les raccourcis pris

24

/** @test */

public function create() {

$this->assertNotNull(new Factorial);

}

25

class Factorial {

}

26

/** @test */

public function factOf1() {

$facto = new Factorial;

$this->assertSame(1,

$facto->fact(1));

}

27

public function fact($number) {

return 1;

}

28

Duplication

public function create() {

$this->assertNotNull(new Factorial);

}

public function factOf1() {

$facto = new Factorial;

...

29

public function setup() {

$this->facto = new Factorial;

}

/** @test */

public function factOf1() {

$this->assertSame(1,

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

}

30

/** @test */

public function factOf2() {

$this->assertSame(2,

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

}

31

public function fact($number) {

return $number;

}

32

Plus de duplication/** @test */

public function factOf1() {

$this->assertSame(1,

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

}

/** @test */

public function factOf2() {

$this->assertSame(2,

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

} 33

public function factDataProvider() {

return [

[1, 1],

[2, 2],

];

}

34

/**

* @test

* @dataProvider factDataProvider

*/

public function factorial($number,

$expected) {

...

35

…$result =

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

$this->assertSame($expected,

$result);

}

36

public function factDataProvider() {

…[2, 2],

[3, 6],

...

37

public function fact($number) {

if ($number < 2) return 1;

return $number *

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

}

38

Beaucoup de travail

39

40

Dépendances

41

Problème

class Foo {

public function __construct() {

$this->bar = new Bar;

}

}

42

Injection des dépendances

43

Setter Injection

class Foo {

public function setBar(Bar $bar) {

$this->bar = $bar;

}

}

public function doSomething() {

// Use $this->bar

}

44

Constructor Injection

class Foo {

public function __construct(

Bar $bar) {

$this->bar = $bar;

}

...

}

45

Passer la dépendance aux méthodes

class Foo {

public function doSomething(

Bar $bar) {

// Use $bar

}

}

46

Système de fichiers

47

vfsStream

Système de fichier virtuel

composer.json

"require-dev": {

"mikey179/vfsStream": "*"

},

48

Vérifier la création d’un répertoire

$root = vfsStream::setup('dir');

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

//Code creating sub folder

$SUT->createDir($parentDir, 'test');

$this->assertTrue(

$root->hasChild('test'));

49

Lire un fichier

$struct = [

'subDir' => ['test.txt'

=> 'content']

];

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

null, $struct);

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

...50

Lire un fichier

…$content = file_get_contents(

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

$this->assertSame('content',

$content);

51

Base de données

52

Mocks

Remplace une dépendance

● PHPUnit mocks● Mockery● Phake

53

Création

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

$mock = $this->getMockBuilder

('\Namespace\Class')

->disableOriginalConstructor()

->getMock();

54

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

->method('methodName')

55

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

->method('methodName')

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

56

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

->method('methodName')

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

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

57

Mocking PDO

$statement = $this->getMockBuilder

('\PDOStatement')

->getMock();

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

->method('execute')

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

...

58

...

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

->method('fetchAll')

->will(

$this->returnValue(

[['id' => 123]]

)

);

...59

$this->getMockBuilder('\PDO')

->getMock();

60

…$pdo = $this->getMockBuilder(

'\stdClass')

->setMethods(['prepare'])

->getMock();

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

->method('prepare')

->will(

$this->returnValue($statement));61

class PDOMock extends \PDO {

public function __construct() {}

}

$pdo = $this->getMockBuilder

('\PDOMock')

->getMock();

62

mysql_*

63

DbUnit

extends PHPUnit_Extensions_Database_TestCase

public function getConnection() {

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

return $this->

createDefaultDBConnection(

$pdo, ':memory:');

}64

public function getDataSet() {

return $this->

createFlatXMLDataSet('file');

}

65

API

66

● Encapsuler○ Zend\Http○ Guzzle○ Classe qui utilise curl

● Mock○ Retourner le xml/json voulu

67

Avantages et inconvénients68

Avantages

69

Inconvénients

70

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

71

Inconvénients

72

Prochaines étapes?

73

Tests en continue - Guard

74

Intégration continue

75

Commentaires: https://joind.in/13312twitter: @ehogue

PHP Mentoring: http://phpmentoring.org/

Questions?

76

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/● PolliceVersoThumbsUp.jpg - keimevo - https://www.flickr.com/photos/keimevo/14093768567/in/photostream/● PolliceVersoThumbsDown.jpg - keimevo - https://www.flickr.com/photos/keimevo/14093716370/in/photostream/● CILights.jpg - Jan Krutisch - https://www.flickr.com/photos/jankrutisch/4272142306/in/photostream/

77