Commencer avec le tdd

72
Commencer avec le TDD Eric Hogue PHP Québec - 2013-06-06

description

Le TDD (Test Driven Development) devient de plus en plus populaire. Guider le développement d’une application par les tests est maintenant une pratique acceptée dans plusieurs communautés. Mais démarrer avec le TDD peut être une tâche ardue. Dans cette présentation, nous allons voir ce qu’est le TDD. En commençant par les principes fondamentaux au TDD. Puis nous verrons quels sont les outils utilisés. Puis comment appliquer ces techniques dans le travail quotidien.

Transcript of Commencer avec le tdd

Page 1: Commencer avec le tdd

Commencer avec le TDDEric Hogue

PHP Québec - 2013-06-06

Page 2: Commencer avec le tdd

Test Driven Development

Page 3: Commencer avec le tdd

Où Commencer?

Page 4: Commencer avec le tdd

Les tests unitaires

Test automatisé qui exerce une seule unité de code

Page 5: Commencer avec le tdd

Outils

● PHPUnit● SimpleTest● atoum● PHPT

Page 6: Commencer avec le tdd

PHPUnit

FactorialTest.php<?phpclass FactorialTest extends \PHPUnit_Framework_TestCase {}

Page 7: Commencer avec le tdd

public function testSomething() {}

/** @test */public function somethingElse() {}

Page 8: Commencer avec le tdd

Les assertions

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

Page 9: Commencer avec le tdd

Préparation des tests

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

Page 10: Commencer avec le tdd

phpunit.xml

<phpunit bootstrap="bootstrap.php" colors="true"strict="true"verbose="true"

>...

</phpunit>

Page 11: Commencer avec le tdd

Le TDD

nyuhuhuuhttp://www.flickr.com/photos/nyuhuhuu/4442144329/

Page 12: Commencer avec le tdd

Red - Green - Refactor

Rouge Un test qui échoue

Page 13: Commencer avec le tdd

Red - Green - Refactor

VertFaire passer le test

Page 14: Commencer avec le tdd

Red - Green - Refactor

RefactorArranger le code

Page 15: Commencer avec le tdd

/** @test */public function create() {

$this->assertNotNull(new Factorial);}

Page 16: Commencer avec le tdd

class Factorial {}

Page 17: Commencer avec le tdd

/** @test */public function factOf1() {

$facto = new Factorial;$this->assertSame(1, $facto->fact(1));

}

Page 18: Commencer avec le tdd

public function fact($number) {return 1;

}

Page 19: Commencer avec le tdd

Duplication

public function create() {$this->assertNotNull(new Factorial);

}

public function factOf1() {$facto = new Factorial;

...

Page 20: Commencer avec le tdd

public function setup() {$this->facto = new Factorial;

}/** @test */public function factOf1() {

$this->assertSame(1, $this->facto->fact(1));}

Page 21: Commencer avec le tdd

/** @test */public function factOf2() {

$this->assertSame(2, $this->facto->fact(2));}

Page 22: Commencer avec le tdd

public function fact($number) {return $number;

}

Page 23: Commencer avec le tdd

Encore de la duplication

/** @test */public function factOf1() {

$this->assertSame(1, $this->facto->fact(1));}/** @test */public function factOf2() {

$this->assertSame(2, $this->facto->fact(2));}

Page 24: Commencer avec le tdd

public function factDataProvider() {return array(

array(1, 1),array(2, 2),

);}

Page 25: Commencer avec le tdd

/** * @test * @dataProvider factDataProvider */public function factorial($number, $expected) {

$result = $this->facto->fact($number);$this->assertSame($expected, $result);

}

Page 26: Commencer avec le tdd

array(3, 6,),

Page 27: Commencer avec le tdd

array(3, 6,),

public function fact($number) {if ($number < 2) return 1;return $number * $this->fact($number - 1);

}

Page 28: Commencer avec le tdd

Les 3 lois du TDD selon Uncle Bob

● Ne jamais écrire du code de production sauf pour faire passer un test unitaire qui échoue

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

Page 29: Commencer avec le tdd

Les 3 lois du TDD selon Uncle Bob

● Ne jamais écrire du code de production sauf pour faire passer un test unitaire qui échoue

● Ne pas écrire plus de test que nécéssaire pour avoir un échec○ une erreur de compilation est un échec

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

Page 30: Commencer avec le tdd

Les 3 lois du TDD selon Uncle Bob

● Ne jamais écrire du code de production sauf pour faire passer un test unitaire qui échoue

● Ne pas écrire plus de test que nécéssaire pour avoir un échec○ une erreur de compilation est un échec

● Ne pas écrire plus de code de production que nécéssaire pour faire passer le test unitaire

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

Page 31: Commencer avec le tdd

Beaucoup de travail

Page 32: Commencer avec le tdd

Photo: Adam Melanconhttp://www.flickr.com/photos/melancon/348974082/

Page 33: Commencer avec le tdd

Les dépendances

Zhent_http://www.flickr.com/photos/zhent/574472488/in/faves-96579472@N07/

Page 34: Commencer avec le tdd

Les fichiers

Ryan Vettesehttp://www.flickr.com/photos/rvettese/383453435/

Page 35: Commencer avec le tdd

vfsStream

Système de fichier virtuel

composer.json"require-dev": {

"mikey179/vfsStream": "*"},

Page 36: Commencer avec le tdd

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

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

//Code qui créer un sous répertoire$this->createDir($parentDir, 'test');

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

Page 37: Commencer avec le tdd

Lire un fichier

$struct = array('subDir' => array('test.txt' => 'contenu')

);$root = vfsStream::setup('root', null, $struct);$parentDir = $root->url('root');

$content = file_get_contents($parentDir . '/subDir/test.txt');$this->assertSame('contenu' , $content);

Page 38: Commencer avec le tdd

La base de données

shindoversehttp://www.flickr.com/photos/shindotv/3835363999/

Page 39: Commencer avec le tdd

Les Mocks

Permet de remplacer une dépendance

● PHPUnit mocks● Mockery● Phake

Page 40: Commencer avec le tdd

Création

$mock = $this->getMock('\Namespace\Classe');

Page 41: Commencer avec le tdd

Création

$mock = $this->getMock('\Namespace\Classe');

Ou

$mock =$this->getMockBuilder ('\Namespace\Classe') ->disableOriginalConstructor() ->getMock();

Page 42: Commencer avec le tdd

$mock->expect($this->once()) ->method('nomMéthode')

Page 43: Commencer avec le tdd

$mock->expect($this->once()) ->method('nomMéthode') ->with(1, 'aa', $this->anything())

Page 44: Commencer avec le tdd

$mock->expect($this->once()) ->method('nomMéthode') ->with(1, 'aa', $this->anything()) ->will($this->returnValue(10));

Page 45: Commencer avec le tdd

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, 'name' => 'Eric Hogue'))));

Page 46: Commencer avec le tdd

$pdo = $this->getMockBuilder('\stdClass')->disableOriginalConstructor()->setMethods(array('prepare'))->getMock();

$pdo->expects($this->once())->method('prepare')->will($this->returnValue($statement));

Page 47: Commencer avec le tdd

Pour utiliser PDO

$this->getMockBuilder('\PDO')

Page 48: Commencer avec le tdd

class PDOMock extends \PDO { public function __construct() {}

}

$pdo = $this->getMockBuilder('\PDOMock')->getMock();

Page 49: Commencer avec le tdd

mysql_*

Eliot Phillipshttp://www.flickr.com/photos/hackaday/5553713944/

Page 50: Commencer avec le tdd

L'extension DbUnit

extends PHPUnit_Extensions_Database_TestCase

public function getConnection() { $pdo = new PDO('sqlite::memory:');

return $this->createDefaultDBConnection($pdo, ':memory:');

}

Page 51: Commencer avec le tdd

public function getDataSet() {return $this->createFlatXMLDataSet('file');

}

Page 52: Commencer avec le tdd

API

Page 53: Commencer avec le tdd

● Mettre tous les appels HTTP dans une classe○ Zend\Http○ Simple classe qui appel curl

● Faire un mock de cette classe○ Retourne le xml/json voulu

Page 54: Commencer avec le tdd

Avantages - Inconvénients

Page 55: Commencer avec le tdd

Avantages du TDD

● Moins de régression

Page 56: Commencer avec le tdd

Avantages du TDD

● Moins de régression● Plus de confiance

Page 57: Commencer avec le tdd

Avantages du TDD

● Moins de régression● Plus de confiance● Couplage plus faible

Page 58: Commencer avec le tdd

Avantages du TDD

● Moins de régression● Plus de confiance● Couplage plus faible● Design plus simple

Page 59: Commencer avec le tdd

Inconvénients du TDD

● Plus long

Page 60: Commencer avec le tdd

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

Improve Ithttp://www.flickr.com/photos/improveit/1573943815/

Page 61: Commencer avec le tdd

Inconvénients du TDD

● Plus long● Difficile à vendre aux gestionnaires

Page 62: Commencer avec le tdd

Inconvénients du TDD

● Plus long● Difficile à vendre aux gestionnaires● C'est difficile

Page 63: Commencer avec le tdd

Prochaines étapes?

Page 64: Commencer avec le tdd

Continuous Testing

Page 65: Commencer avec le tdd

BDD

● phpspec● Codeception● Behat

○ Mink + Goutte/Selenium

Page 66: Commencer avec le tdd

Behat + Mink

Feature: Add a new postIn order to post the next meetupAs an admin userI want to add a new event

Page 67: Commencer avec le tdd

Scenario: View eventsGiven I am on "/"When I go to "evenement"Then I should see "Commencer avec le

TDD"

Page 68: Commencer avec le tdd

Intégration Continue

Page 69: Commencer avec le tdd

Intégration Continue

● Exécute les tests automatiquement○ tests unitaires○ tests d'acceptation○ tests de performace ○ ...

Page 70: Commencer avec le tdd

Intégration Continue

● Exécute les tests automatiquement○ tests unitaires○ tests d'acceptation○ tests de performace ○ ...

● Vérifie que les standards sont respectés○ phpcs

Page 71: Commencer avec le tdd

Intégration Continue

● Exécute les tests automatiquement○ tests unitaires○ tests d'acceptation○ tests de performace ○ ...

● Vérifie que les standards sont respectés○ phpcs

● Détecte des "code smells"○ phploc○ phpcpd○ PHP Depend○ PHP Mess Detector

Page 72: Commencer avec le tdd

Damián Navashttp://www.flickr.com/photos/wingedwolf/5471047557/

Commentaires:https://joind.in/8740

Twitter:@ehogue

Blogue:http://erichogue.ca/

Questions