Commencer avec le tdd
-
Upload
eric-hogue -
Category
Technology
-
view
7.260 -
download
1
description
Transcript of Commencer avec le tdd
Commencer avec le TDDEric Hogue
PHP Québec - 2013-06-06
Test Driven Development
Où Commencer?
Les tests unitaires
Test automatisé qui exerce une seule unité de code
Outils
● PHPUnit● SimpleTest● atoum● PHPT
PHPUnit
FactorialTest.php<?phpclass FactorialTest extends \PHPUnit_Framework_TestCase {}
public function testSomething() {}
/** @test */public function somethingElse() {}
Les assertions
● $this->assertTrue();● $this->assertEquals();● $this->assertSame();● $this->assertContains();● $this->assertNull();● $this->assertRegExp();● ...
Préparation des tests
setup() -> Avant chaque testteardown() -> Après chaque test
phpunit.xml
<phpunit bootstrap="bootstrap.php" colors="true"strict="true"verbose="true"
>...
</phpunit>
Le TDD
nyuhuhuuhttp://www.flickr.com/photos/nyuhuhuu/4442144329/
Red - Green - Refactor
Rouge Un test qui échoue
Red - Green - Refactor
VertFaire passer le test
Red - Green - Refactor
RefactorArranger le code
/** @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;
}
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));}
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);
}
array(3, 6,),
array(3, 6,),
public function fact($number) {if ($number < 2) return 1;return $number * $this->fact($number - 1);
}
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
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
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
Beaucoup de travail
Photo: Adam Melanconhttp://www.flickr.com/photos/melancon/348974082/
Les dépendances
Zhent_http://www.flickr.com/photos/zhent/574472488/in/faves-96579472@N07/
Les fichiers
Ryan Vettesehttp://www.flickr.com/photos/rvettese/383453435/
vfsStream
Système de fichier virtuel
composer.json"require-dev": {
"mikey179/vfsStream": "*"},
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'));
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);
La base de données
shindoversehttp://www.flickr.com/photos/shindotv/3835363999/
Les Mocks
Permet de remplacer une dépendance
● PHPUnit mocks● Mockery● Phake
Création
$mock = $this->getMock('\Namespace\Classe');
Création
$mock = $this->getMock('\Namespace\Classe');
Ou
$mock =$this->getMockBuilder ('\Namespace\Classe') ->disableOriginalConstructor() ->getMock();
$mock->expect($this->once()) ->method('nomMéthode')
$mock->expect($this->once()) ->method('nomMéthode') ->with(1, 'aa', $this->anything())
$mock->expect($this->once()) ->method('nomMéthode') ->with(1, 'aa', $this->anything()) ->will($this->returnValue(10));
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'))));
$pdo = $this->getMockBuilder('\stdClass')->disableOriginalConstructor()->setMethods(array('prepare'))->getMock();
$pdo->expects($this->once())->method('prepare')->will($this->returnValue($statement));
Pour utiliser PDO
$this->getMockBuilder('\PDO')
class PDOMock extends \PDO { public function __construct() {}
}
$pdo = $this->getMockBuilder('\PDOMock')->getMock();
mysql_*
Eliot Phillipshttp://www.flickr.com/photos/hackaday/5553713944/
L'extension DbUnit
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
● 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
Avantages - Inconvénients
Avantages du TDD
● Moins de régression
Avantages du TDD
● Moins de régression● Plus de confiance
Avantages du TDD
● Moins de régression● Plus de confiance● Couplage plus faible
Avantages du TDD
● Moins de régression● Plus de confiance● Couplage plus faible● Design plus simple
Inconvénients du TDD
● Plus long
“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/
Inconvénients du TDD
● Plus long● Difficile à vendre aux gestionnaires
Inconvénients du TDD
● Plus long● Difficile à vendre aux gestionnaires● C'est difficile
Prochaines étapes?
Continuous Testing
BDD
● phpspec● Codeception● Behat
○ Mink + Goutte/Selenium
Behat + Mink
Feature: Add a new postIn order to post the next meetupAs an admin userI want to add a new event
Scenario: View eventsGiven I am on "/"When I go to "evenement"Then I should see "Commencer avec le
TDD"
Intégration Continue
Intégration Continue
● Exécute les tests automatiquement○ tests unitaires○ tests d'acceptation○ tests de performace ○ ...
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
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
Damián Navashttp://www.flickr.com/photos/wingedwolf/5471047557/
Commentaires:https://joind.in/8740
Twitter:@ehogue
Blogue:http://erichogue.ca/
Questions