commencer avec le tdd
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
![Page 1: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/1.jpg)
Commencer avec le TDDEric Hogue
PHP Québec - 2013-06-06
![Page 2: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/2.jpg)
Test Driven Development
![Page 3: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/3.jpg)
Où Commencer?
![Page 4: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/4.jpg)
Les tests unitaires
Test automatisé qui exerce une seule unité de code
![Page 5: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/5.jpg)
Outils
● PHPUnit● SimpleTest● atoum● PHPT
![Page 6: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/6.jpg)
PHPUnit
FactorialTest.php<?phpclass FactorialTest extends \PHPUnit_Framework_TestCase {}
![Page 7: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/7.jpg)
public function testSomething() {}
/** @test */public function somethingElse() {}
![Page 8: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/8.jpg)
Les assertions
● $this->assertTrue();● $this->assertEquals();● $this->assertSame();● $this->assertContains();● $this->assertNull();● $this->assertRegExp();● ...
![Page 9: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/9.jpg)
Préparation des tests
setup() -> Avant chaque testteardown() -> Après chaque test
![Page 10: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/10.jpg)
phpunit.xml
<phpunit bootstrap="bootstrap.php" colors="true"strict="true"verbose="true"
>...
</phpunit>
![Page 11: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/11.jpg)
Le TDD
nyuhuhuuhttp://www.flickr.com/photos/nyuhuhuu/4442144329/
![Page 12: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/12.jpg)
Red - Green - Refactor
Rouge Un test qui échoue
![Page 13: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/13.jpg)
Red - Green - Refactor
VertFaire passer le test
![Page 14: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/14.jpg)
Red - Green - Refactor
RefactorArranger le code
![Page 15: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/15.jpg)
/** @test */public function create() {
$this->assertNotNull(new Factorial);}
![Page 16: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/16.jpg)
class Factorial {}
![Page 17: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/17.jpg)
/** @test */public function factOf1() {
$facto = new Factorial;$this->assertSame(1, $facto->fact(1));
}
![Page 18: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/18.jpg)
public function fact($number) {return 1;
}
![Page 19: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/19.jpg)
Duplication
public function create() {$this->assertNotNull(new Factorial);
}
public function factOf1() {$facto = new Factorial;
...
![Page 20: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/20.jpg)
public function setup() {$this->facto = new Factorial;
}/** @test */public function factOf1() {
$this->assertSame(1, $this->facto->fact(1));}
![Page 21: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/21.jpg)
/** @test */public function factOf2() {
$this->assertSame(2, $this->facto->fact(2));}
![Page 22: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/22.jpg)
public function fact($number) {return $number;
}
![Page 23: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/23.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/24.jpg)
public function factDataProvider() {return array(
array(1, 1),array(2, 2),
);}
![Page 25: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/25.jpg)
/** * @test * @dataProvider factDataProvider */public function factorial($number, $expected) {
$result = $this->facto->fact($number);$this->assertSame($expected, $result);
}
![Page 26: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/26.jpg)
array(3, 6,),
![Page 27: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/27.jpg)
array(3, 6,),
public function fact($number) {if ($number < 2) return 1;return $number * $this->fact($number - 1);
}
![Page 28: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/28.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/29.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/30.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/31.jpg)
Beaucoup de travail
![Page 32: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/32.jpg)
Photo: Adam Melanconhttp://www.flickr.com/photos/melancon/348974082/
![Page 33: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/33.jpg)
Les dépendances
Zhent_http://www.flickr.com/photos/zhent/574472488/in/faves-96579472@N07/
![Page 34: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/34.jpg)
Les fichiers
Ryan Vettesehttp://www.flickr.com/photos/rvettese/383453435/
![Page 35: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/35.jpg)
vfsStream
Système de fichier virtuel
composer.json"require-dev": {
"mikey179/vfsStream": "*"},
![Page 36: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/36.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/37.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/38.jpg)
La base de données
shindoversehttp://www.flickr.com/photos/shindotv/3835363999/
![Page 39: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/39.jpg)
Les Mocks
Permet de remplacer une dépendance
● PHPUnit mocks● Mockery● Phake
![Page 40: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/40.jpg)
Création
$mock = $this->getMock('\Namespace\Classe');
![Page 41: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/41.jpg)
Création
$mock = $this->getMock('\Namespace\Classe');
Ou
$mock =$this->getMockBuilder ('\Namespace\Classe') ->disableOriginalConstructor() ->getMock();
![Page 42: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/42.jpg)
$mock->expect($this->once()) ->method('nomMéthode')
![Page 43: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/43.jpg)
$mock->expect($this->once()) ->method('nomMéthode') ->with(1, 'aa', $this->anything())
![Page 44: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/44.jpg)
$mock->expect($this->once()) ->method('nomMéthode') ->with(1, 'aa', $this->anything()) ->will($this->returnValue(10));
![Page 45: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/45.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/46.jpg)
$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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/47.jpg)
Pour utiliser PDO
$this->getMockBuilder('\PDO')
![Page 48: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/48.jpg)
class PDOMock extends \PDO { public function __construct() {}
}
$pdo = $this->getMockBuilder('\PDOMock')->getMock();
![Page 49: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/49.jpg)
mysql_*
Eliot Phillipshttp://www.flickr.com/photos/hackaday/5553713944/
![Page 50: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/50.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/51.jpg)
public function getDataSet() {return $this->createFlatXMLDataSet('file');
}
![Page 52: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/52.jpg)
API
![Page 53: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/53.jpg)
● 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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/54.jpg)
Avantages - Inconvénients
![Page 55: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/55.jpg)
Avantages du TDD
● Moins de régression
![Page 56: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/56.jpg)
Avantages du TDD
● Moins de régression● Plus de confiance
![Page 57: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/57.jpg)
Avantages du TDD
● Moins de régression● Plus de confiance● Couplage plus faible
![Page 58: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/58.jpg)
Avantages du TDD
● Moins de régression● Plus de confiance● Couplage plus faible● Design plus simple
![Page 59: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/59.jpg)
Inconvénients du TDD
● Plus long
![Page 60: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/60.jpg)
“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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/61.jpg)
Inconvénients du TDD
● Plus long● Difficile à vendre aux gestionnaires
![Page 62: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/62.jpg)
Inconvénients du TDD
● Plus long● Difficile à vendre aux gestionnaires● C'est difficile
![Page 63: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/63.jpg)
Prochaines étapes?
![Page 64: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/64.jpg)
Continuous Testing
![Page 65: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/65.jpg)
BDD
● phpspec● Codeception● Behat
○ Mink + Goutte/Selenium
![Page 66: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/66.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/67.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/68.jpg)
Intégration Continue
![Page 69: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/69.jpg)
Intégration Continue
● Exécute les tests automatiquement○ tests unitaires○ tests d'acceptation○ tests de performace ○ ...
![Page 70: Commencer avec le tdd](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/70.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/71.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022052621/558a2939d8b42a3e028b45be/html5/thumbnails/72.jpg)
Damián Navashttp://www.flickr.com/photos/wingedwolf/5471047557/
Commentaires:https://joind.in/8740
Twitter:@ehogue
Blogue:http://erichogue.ca/
Questions