SlideShare une entreprise Scribd logo
1  sur  144
Télécharger pour lire hors ligne
RECETTES
de
TESTS
Charles 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 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
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
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
OBJETS
Photo 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 OWN
Photo 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
SYSTEME
Photo 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

Contenu connexe

Tendances

PHPunit and you
PHPunit and youPHPunit and you
PHPunit and youmarkstory
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014Guillaume POTIER
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven DevelopmentAugusto Pascutti
 
Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Bernhard Schussek
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to ProductionMark Baker
 
Quick: Better Tests via Incremental Setup
Quick: Better Tests via Incremental SetupQuick: Better Tests via Incremental Setup
Quick: Better Tests via Incremental SetupBrian Gesiak
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Everything You (N)ever Wanted to Know about Testing View Controllers
Everything You (N)ever Wanted to Know about Testing View ControllersEverything You (N)ever Wanted to Know about Testing View Controllers
Everything You (N)ever Wanted to Know about Testing View ControllersBrian Gesiak
 
Coffeescript - what's good
Coffeescript - what's goodCoffeescript - what's good
Coffeescript - what's goodJeongHun Byeon
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
Testing view controllers with Quick and Nimble
Testing view controllers with Quick and NimbleTesting view controllers with Quick and Nimble
Testing view controllers with Quick and NimbleMarcio Klepacz
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2eugenio pombi
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome TownRoss Tuck
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Konstantin Kudryashov
 

Tendances (20)

PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
My Development Story
My Development StoryMy Development Story
My Development Story
 
CakePHP workshop
CakePHP workshopCakePHP workshop
CakePHP workshop
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven Development
 
Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Best Practice Testing with Lime 2
Best Practice Testing with Lime 2
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
 
Quick: Better Tests via Incremental Setup
Quick: Better Tests via Incremental SetupQuick: Better Tests via Incremental Setup
Quick: Better Tests via Incremental Setup
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Everything You (N)ever Wanted to Know about Testing View Controllers
Everything You (N)ever Wanted to Know about Testing View ControllersEverything You (N)ever Wanted to Know about Testing View Controllers
Everything You (N)ever Wanted to Know about Testing View Controllers
 
Coffeescript - what's good
Coffeescript - what's goodCoffeescript - what's good
Coffeescript - what's good
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Testing view controllers with Quick and Nimble
Testing view controllers with Quick and NimbleTesting view controllers with Quick and Nimble
Testing view controllers with Quick and Nimble
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 

Similaire à Recettes de tests

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
The command dispatcher pattern
The command dispatcher patternThe command dispatcher pattern
The command dispatcher patternolvlvl
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Kacper Gunia
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowKacper Gunia
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにYuya Takeyama
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Designunodelostrece
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09Michelangelo van Dam
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Concurrent test frameworks
Concurrent test frameworksConcurrent test frameworks
Concurrent test frameworksAndrea Giuliano
 
Introduction to DI(C)
Introduction to DI(C)Introduction to DI(C)
Introduction to DI(C)Radek Benkel
 

Similaire à Recettes de tests (20)

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
The command dispatcher pattern
The command dispatcher patternThe command dispatcher pattern
The command dispatcher pattern
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Javascript in Plone
Javascript in PloneJavascript in Plone
Javascript in Plone
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Concurrent test frameworks
Concurrent test frameworksConcurrent test frameworks
Concurrent test frameworks
 
Introduction to DI(C)
Introduction to DI(C)Introduction to DI(C)
Introduction to DI(C)
 

Plus de Charles Desneuf

Process Behavior Charts - Le Conte de Noël
Process Behavior Charts - Le Conte de NoëlProcess Behavior Charts - Le Conte de Noël
Process Behavior Charts - Le Conte de NoëlCharles Desneuf
 
De CRUD à DDD pas à pas
De CRUD à DDD pas à pasDe CRUD à DDD pas à pas
De CRUD à DDD pas à pasCharles Desneuf
 
Vous n'avez pas besoin de ça
Vous n'avez pas besoin de çaVous n'avez pas besoin de ça
Vous n'avez pas besoin de çaCharles Desneuf
 
Faire grandir une equipe technique
Faire grandir une equipe techniqueFaire grandir une equipe technique
Faire grandir une equipe techniqueCharles Desneuf
 
Les exceptions, oui, mais pas n'importe comment
Les exceptions, oui, mais pas n'importe commentLes exceptions, oui, mais pas n'importe comment
Les exceptions, oui, mais pas n'importe commentCharles Desneuf
 
Dealing with not so exceptional exceptions
Dealing with not so exceptional exceptionsDealing with not so exceptional exceptions
Dealing with not so exceptional exceptionsCharles Desneuf
 

Plus de Charles Desneuf (6)

Process Behavior Charts - Le Conte de Noël
Process Behavior Charts - Le Conte de NoëlProcess Behavior Charts - Le Conte de Noël
Process Behavior Charts - Le Conte de Noël
 
De CRUD à DDD pas à pas
De CRUD à DDD pas à pasDe CRUD à DDD pas à pas
De CRUD à DDD pas à pas
 
Vous n'avez pas besoin de ça
Vous n'avez pas besoin de çaVous n'avez pas besoin de ça
Vous n'avez pas besoin de ça
 
Faire grandir une equipe technique
Faire grandir une equipe techniqueFaire grandir une equipe technique
Faire grandir une equipe technique
 
Les exceptions, oui, mais pas n'importe comment
Les exceptions, oui, mais pas n'importe commentLes exceptions, oui, mais pas n'importe comment
Les exceptions, oui, mais pas n'importe comment
 
Dealing with not so exceptional exceptions
Dealing with not so exceptional exceptionsDealing with not so exceptional exceptions
Dealing with not so exceptional exceptions
 

Dernier

Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 

Dernier (20)

Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 

Recettes de tests

  • 3. Photo by Dan Gold on Unsplash
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. PHPUnit Prophecy Photo by Scott Umstattd on Unsplash
  • 16. ANATOMIE D’UN TEST Photo by Michael Browning on Unsplash
  • 17. 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 ); } }
  • 18. 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 ); } }
  • 19. 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()
  • 22. 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 ); } }
  • 23. ➜ 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
  • 24. ➜ 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
  • 25. 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 ); } }
  • 26. 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 ); } }
  • 27. Photo by Gemma Evans on Unsplash ARRANGE ACT ASSERT
  • 28. 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 ); } }
  • 29. 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
  • 30. 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
  • 31. 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
  • 33. 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 ); }
  • 34. 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) ); } }
  • 35. class Serveur { public function annonceLeMenu() { $plat = 'Gencives de porc !'; return sprintf( 'Le chef vous propose aujourd'hui %s', $this->transformeNomDuPlat($plat) ); } }
  • 36. 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 ); }
  • 37. 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 ); }
  • 38. 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); } }
  • 39. 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
  • 40. 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
  • 41. 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
  • 42. 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); } }
  • 43. class Serveur { public function recoitUneCommandePourUnPlatDuJour() { } }
  • 44. class Serveur { public function recoitUneCommandePourUnPlatDuJour() { for($i = 0; $i < 100; $i++) { $this->cuisine->ilFautUnPlatDuJour(); } } }
  • 45. 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); } }
  • 46. class Serveur { public function recoitUneCommandePourUnPlatDuJour() { $this->cuisine->ilFautUnPlatDuJour(); } }
  • 47. 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); } }
  • 50. 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() ); } }
  • 51. class PizzaSurgelee { public function __construct($ingredients) { $this->ingredients = $ingredients; } public function ingredients() { return $this->ingredients; } }
  • 52. class Pizzaiolo { public function preparePizzaMargheritaMaison(){ $pizzaSurgelee = $this->acheteUnePizzaMargheritaSurgelee(); return $this->rechauffeLaPizza($pizzaSurgelee); } }
  • 53. public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo(); $pizza = $pizzaiolo->preparePizzaMargheritaMaison(); $this->assertEquals( ['pate', 'sauce tomate', 'basilic', 'mozzarella'], $pizza->ingredients() ); }
  • 54. 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 ); } }
  • 55. public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo(); $pizza = $pizzaiolo->preparePizzaMargheritaMaison(); $this->assertEquals( new PizzaMaison(['pate', 'sauce tomate', 'basilic', 'mozzarella']), $pizza ); }
  • 56. class Pizzaiolo { public function preparePizzaMargheritaMaison() { $pateAPizza = new PateAPizza(); $this->etaleLaPate($pateAPizza); $this->enduitDeSauceTomate($pateAPizza); $this->disposeLaMozzarella($pateAPizza); $this->placeLeBasilic($pateAPizza); return $this->cuire($pateAPizza); } }
  • 57. public function test_prepare_une_pizza_margherita_maison() { $pizzaiolo = new Pizzaiolo(); $pizza = $pizzaiolo->preparePizzaMargheritaMaison(); $this->assertEquals( new PizzaMaison(['pate', 'sauce tomate', 'basilic', 'mozzarella']), $pizza ); }
  • 58. class PizzaMaison { public function __construct($ingredients) { $this->ingredients = $ingredients; } public function ingredients() { return $this->ingredients; } }
  • 59. class PizzaMaison { public function __construct($ingredients) { $this->ingredients = $ingredients; } public function ingredients() { return $this->ingredients; } }
  • 60. TEST CLASS PER FIXTURE Photo by Lou Stejskal on Flickr
  • 61. 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()); } }
  • 62. 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()); }
  • 63. 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()); }
  • 64. 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()); } }
  • 65. 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()); } }
  • 66. 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()); } }
  • 67. 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()); } }
  • 68. 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()); } }
  • 69. // UneEndiveDeBaseTest.php public function setUp() { $this->endive = new Endive(); } // UneEndiveCuiteTest.php public function setUp() { $this->endive = new Endive(); $this->endive->cuire(); }
  • 70. class UneEndiveCrueTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->endive = new Endive(); } }
  • 71. class UneEndiveCrueTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->endive = new Endive(); } }
  • 72. class Endive { public static function crue() { return new self(); } }
  • 73. class UneEndiveCrueTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->endive = Endive::crue(); } }
  • 74. DON’T MOCK WHAT YOU DON’T OWN Photo by Naomi Hébert on Unsplash
  • 75. 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); } }
  • 76. namespace IKEA; class Realistisk { /** * @return Tallrik */ public function laga($tallrik, $varaktighet) { sleep($varaktighet); return $this->fårEnVarmTallrik(get_class($tallrik) , $varaktighet); } }
  • 77. 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); }
  • 78. 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); }
  • 79. class Realistisk { public function laga($tallrik, $varaktighet) { sleep($duree); return $this->fårEnKallTallrik(get_class($tallrik), $varaktighet); } }
  • 80. 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); }
  • 81. 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); }
  • 82. 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); }
  • 83. 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); }
  • 84. interface Four { public function cuire($plat, $duree); }
  • 85. 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); }
  • 86. 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); }
  • 87. 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(); } }
  • 88. class Gratin { public function cuireAvec(Realistisk $realistisk, $duree) { $tallrik = $realistisk->laga($this, $duree); return $tallrik->fåTallrik(); } }
  • 89. class Gratin { public function cuireAvec(Four $four, $duree) { return $four->cuire($this, $duree); } }
  • 90. 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); } }
  • 91. 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); } }
  • 92. NE DEPENDEZ PAS DU SYSTEME Photo by James Harris on Unsplash
  • 93. 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()); }
  • 94. class Quiche { public function __construct(Datetime $dateCuisson) { $this->dateCuisson = $dateCuisson; } public function peutEtreConsommee() { return $this->dateCuisson->modify('+2 day') < new Datetime(); } }
  • 95. 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()); }
  • 96. 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()); }
  • 97. class Horloge { public function maintenant() { return new Datetime(); } }
  • 98. class Quiche { public function __construct(Datetime $cuisineeLe) { $this->cuisineeLe = $cuisineeLe; } public function peutEtreConsommee(Horloge $horloge) { return $this->cuisineeLe->modify('+2 day') < $horloge->maintenant(); } }
  • 99. 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)); }
  • 100. 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)); }
  • 101. class Quiche { public function peutEtreConsommeeLe(Datetime $dateDeConsommation) { return $this->cuisineeLe->modify('+2 day') < $dateDeConsommation; } }
  • 102. 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); }
  • 103. 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); }
  • 104. OBJECT MOTHER Photo by Eaters Collective on Unsplash
  • 105. 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()); } }
  • 106. class Ingredient { public function __construct($type, $nom) { $this->type = $type; $this->nom = $nom; } }
  • 107. class Ingredient { public function __construct($type, $nom, $DLC) { $this->type = $type; $this->nom = $nom; $this->DLC = $DLC; } }
  • 108. 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()); }
  • 109. 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()); } }
  • 110. 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()); }
  • 111. function uneViande() { return IngredientMother::viande(); } function unLegume() { return IngredientMother::legume(); } function unFromage() { return IngredientMother::fromage(); } function uneSauce() { return IngredientMother::sauce(); }
  • 112. 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()); }
  • 113. 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()); }
  • 114. BUILDERS Photo by Jorge Zapata on Unsplash
  • 115. 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')) ); } }
  • 116. 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')) ); } }
  • 117. 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); } }
  • 118. class IngredientBuilder { public function build() { return new Ingredient($this->nom, $this->dlc); } }
  • 119. class IngredientBuilder { public function nomme($nom) { $this->nom = $nom; return $this; } public function avecUneDLCLe($dlc) { $this->dlc = $dlc; return $this; } }
  • 120. class IngredientBuilder { public function nomme($nom) { $this->nom = $nom; return $this; } public function avecUneDLCLe($dlc) { $this->dlc = $dlc; return $this; } }
  • 121. class IngredientBuilder { public function __construct() { $this->nom = "pomme de terre"; $this->dlc = new Datetime(); } }
  • 122. function UnIngredient() { return new IngredientBuilder(); }
  • 124. 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'))); } }
  • 125. DATA PROVIDER Photo by Julian Andres Carmona Serrato on Unsplash
  • 126. 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()); } }
  • 127. 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()); } }
  • 128. 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()); } }
  • 129. 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()); } }
  • 130. const EST_VEGETARIEN = true; const NEST_PAS_VEGETARIEN = false;
  • 131. 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 ], ]; }
  • 132. 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 ], ]; }
  • 133. 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 ], ]; }
  • 134. 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 ], ]; }
  • 135. /** * @dataProvider plats */ public function test_est_vegetarien_sil_ne_contient_que_des_ingredients_vegetariens ($plat, $estVegetarien) { $this->assertEquals($estVegetarien, $plat->estVegetarien()); }
  • 136. 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()); } }
  • 137. 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 ], ]; } }
  • 138. Assurez vous que vous testez ce que vous voulez tester. Photo by rawpixel.com on Unsplash
  • 139. Exprimez les règles métiers dans les noms des tests. Photo by rawpixel.com on Unsplash
  • 140. Utilisez le même vocabulaire dans le nom du test et dans l’exemple. Photo by rawpixel.com on Unsplash
  • 141. Ne couplez pas le test à l’implémentation. Photo by rawpixel.com on Unsplash
  • 142. Écoutez les tests pour guider l’implémentation. Photo by rawpixel.com on Unsplash
  • 143. documentation tests design Photo by rawpixel.com on Unsplash
  • 144. @SelrahcD C’est tout ! documentation tests design Photo by rawpixel.com on Unsplash