recettes de tests
TRANSCRIPT
RECETTES de
TESTSCharles Desneuf - @SelrahcD
@SelrahcD
Photo by Dan Gold on Unsplash
Découvrir des bugs Permettre de réfactorer
Documenter Réfléchir à l’interface du système Détecter des problèmes de design
Photo by Brooke Lark on Unsplash
Découvrir des bugs Permettre de réfactorer
Documenter Réfléchir à l’interface du système Détecter des problèmes de design
Photo by Brooke Lark on Unsplash
Découvrir des bugs Permettre de réfactorer
Documenter Réfléchir à l’interface du système Détecter des problèmes de design
Photo by Brooke Lark on Unsplash
Découvrir des bugs Permettre de réfactorer
Documenter Réfléchir à l’interface du système
Détecter des problèmes de designPhoto by Brooke Lark on Unsplash
Découvrir des bugs Permettre de réfactorer
Documenter Réfléchir à l’interface du système
Détecter des problèmes de designPhoto by Brooke Lark on Unsplash
Indépendants de l’implémentation Décrire le comportement du système
Avoir un résultat prédictible Rapides
Indépendants les uns des autres Simple à mettre en place
Photo by Brooke Lark on Unsplash
Indépendants de l’implémentation Décrire le comportement du système
Avoir un résultat prédictible Rapides
Indépendants les uns des autres Simple à mettre en place
Photo by Brooke Lark on Unsplash
Indépendants de l’implémentation Décrire le comportement du système Avoir un résultat prédictible
Rapides Indépendants les uns des autres
Simple à mettre en placePhoto by Brooke Lark on Unsplash
Indépendants de l’implémentation Décrire le comportement du système
Avoir un résultat prédictible Rapides
Indépendants les uns des autres Simple à mettre en place
Photo by Brooke Lark on Unsplash
Indépendants de l’implémentation Décrire le comportement du système
Avoir un résultat prédictible Rapides
Indépendants les uns des autres Simple à mettre en place
Photo by Brooke Lark on Unsplash
Indépendants de l’implémentation Décrire le comportement du système
Avoir un résultat prédictible Rapides
Indépendants les uns des autres Simple à mettre en place
Photo by Brooke Lark on Unsplash
PHPUnit Prophecy
Photo by Scott Umstattd on Unsplash
ANATOMIE D’UN
TEST
Photo by Michael Browning on Unsplash
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
public function testIlAnnonceLePlatDuJour()
public function test_il_annonce_le_plat_du_jour()
/** * @test */ public function il_annonce_le_plat_du_jour()
/** * @test */ public function il annonce le plat du jour()
public function he_should_announce_todays_special()
public function he_announces_todays_special()
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
➜ recettes phpunit --testdox tests/ServeurTest.php
PHPUnit 4.7.6 by Sebastian Bergmann and contributors.
Serveur
[x] il annonce le plat du jour
[x] il transmet une commande pour le plat du jour a la cuisine
➜ recettes phpunit --testdox tests/ServeurTest.php
PHPUnit 4.7.6 by Sebastian Bergmann and contributors.
Serveur
[x] il annonce le plat du jour
[x] il transmet une commande pour le plat du jour a la cuisine
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
Photo by Gemma Evans on Unsplash
ARRANGE
ACT
ASSERT
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
Arrange
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
Act
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); } }
Assert
ARRANGE ACT ASSERT
GIVEN WHEN THEN
Photo by Baher Khairy on Unsplash
public function test_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlat() ->willReturn('Gencives de porc !') ->shouldBeCalledTimes(1);
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); }
class Serveur {
public function annonceLeMenu() { $plat = $this->cuisine->quelEstLePlatDuJour();
// fait autre chose, oublie le menu
$plat = $this->cuisine->quelEstLePlatDuJour();
return sprintf( 'Le chef vous propose aujourd\'hui %s', $this->transformeNomDuPlat($plat) ); } }
class Serveur {
public function annonceLeMenu() { $plat = 'Gencives de porc !';
return sprintf( 'Le chef vous propose aujourd\'hui %s', $this->transformeNomDuPlat($plat) ); } }
public function test_annonce_le_plat_du_jour() {
$cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlat() ->willReturn('Gencives de porc !') ->shouldBeCalledTimes(1);
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); }
public function test_annonce_le_plat_du_jour() { $cuisine = $this->prophesize(Cuisine::class);
$cuisine ->quelEstLePlatDuJour() ->willReturn('Gencives de porc !');
$serveur = new Serveur($cuisine->reveal());
$annonce = $serveur->annonceLePlatDuJour();
$this->assertEquals( 'Le chef vous propose aujourd\'hui des gencives de porc', $annonce ); }
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_la_cuisine() { $cuisine = $this->prophesize(Cuisine::class);
$serveur = new Serveur($cuisine->reveal());
$serveur->recoitUneCommandePourUnPlatDuJour();
$cuisine ->ilFautUnPlatDuJour() ->shouldHaveBeenCalledTimes(1); } }
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_la_cuisine() { $cuisine = $this->prophesize(Cuisine::class);
$serveur = new Serveur($cuisine->reveal());
$serveur->recoitUneCommandePourUnPlatDuJour();
$cuisine ->ilFautUnPlatDuJour() ->shouldHaveBeenCalledTimes(1); } }
Arrange
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_la_cuisine() { $cuisine = $this->prophesize(Cuisine::class);
$serveur = new Serveur($cuisine->reveal());
$serveur->recoitUneCommandePourUnPlatDuJour();
$cuisine ->ilFautUnPlatDuJour() ->shouldHaveBeenCalledTimes(1); } }
Act
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_la_cuisine() { $cuisine = $this->prophesize(Cuisine::class);
$serveur = new Serveur($cuisine->reveal());
$serveur->recoitUneCommandePourUnPlatDuJour();
$cuisine ->ilFautUnPlatDuJour() ->shouldHaveBeenCalledTimes(1); } }
Assert
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_la_cuisine() { $cuisine = $this->prophesize(Cuisine::class);
$serveur = new Serveur($cuisine->reveal());
$serveur->recoitUneCommandePourUnPlatDuJour();
$cuisine ->ilFautUnPlatDuJour() ->shouldHaveBeenCalledTimes(1); } }
class Serveur {
public function recoitUneCommandePourUnPlatDuJour() { } }
class Serveur {
public function recoitUneCommandePourUnPlatDuJour() { for($i = 0; $i < 100; $i++) { $this->cuisine->ilFautUnPlatDuJour(); } } }
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_la_cuisine() { $cuisine = $this->prophesize(Cuisine::class);
$serveur = new Serveur($cuisine->reveal());
$serveur->recoitUneCommandePourUnPlatDuJour();
$cuisine ->ilFautUnPlatDuJour() ->shouldHaveBeenCalledTimes(1); } }
class Serveur {
public function recoitUneCommandePourUnPlatDuJour() {
$this->cuisine->ilFautUnPlatDuJour();
} }
class ServeurTest extends \PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_la_cuisine() { $cuisine = $this->prophesize(Cuisine::class);
$serveur = new Serveur($cuisine->reveal());
$serveur->recoitUneCommandePourUnPlatDuJour();
$cuisine ->ilFautUnPlatDuJour() ->shouldHaveBeenCalledTimes(1); } }
Mock Arrange
Spy Assert
Photo by Alexander Maasch on Unsplash
EGALITE
DES
OBJETSPhoto by Brenan Greene on Unsplash
class PizzaioloTest extends \PHPUnit_Framework_TestCase {
public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePizzaMargheritaMaison();
$this->assertEquals( ['pate', 'sauce tomate', 'basilic', 'mozzarella'], $pizza->ingredients() ); } }
class PizzaSurgelee { public function __construct($ingredients) { $this->ingredients = $ingredients; }
public function ingredients() { return $this->ingredients; } }
class Pizzaiolo {
public function preparePizzaMargheritaMaison(){
$pizzaSurgelee = $this->acheteUnePizzaMargheritaSurgelee();
return $this->rechauffeLaPizza($pizzaSurgelee); } }
public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePizzaMargheritaMaison();
$this->assertEquals( ['pate', 'sauce tomate', 'basilic', 'mozzarella'], $pizza->ingredients() ); }
class PizzaioloTest extends \PHPUnit_Framework_TestCase {
public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePizzaMargheritaMaison();
$this->assertEquals( new PizzaMaison(['pate', 'sauce tomate', 'basilic', 'mozzarella']), $pizza ); } }
public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePizzaMargheritaMaison();
$this->assertEquals( new PizzaMaison(['pate', 'sauce tomate', 'basilic', 'mozzarella']), $pizza ); }
class Pizzaiolo { public function preparePizzaMargheritaMaison() {
$pateAPizza = new PateAPizza();
$this->etaleLaPate($pateAPizza);
$this->enduitDeSauceTomate($pateAPizza);
$this->disposeLaMozzarella($pateAPizza);
$this->placeLeBasilic($pateAPizza);
return $this->cuire($pateAPizza);
} }
public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePizzaMargheritaMaison();
$this->assertEquals( new PizzaMaison(['pate', 'sauce tomate', 'basilic', 'mozzarella']), $pizza ); }
class PizzaMaison { public function __construct($ingredients) { $this->ingredients = $ingredients; }
public function ingredients() { return $this->ingredients; } }
class PizzaMaison { public function __construct($ingredients) { $this->ingredients = $ingredients; }
public function ingredients() { return $this->ingredients; } }
TEST CLASS
PER FIXTURE
Photo by Lou Stejskal on Flickr
class EndiveTest extends \PHPUnit_Framework_TestCase {
public function test_une_endive_de_base_est_crue() { $endive = new Endive();
$this->assertTrue($endive->crue()); }
public function test_une_endive_de_base_est_bonne() { $endive = new Endive();
$this->assertTrue($endive->bonne()); }
public function test_une_endive_cuite_nest_pas_crue() { $endive = new Endive();
$endive->cuire();
$this->assertFalse($endive->crue()); }
public function test_une_endive_cuite_nest_pas_bonne() { $endive = new Endive();
$endive->cuire();
$this->assertFalse($endive->bonne()); } }
public function test_une_endive_de_base_est_crue() {
$endive = new Endive();
$this->assertTrue($endive->crue()); }
public function test_une_endive_de_base_est_bonne() {
$endive = new Endive();
$this->assertTrue($endive->bonne()); }
public function test_une_endive_cuite_nest_pas_crue(){
$endive = new Endive();
$endive->cuire();
$this->assertFalse($endive->crue()); }
public function test_une_endive_cuite_nest_pas_bonne() {
$endive = new Endive();
$endive->cuire();
$this->assertFalse($endive->bonne()); }
class UneEndiveDeBaseTest extends \PHPUnit_Framework_TestCase {
public function setUp() { $this->endive = new Endive(); }
public function test_est_crue() { $this->assertTrue($this->endive->crue()); }
public function test_est_bonne() { $this->assertTrue($this->endive->bonne()); } }
class UneEndiveCuiteTest extends \PHPUnit_Framework_TestCase {
public function setUp() { $this->endive = new Endive(); $this->endive->cuire(); }
public function test_nest_pas_crue() { $this->assertFalse($this->endive->crue()); }
public function test_nest_pas_bonne() { $this->assertFalse($this->endive->bonne()); } }
class UneEndiveDeBaseTest extends \PHPUnit_Framework_TestCase {
public function setUp() { $this->endive = new Endive(); }
public function test_est_crue() { $this->assertTrue($this->endive->crue()); }
public function test_est_bonne() { $this->assertTrue($this->endive->bonne()); } }
class UneEndiveCuiteTest extends \PHPUnit_Framework_TestCase {
public function setUp() { $this->endive = new Endive(); $this->endive->cuire(); }
public function test_nest_pas_crue() { $this->assertFalse($this->endive->crue()); }
public function test_nest_pas_bonne() { $this->assertFalse($this->endive->bonne()); } }
class UneEndiveDeBaseTest extends \PHPUnit_Framework_TestCase {
public function setUp() { $this->endive = new Endive(); }
public function test_est_crue() { $this->assertTrue($this->endive->crue()); }
public function test_est_bonne() { $this->assertTrue($this->endive->bonne()); } }
// UneEndiveDeBaseTest.php
public function setUp() { $this->endive = new Endive(); }
// UneEndiveCuiteTest.php
public function setUp() { $this->endive = new Endive(); $this->endive->cuire(); }
class UneEndiveCrueTest extends \PHPUnit_Framework_TestCase {
public function setUp() { $this->endive = new Endive(); }
}
class UneEndiveCrueTest extends \PHPUnit_Framework_TestCase {
public function setUp() { $this->endive = new Endive(); }
}
class Endive { public static function crue() { return new self(); } }
class UneEndiveCrueTest extends \PHPUnit_Framework_TestCase {
public function setUp() {
$this->endive = Endive::crue();
}
}
DON’T MOCK
WHAT YOU
DON’T OWNPhoto by Naomi Hébert on Unsplash
class GratinTest extends \PHPUnit_Framework_TestCase {
public function test_cuit_au_four_donne_un_gratin_croustillant() {
$gratin = new Gratin();
$realistisk = new Realistisk();
$plat = $gratin->cuireAvec($realistisk, self::50_MINUTES);
$this->assertEquals(new GratinCroustillant(), $plat); } }
namespace IKEA;
class Realistisk {
/** * @return Tallrik */ public function laga($tallrik, $varaktighet) {
sleep($varaktighet);
return $this->fårEnVarmTallrik(get_class($tallrik) , $varaktighet); } }
public function test_cuit_au_four_donne_un_gratin_croustillant() {
$gratin = new Gratin();
$realistisk = new Realistisk();
$plat = $gratin->cuireAvec($realistisk, self::50_MINUTES);
$this->assertEquals(new GratinCroustillant(), $plat); }
public function test_cuit_au_four_donne_un_gratin_croustillant() { $gratin = new Gratin();
$tallrik = $this->prophesize(Tallrik::class);
$tallrik->fåTallrik() ->willReturn(new GratinCroustillant());
$realistisk = $this->prophesize(Realistisk::class);
$realistisk->laga($gratin, self::50_MINUTES) ->willReturn(function() use($tallrik){ return $tallrik->reveal(); });
$plat = $gratin->cuireAvec($realistisk->reveal(), self::50_MINUTES);
$this->assertEquals(new GratinCroustillant(), $plat); }
class Realistisk {
public function laga($tallrik, $varaktighet) {
sleep($duree);
return $this->fårEnKallTallrik(get_class($tallrik), $varaktighet); } }
public function test_cuit_au_four_donne_un_gratin_croustillant() { $gratin = new Gratin();
$tallrik = $this->prophesize(Tallrik::class);
$tallrik->fåTallrik() ->willReturn(new GratinCroustillant());
$realistisk = $this->prophesize(Realistisk::class);
$realistisk->laga($gratin, self::50_MINUTES) ->willReturn(function() use($tallrik){ return $tallrik->reveal(); });
$plat = $gratin->cuireAvec($realistisk->reveal(), self::50_MINUTES);
$this->assertEquals(new GratinCroustillant(), $plat); }
public function test_cuit_au_four_donne_un_gratin_croustillant() {
$gratin = new Gratin();
$realistisk = new Realistisk();
$plat = $gratin->cuireAvec($realistisk, self::50_MINUTES);
$this->assertEquals(new GratinCroustillant(), $plat); }
public function test_cuit_au_four_donne_un_gratin_croustillant() {
$gratin = new Gratin();
$realistisk = new Realistisk();
$plat = $gratin->cuireAvec($realistisk, self::50_MINUTES);
$this->assertEquals(new GratinCroustillant(), $plat); }
public function test_cuit_au_four_donne_un_gratin_croustillant() { $gratin = new Gratin();
$tallrik = $this->prophesize(Tallrik::class);
$tallrik->fåTallrik() ->willReturn(new GratinCroustillant());
$realistisk = $this->prophesize(Realistisk::class);
$realistisk->laga($gratin, self::50_MINUTES) ->willReturn(function() use($tallrik){ return $tallrik->reveal(); });
$plat = $gratin->cuireAvec($realistisk->reveal(), self::50_MINUTES);
$this->assertEquals(new GratinCroustillant(), $plat); }
interface Four {
public function cuire($plat, $duree); }
public function test_cuit_au_four_donne_un_gratin_croustillant() { $gratin = new Gratin();
$four = $this->prophesize(Four::class);
$four->cuire($gratin, self::50_MINUTES) ->willReturn(new GratinCroustillant());
$plat = $gratin->cuireAvec($four->reveal());
$this->assertEquals(new GratinCroustillant(), $plat); }
public function test_cuit_au_four_donne_un_gratin_croustillant() { $gratin = new Gratin();
$four = $this->prophesize(Four::class);
$four->cuire($gratin, self::50_MINUTES) ->willReturn(new GratinCroustillant());
$plat = $gratin->cuireAvec($four->reveal());
$this->assertEquals(new GratinCroustillant(), $plat); }
class LeFourDeLaCuisine implements Four { public function __construct(Realistisk $realistisk) { $this->realistisk = $realistisk; }
public function cuire($plat, $duree) { $tallrik = $this->realistisk->laga($plat, $duree);
return $tallrik->fåTallrik(); } }
class Gratin { public function cuireAvec(Realistisk $realistisk, $duree) {
$tallrik = $realistisk->laga($this, $duree);
return $tallrik->fåTallrik(); } }
class Gratin { public function cuireAvec(Four $four, $duree) {
return $four->cuire($this, $duree); } }
class LeFourDeLaCuisineTest extends PHPUnit_Framework_TestCase { public function test_cuit_un_fromage_de_chevre_en_chevre_chaud() {
$four = new FourDeLaCuisine(new Realistisk());
$plat = $four->cuire(new FromageDeChevre(), self::10_MINUTES);
$this->assertEquals(new ChevreChaud(), $plat); } }
class LeFourDeLaCuisineTest extends PHPUnit_Framework_TestCase { public function test_cuit_un_fromage_de_chevre_en_chevre_chaud() {
$four = new FourDeLaCuisine(new Realistisk());
$plat = $four->cuire(new FromageDeChevre(), self::10_MINUTES);
$this->assertEquals(new ChevreChaud(), $plat); } }
NE DEPENDEZ
PAS DU
SYSTEMEPhoto by James Harris on Unsplash
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite() { $quiche = new Quiche(new Datetime('2017-10-26'));
$this->assertTrue($quiche->peutEtreConsommee()); }
class Quiche { public function __construct(Datetime $dateCuisson) { $this->dateCuisson = $dateCuisson; }
public function peutEtreConsommee() { return $this->dateCuisson->modify('+2 day') < new Datetime(); } }
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite() { $quiche = new Quiche(new Datetime('2017-10-26'));
$this->assertTrue($quiche->peutEtreConsommee()); }
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite() { $quiche = new Quiche(new Datetime('2017-10-26'));
$this->assertTrue($quiche->peutEtreConsommee()); }
class Horloge { public function maintenant() {
return new Datetime();
} }
class Quiche { public function __construct(Datetime $cuisineeLe) { $this->cuisineeLe = $cuisineeLe; }
public function peutEtreConsommee(Horloge $horloge) { return $this->cuisineeLe->modify('+2 day') < $horloge->maintenant(); } }
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite() { $horloge = $this->prophesize(Horloge::class);
$horloge->maintenant()->willReturn(new Datetime('2017-10-27'));
$quiche = new Quiche(new Datetime('2017-10-26'));
$this->assertTrue($quiche->peutEtreConsommee($horloge)); }
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite() { $horloge = $this->prophesize(Horloge::class);
$horloge->maintenant()->willReturn(new Datetime('2017-10-27'));
$quiche = new Quiche(new Datetime('2017-10-26'));
$this->assertTrue($quiche->peutEtreConsommee($horloge)); }
class Quiche {
public function peutEtreConsommeeLe(Datetime $dateDeConsommation) { return $this->cuisineeLe->modify('+2 day') < $dateDeConsommation; } }
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite() { $quiche = new Quiche(new Datetime('2017-10-26'));
$quichePeutEtreConsommee = $quiche ->peutEtreConsommeeLe(new Datetime('2017-10-27'));
$this->assertTrue($quichePeutEtreConsommee); }
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite() { $quiche = new Quiche(new Datetime('2017-10-26'));
$quichePeutEtreConsommee = $quiche ->peutEtreConsommeeLe(new Datetime('2017-10-27'));
$this->assertTrue($quichePeutEtreConsommee); }
OBJECT
MOTHER
Photo by Eaters Collective on Unsplash
class PlatDePatesTest extends \PHPUnit_Framework_TestCase {
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce() { $platDePates = new PlatDePates([ new Ingredient('fromage', 'parmesan'), new Ingredient('viande', 'lardons'), new Ingredient('sauce', 'creme fraiche'), new Ingredient('legume', 'oignon'), ]);
$this->assertTrue($platDePates->estBon()); } }
class Ingredient { public function __construct($type, $nom) { $this->type = $type; $this->nom = $nom; } }
class Ingredient { public function __construct($type, $nom, $DLC) { $this->type = $type; $this->nom = $nom; $this->DLC = $DLC; } }
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce() { $platDePates = new PlatDePates([ new Ingredient('fromage', 'parmesan'), new Ingredient('viande', 'lardons'), new Ingredient('sauce', 'creme fraiche'), new Ingredient('legume', 'oignon'), ]);
$this->assertTrue($platDePates->estBon()); }
class IngredientMother { public static function viande() { return new Ingredient('viande', 'boeuf hache', new Datetime()); }
public static function legume() { return new Ingredient('legume', 'salsifi', new Datetime()); }
public static function fromage() { return new Ingredient('fromage', 'coulommier', new Datetime()); }
public static function sauce() { return new Ingredient('sauce', 'soja', new Datetime()); } }
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce() { $platDePates = new PlatDePates([ IngredientMother::fromage(), IngredientMother::viande(), IngredientMother::sauce(), IngredientMother::legume(), ]);
$this->assertTrue($platDePates->estBon()); }
function uneViande() { return IngredientMother::viande(); }
function unLegume() { return IngredientMother::legume(); }
function unFromage() { return IngredientMother::fromage(); }
function uneSauce() { return IngredientMother::sauce(); }
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce() { $platDePates = new PlatDePates([ unFromage(), uneViande(), uneSauce(), unLegume(), ]);
$this->assertTrue($platDePates->estBon()); }
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce() { $platDePates = new PlatDePates([ unFromage(), uneViande(), uneSauce(), unLegume(), ]);
$this->assertTrue($platDePates->estBon()); }
BUILDERS
Photo by Jorge Zapata on Unsplash
class PlatDePatesTest extends \PHPUnit_Framework_TestCase {
public function test_nest_pas_consommable_sil_contient_un_ingredient_avec_une_DLC_depassee() { $platDePates = new PlatDePates([ new Ingredient('parmesan', new DateTime('2017-10-30')), new Ingredient('lardons', new DateTime('2017-10-15')), ]);
$this->assertFalse( $platDePates->estConsommableLe(new DateTime('2017-10-20')) ); } }
class PlatDePatesTest extends \PHPUnit_Framework_TestCase {
public function test_nest_pas_consommable_sil_contient_un_ingredient_avec_une_DLC_depassee() { $platDePates = new PlatDePates([ new Ingredient('parmesan', new DateTime('2017-10-30')), new Ingredient('lardons', new DateTime('2017-10-15')), ]);
$this->assertFalse( $platDePates->estConsommableLe(new DateTime('2017-10-20')) ); } }
class IngredientBuilder { private $nom;
private $dlc;
public function __construct() {
$this->nom = "pomme de terre";
$this->dlc = new Datetime(); }
public function nomme($nom) { $this->nom = $nom;
return $this; }
public function avecUneDLCLe($dlc) { $this->dlc = $dlc;
return $this; }
public function build() { return new Ingredient($this->nom, $this->dlc); } }
class IngredientBuilder {
public function build() { return new Ingredient($this->nom, $this->dlc); } }
class IngredientBuilder { public function nomme($nom) { $this->nom = $nom;
return $this; }
public function avecUneDLCLe($dlc) { $this->dlc = $dlc;
return $this; } }
class IngredientBuilder { public function nomme($nom) { $this->nom = $nom;
return $this; }
public function avecUneDLCLe($dlc) { $this->dlc = $dlc;
return $this; } }
class IngredientBuilder { public function __construct() {
$this->nom = "pomme de terre";
$this->dlc = new Datetime(); } }
function UnIngredient() { return new IngredientBuilder(); }
UnIngredient() ->nomme('Poisson panné') ->avecUneDLCLe(new Datetime('2018-01-12')) ->build();
class PlatDePatesTest extends \PHPUnit_Framework_TestCase {
public function test_nest_pas_consommable_sil_contient_un_ingredient_avec_une_DLC_depassee() { $platDePates = new PlatDePates([ UnIngredient()->avecUneDLCLe(new Datetime('2017-10-30'))->build(), UnIngredient()->avecUneDLCLe(new Datetime('2017-10-15'))->build(), ]);
$this->assertFalse($platDePates->estConsommableLe(new DateTime('2017-10-20'))); } }
DATA PROVIDER
Photo by Julian Andres Carmona Serrato on Unsplash
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade(){ $plat = new Plat(['salade']); $this->assertTrue($plat->estVegetarien()); }
public function test_est_vegetarien_sil_ne_contient_que_du_fromage() { $plat = new Plat(['fromage']); $this->assertTrue($plat->estVegetarien()); }
public function test_nest_pas_vegetarien_sil_contient_de_la_viande() { $plat = new Plat(['salade', 'viande']); $this->assertFalse($plat->estVegetarien()); } }
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade(){ $plat = new Plat(['salade']); $this->assertTrue($plat->estVegetarien()); }
public function test_est_vegetarien_sil_ne_contient_que_du_fromage() { $plat = new Plat(['fromage']); $this->assertTrue($plat->estVegetarien()); }
public function test_nest_pas_vegetarien_sil_contient_de_la_viande() { $plat = new Plat(['salade', 'viande']); $this->assertFalse($plat->estVegetarien()); } }
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade(){ $plat = new Plat(['salade']); $this->assertTrue($plat->estVegetarien()); }
public function test_est_vegetarien_sil_ne_contient_que_du_fromage() { $plat = new Plat(['fromage']); $this->assertTrue($plat->estVegetarien()); }
public function test_nest_pas_vegetarien_sil_contient_de_la_viande() { $plat = new Plat(['salade', 'viande']); $this->assertFalse($plat->estVegetarien()); } }
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade(){ $plat = new Plat(['salade']); $this->assertTrue($plat->estVegetarien()); }
public function test_est_vegetarien_sil_ne_contient_que_du_fromage() { $plat = new Plat(['fromage']); $this->assertTrue($plat->estVegetarien()); }
public function test_nest_pas_vegetarien_sil_contient_de_la_viande() { $plat = new Plat(['salade', 'viande']); $this->assertFalse($plat->estVegetarien()); } }
const EST_VEGETARIEN = true; const NEST_PAS_VEGETARIEN = false;
public function plats() { return [ 'Un plat qui ne contient que la salade est vegetarien' => [ new Plat(['salade']), self::EST_VEGETARIEN ], 'Un plat avec du fromage est vegetarien' => [ new Plat(['fromage']), self::EST_VEGETARIEN ], 'Un plat avec de la viande n\'est pas vegetarien' => [ new Plat(['viande']), self::NEST_PAS_VEGETARIEN ], ]; }
public function plats() { return [ 'Un plat qui ne contient que la salade est vegetarien' => [ new Plat(['salade']), self::EST_VEGETARIEN ], 'Un plat avec du fromage est vegetarien' => [ new Plat(['fromage']), self::EST_VEGETARIEN ], 'Un plat avec de la viande n\'est pas vegetarien' => [ new Plat(['viande']), self::NEST_PAS_VEGETARIEN ], ]; }
public function plats() { return [ 'Un plat qui ne contient que la salade est vegetarien' => [ new Plat(['salade']), self::EST_VEGETARIEN ], 'Un plat avec du fromage est vegetarien' => [ new Plat(['fromage']), self::EST_VEGETARIEN ], 'Un plat avec de la viande n\'est pas vegetarien' => [ new Plat(['viande']), self::NEST_PAS_VEGETARIEN ], ]; }
public function plats() { return [ 'Un plat qui ne contient que la salade est vegetarien' => [ new Plat(['salade']), self::EST_VEGETARIEN ], 'Un plat avec du fromage est vegetarien' => [ new Plat(['fromage']), self::EST_VEGETARIEN ], 'Un plat avec de la viande n\'est pas vegetarien' => [ new Plat(['viande']), self::NEST_PAS_VEGETARIEN ], ]; }
/** * @dataProvider plats */ public function test_est_vegetarien_sil_ne_contient_que_des_ingredients_vegetariens ($plat, $estVegetarien) { $this->assertEquals($estVegetarien, $plat->estVegetarien()); }
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade(){ $plat = new Plat(['salade']); $this->assertTrue($plat->estVegetarien()); }
public function test_est_vegetarien_sil_ne_contient_que_du_fromage() { $plat = new Plat(['fromage']); $this->assertTrue($plat->estVegetarien()); }
public function test_nest_pas_vegetarien_sil_contient_de_la_viande() { $plat = new Plat(['salade', 'viande']); $this->assertFalse($plat->estVegetarien()); } }
class PlatTest extends PHPUnit_Framework_TestCase {
const EST_VEGETARIEN = true; const NEST_PAS_VEGETARIEN = false;
/** * @dataProvider plats */ public function test_est_vegetarien_sil_ne_contient_que_des_ingredients_vegetariens ($plat, $estVegetarien) { $this->assertEquals($estVegetarien, $plat->estVegetarien()); }
public function plats() { return [ 'Un plat qui ne contient que la salade est vegetarien' => [ new Plat(['salade']), self::EST_VEGETARIEN ], 'Un plat avec du fromage est vegetarien' => [ new Plat(['fromage']), self::EST_VEGETARIEN ], 'Un plat avec de la viande n\'est pas vegetarien' => [ new Plat(['viande']), self::NEST_PAS_VEGETARIEN ], ]; } }
Assurez vous que vous testez ce que vous
voulez tester.Photo by rawpixel.com on Unsplash
Exprimez les règles métiers dans les noms
des tests.Photo by rawpixel.com on Unsplash
Utilisez le même vocabulaire dans le nom du test et dans
l’exemple.Photo by rawpixel.com on Unsplash
Ne couplez pas le test à
l’implémentation.Photo by rawpixel.com on Unsplash
Écoutez les tests pour guider l’implémentation.
Photo by rawpixel.com on Unsplash
documentation tests design
Photo by rawpixel.com on Unsplash
@SelrahcD
C’est tout !
documentation tests design
Photo by rawpixel.com on Unsplash