Successfully reported this slideshow.
Your SlideShare is downloading. ×

Commencer avec le TDD

Commencer avec le TDD

Download to read offline

Talk given in French at ConFoo 2015

Le TDD (Test Driven Development) gagne en popularité dans la communauté PHP. C’est maintenant une pratique accepté. Mais commencer peut sembler difficile.

Dans cette session, nous allons voir ce qu’est le TDD. Nous allons commencer par voir les principes. Puis les outils utilisés, et comment s’en servir au quotidien. Nous allons aussi voir les difficultés souvent rencontrées et comment les contourner.

Talk given in French at ConFoo 2015

Le TDD (Test Driven Development) gagne en popularité dans la communauté PHP. C’est maintenant une pratique accepté. Mais commencer peut sembler difficile.

Dans cette session, nous allons voir ce qu’est le TDD. Nous allons commencer par voir les principes. Puis les outils utilisés, et comment s’en servir au quotidien. Nous allons aussi voir les difficultés souvent rencontrées et comment les contourner.

Advertisement
Advertisement

More Related Content

Advertisement
Advertisement

Commencer avec le TDD

  1. 1. Commencer avec le TDD Eric Hogue - @ehogue Confoo - 2014-02-27 1
  2. 2. TDD 2
  3. 3. Où commencer? 3
  4. 4. Tests unitaires 4
  5. 5. 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
  6. 6. Ne pas traverser de frontières 6
  7. 7. Outils ● SimpleTest ● atoum ● PHPT ● PHPUnit 7
  8. 8. 8
  9. 9. Installation - Phar $ wget https://phar.phpunit.de/phpunit.phar $ chmod +x phpunit.phar $ mv phpunit.phar /usr/local/bin/phpunit 9
  10. 10. Installation - Composer # composer.json { "require-dev": { "phpunit/phpunit": "4.5.*" } } $ composer install 10
  11. 11. PHPUnit FactorialTest.php <?php class FactorialTest extends PHPUnit_Framework_TestCase { } 11
  12. 12. public function testSomething() { } /** @test */ public function somethingElse() { } 12
  13. 13. ● Arrange ● Act ● Assert 13
  14. 14. Arrange /** @test */ public function factOf1() { $factorial = new Factorial; } 14
  15. 15. Act /** @test */ public function factOf1() { $factorial = new Factorial; $result = $factorial->fact(1); } 15
  16. 16. Assert /** @test */ public function factOf1() { $factorial = new Factorial; $result = $factorial->fact(1); $this->assertSame(1, $result); } 16
  17. 17. PHPUnit Assertions ● $this->assertTrue(); ● $this->assertEquals(); ● $this->assertSame(); ● $this->assertContains(); ● $this->assertNull(); ● $this->assertRegExp(); ● ... 17
  18. 18. Preparing For Your Tests setup() -> Avant chaque test teardown() -> Après chaque test setUpBeforeClass() + tearDownAfterClass() Une fois par test 18
  19. 19. 19
  20. 20. TDD 20
  21. 21. 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.TheThreeRulesOfTdd 21
  22. 22. Red - Green - Refactor Red Écrire un test qui échoue 22
  23. 23. Red - Green - Refactor Green Le faire passer 23
  24. 24. Red - Green - Refactor Refactor Régler les raccourcis pris 24
  25. 25. /** @test */ public function create() { $this->assertNotNull(new Factorial); } 25
  26. 26. class Factorial { } 26
  27. 27. /** @test */ public function factOf1() { $facto = new Factorial; $this->assertSame(1, $facto->fact(1)); } 27
  28. 28. public function fact($number) { return 1; } 28
  29. 29. Duplication public function create() { $this->assertNotNull(new Factorial); } public function factOf1() { $facto = new Factorial; ... 29
  30. 30. public function setup() { $this->facto = new Factorial; } /** @test */ public function factOf1() { $this->assertSame(1, $this->facto->fact(1)); } 30
  31. 31. /** @test */ public function factOf2() { $this->assertSame(2, $this->facto->fact(2)); } 31
  32. 32. public function fact($number) { return $number; } 32
  33. 33. 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
  34. 34. public function factDataProvider() { return [ [1, 1], [2, 2], ]; } 34
  35. 35. /** * @test * @dataProvider factDataProvider */ public function factorial($number, $expected) { ... 35
  36. 36. … $result = $this->facto->fact($number); $this->assertSame($expected, $result); } 36
  37. 37. public function factDataProvider() { … [2, 2], [3, 6], ... 37
  38. 38. public function fact($number) { if ($number < 2) return 1; return $number * $this->fact($number - 1); } 38
  39. 39. Beaucoup de travail 39
  40. 40. 40
  41. 41. Dépendances 41
  42. 42. Problème class Foo { public function __construct() { $this->bar = new Bar; } } 42
  43. 43. Injection des dépendances 43
  44. 44. Setter Injection class Foo { public function setBar(Bar $bar) { $this->bar = $bar; } } public function doSomething() { // Use $this->bar } 44
  45. 45. Constructor Injection class Foo { public function __construct( Bar $bar) { $this->bar = $bar; } ... } 45
  46. 46. Passer la dépendance aux méthodes class Foo { public function doSomething( Bar $bar) { // Use $bar } } 46
  47. 47. Système de fichiers 47
  48. 48. vfsStream Système de fichier virtuel composer.json "require-dev": { "mikey179/vfsStream": "*" }, 48
  49. 49. 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
  50. 50. Lire un fichier $struct = [ 'subDir' => ['test.txt' => 'content'] ]; $root = vfsStream::setup('root', null, $struct); $parentDir = $root->url('root'); ... 50
  51. 51. Lire un fichier … $content = file_get_contents( $parentDir . '/subDir/test.txt'); $this->assertSame('content', $content); 51
  52. 52. Base de données 52
  53. 53. Mocks Remplace une dépendance ● PHPUnit mocks ● Mockery ● Phake 53
  54. 54. Création $mock = $this->getMock('NSClass'); $mock = $this->getMockBuilder ('NamespaceClass') ->disableOriginalConstructor() ->getMock(); 54
  55. 55. $mock->expects($this->once()) ->method('methodName') 55
  56. 56. $mock->expects($this->once()) ->method('methodName') ->with(1, 'aa', $this->anything()) 56
  57. 57. $mock->expects($this->once()) ->method('methodName') ->with(1, 'aa', $this->anything()) ->will($this->returnValue(10)); 57
  58. 58. Mocking PDO $statement = $this->getMockBuilder ('PDOStatement') ->getMock(); $statement->expects($this->once()) ->method('execute') ->will($this->returnValue(true)); ... 58
  59. 59. ... $statement->expects($this->once()) ->method('fetchAll') ->will( $this->returnValue( [['id' => 123]] ) ); ... 59
  60. 60. $this->getMockBuilder('PDO') ->getMock(); 60
  61. 61. … $pdo = $this->getMockBuilder( 'stdClass') ->setMethods(['prepare']) ->getMock(); $pdo->expects($this->once()) ->method('prepare') ->will( $this->returnValue($statement)); 61
  62. 62. class PDOMock extends PDO { public function __construct() {} } $pdo = $this->getMockBuilder ('PDOMock') ->getMock(); 62
  63. 63. mysql_* 63
  64. 64. DbUnit extends PHPUnit_Extensions_Database_TestCase public function getConnection() { $pdo = new PDO('sqlite::memory:'); return $this-> createDefaultDBConnection( $pdo, ':memory:'); } 64
  65. 65. public function getDataSet() { return $this-> createFlatXMLDataSet('file'); } 65
  66. 66. API 66
  67. 67. ● Encapsuler ○ ZendHttp ○ Guzzle ○ Classe qui utilise curl ● Mock ○ Retourner le xml/json voulu 67
  68. 68. Avantages et inconvénients 68
  69. 69. Avantages 69
  70. 70. Inconvénients 70
  71. 71. “If it doesn't have to work, I can get it done a lot faster!” - Kent Beck 71
  72. 72. Inconvénients 72
  73. 73. Prochaines étapes? 73
  74. 74. Tests en continue - Guard 74
  75. 75. Intégration continue 75
  76. 76. Commentaires: https://joind.in/13312 twitter: @ehogue PHP Mentoring: http://phpmentoring.org/ Questions? 76
  77. 77. 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

×