Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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
...
Découvrir des bugs
Permettre de réfactorer
Documenter
Réfléchir à l’interface du système
Détecter des problèmes de design
...
Découvrir des bugs
Permettre de réfactorer
Documenter
Réfléchir à l’interface du système
Détecter des problèmes de design
...
Découvrir des bugs
Permettre de réfactorer
Documenter
Réfléchir à l’interface du système
Détecter des problèmes de design
...
Découvrir des bugs
Permettre de réfactorer
Documenter
Réfléchir à l’interface du système
Détecter des problèmes de design
...
Indépendants de l’implémentation
Décrire le comportement du système
Avoir un résultat prédictible
Rapides
Indépendants les...
Indépendants de l’implémentation
Décrire le comportement du système
Avoir un résultat prédictible
Rapides
Indépendants les...
Indépendants de l’implémentation
Décrire le comportement du système
Avoir un résultat prédictible
Rapides
Indépendants les...
Indépendants de l’implémentation
Décrire le comportement du système
Avoir un résultat prédictible
Rapides
Indépendants les...
Indépendants de l’implémentation
Décrire le comportement du système
Avoir un résultat prédictible
Rapides
Indépendants les...
Indépendants de l’implémentation
Décrire le comportement du système
Avoir un résultat prédictible
Rapides
Indépendants les...
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 = $thi...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour()
{
$cuisine = $thi...
public function testIlAnnonceLePlatDuJour()
public function test_il_annonce_le_plat_du_jour()
/**
* @test
*/
public functi...
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 = $thi...
➜ recettes phpunit --testdox tests/ServeurTest.php
PHPUnit 4.7.6 by Sebastian Bergmann and contributors.
Serveur
[x] il an...
➜ recettes phpunit --testdox tests/ServeurTest.php
PHPUnit 4.7.6 by Sebastian Bergmann and contributors.
Serveur
[x] il an...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour()
{
$cuisine = $thi...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour()
{
$cuisine = $thi...
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 = $thi...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour()
{
$cuisine = $thi...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour()
{
$cuisine = $thi...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_il_annonce_le_plat_du_jour()
{
$cuisine = $thi...
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()
...
class Serveur {
public function annonceLeMenu() {
$plat = $this->cuisine->quelEstLePlatDuJour();
// fait autre chose, oubl...
class Serveur {
public function annonceLeMenu() {
$plat = 'Gencives de porc !';
return sprintf(
'Le chef vous propose aujo...
public function test_annonce_le_plat_du_jour()
{
$cuisine = $this->prophesize(Cuisine::class);
$cuisine
->quelEstLePlat()
...
public function test_annonce_le_plat_du_jour()
{
$cuisine = $this->prophesize(Cuisine::class);
$cuisine
->quelEstLePlatDuJ...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_l...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_l...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_l...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_l...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_l...
class Serveur {
public function recoitUneCommandePourUnPlatDuJour() {
}
}
class Serveur {
public function recoitUneCommandePourUnPlatDuJour() {
for($i = 0; $i < 100; $i++) {
$this->cuisine->ilFaut...
class ServeurTest extends PHPUnit_Framework_TestCase {
public function test_transmet_une_commande_pour_le_plat_du_jour_a_l...
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_l...
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()
{
$piz...
class PizzaSurgelee {
public function __construct($ingredients)
{
$this->ingredients = $ingredients;
}
public function ing...
class Pizzaiolo {
public function preparePizzaMargheritaMaison(){
$pizzaSurgelee = $this->acheteUnePizzaMargheritaSurgelee...
public function test_prepare_une_pizza_margherita_maison()
{
$pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePiz...
class PizzaioloTest extends PHPUnit_Framework_TestCase {
public function test_prepare_une_pizza_margherita_maison()
{
$piz...
public function test_prepare_une_pizza_margherita_maison()
{
$pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePiz...
class Pizzaiolo {
public function preparePizzaMargheritaMaison() {
$pateAPizza = new PateAPizza();
$this->etaleLaPate($pat...
public function test_prepare_une_pizza_margherita_maison()
{
$pizzaiolo = new Pizzaiolo();
$pizza = $pizzaiolo->preparePiz...
class PizzaMaison {
public function __construct($ingredients)
{
$this->ingredients = $ingredients;
}
public function ingre...
class PizzaMaison {
public function __construct($ingredients)
{
$this->ingredients = $ingredients;
}
public function ingre...
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 E...
public function test_une_endive_de_base_est_crue() {
$endive = new Endive();
$this->assertTrue($endive->crue());
}
public ...
public function test_une_endive_cuite_nest_pas_crue(){
$endive = new Endive();
$endive->cuire();
$this->assertFalse($endiv...
class UneEndiveDeBaseTest extends PHPUnit_Framework_TestCase {
public function setUp()
{
$this->endive = new Endive();
}
p...
class UneEndiveCuiteTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->endive = new Endive();
$thi...
class UneEndiveDeBaseTest extends PHPUnit_Framework_TestCase {
public function setUp()
{
$this->endive = new Endive();
}
p...
class UneEndiveCuiteTest extends PHPUnit_Framework_TestCase {
public function setUp()
{
$this->endive = new Endive();
$thi...
class UneEndiveDeBaseTest extends PHPUnit_Framework_TestCase {
public function setUp()
{
$this->endive = new Endive();
}
p...
// UneEndiveDeBaseTest.php
public function setUp()
{
$this->endive = new Endive();
}
// UneEndiveCuiteTest.php
public func...
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() {
$...
namespace IKEA;
class Realistisk {
/**
* @return Tallrik
*/
public function laga($tallrik, $varaktighet) {
sleep($varaktig...
public function test_cuit_au_four_donne_un_gratin_croustillant() {
$gratin = new Gratin();
$realistisk = new Realistisk();...
public function test_cuit_au_four_donne_un_gratin_croustillant()
{
$gratin = new Gratin();
$tallrik = $this->prophesize(Ta...
class Realistisk {
public function laga($tallrik, $varaktighet) {
sleep($duree);
return $this->fårEnKallTallrik(get_class(...
public function test_cuit_au_four_donne_un_gratin_croustillant()
{
$gratin = new Gratin();
$tallrik = $this->prophesize(Ta...
public function test_cuit_au_four_donne_un_gratin_croustillant() {
$gratin = new Gratin();
$realistisk = new Realistisk();...
public function test_cuit_au_four_donne_un_gratin_croustillant() {
$gratin = new Gratin();
$realistisk = new Realistisk();...
public function test_cuit_au_four_donne_un_gratin_croustillant()
{
$gratin = new Gratin();
$tallrik = $this->prophesize(Ta...
interface Four {
public function cuire($plat, $duree);
}
public function test_cuit_au_four_donne_un_gratin_croustillant()
{
$gratin = new Gratin();
$four = $this->prophesize(Four:...
public function test_cuit_au_four_donne_un_gratin_croustillant()
{
$gratin = new Gratin();
$four = $this->prophesize(Four:...
class LeFourDeLaCuisine implements Four {
public function __construct(Realistisk $realistisk)
{
$this->realistisk = $reali...
class Gratin {
public function cuireAvec(Realistisk $realistisk, $duree) {
$tallrik = $realistisk->laga($this, $duree);
re...
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_...
class LeFourDeLaCuisineTest extends PHPUnit_Framework_TestCase {
public function test_cuit_un_fromage_de_chevre_en_chevre_...
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-...
class Quiche {
public function __construct(Datetime $dateCuisson) {
$this->dateCuisson = $dateCuisson;
}
public function p...
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite()
{
$quiche = new Quiche(new Datetime('2017-...
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite()
{
$quiche = new Quiche(new Datetime('2017-...
class Horloge {
public function maintenant() {
return new Datetime();
}
}
class Quiche {
public function __construct(Datetime $cuisineeLe) {
$this->cuisineeLe = $cuisineeLe;
}
public function peut...
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite()
{
$horloge = $this->prophesize(Horloge::cl...
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite()
{
$horloge = $this->prophesize(Horloge::cl...
class Quiche {
public function peutEtreConsommeeLe(Datetime $dateDeConsommation)
{
return $this->cuisineeLe->modify('+2 da...
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite()
{
$quiche = new Quiche(new Datetime('2017-...
public function test_une_quiche_est_consommable_2_jours_apres_avoir_ete_cuite()
{
$quiche = new Quiche(new Datetime('2017-...
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_froma...
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 = $...
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce()
{
$platDePates = new PlatDePates([
new ...
class IngredientMother {
public static function viande()
{
return new Ingredient('viande', 'boeuf hache', new Datetime());...
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce()
{
$platDePates = new PlatDePates([
Ingr...
function uneViande()
{
return IngredientMother::viande();
}
function unLegume()
{
return IngredientMother::legume();
}
fun...
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce()
{
$platDePates = new PlatDePates([
unFr...
public function test_est_bon_sil_contient_de_la_viande_du_fromage_et_de_la_sauce()
{
$platDePates = new PlatDePates([
unFr...
BUILDERS
Photo by Jorge Zapata on Unsplash
class PlatDePatesTest extends PHPUnit_Framework_TestCase {
public function test_nest_pas_consommable_sil_contient_un_ingre...
class PlatDePatesTest extends PHPUnit_Framework_TestCase {
public function test_nest_pas_consommable_sil_contient_un_ingre...
class IngredientBuilder {
private $nom;
private $dlc;
public function __construct() {
$this->nom = "pomme de terre";
$this...
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($d...
class IngredientBuilder {
public function nomme($nom)
{
$this->nom = $nom;
return $this;
}
public function avecUneDLCLe($d...
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_ingre...
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()...
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade()...
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade()...
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade()...
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:...
public function plats()
{
return [
'Un plat qui ne contient que la salade est vegetarien' => [
new Plat(['salade']), self:...
public function plats()
{
return [
'Un plat qui ne contient que la salade est vegetarien' => [
new Plat(['salade']), self:...
public function plats()
{
return [
'Un plat qui ne contient que la salade est vegetarien' => [
new Plat(['salade']), self:...
/**
* @dataProvider plats
*/
public function test_est_vegetarien_sil_ne_contient_que_des_ingredients_vegetariens
($plat, $...
class PlatTest extends PHPUnit_Framework_TestCase {
public function test_est_vegetarien_sil_ne_contient_que_de_la_salade()...
class PlatTest extends PHPUnit_Framework_TestCase {
const EST_VEGETARIEN = true;
const NEST_PAS_VEGETARIEN = false;
/**
* ...
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
Upcoming SlideShare
Loading in …5
×

Recettes de tests

1,031 views

Published on

Ecrire des tests c'est bien, écrire des tests que l'on aime sur le long terme c'est mieux.

Published in: Software
  • Be the first to comment

Recettes de tests

  1. 1. RECETTES de TESTS Charles Desneuf - @SelrahcD
  2. 2. @SelrahcD
  3. 3. Photo by Dan Gold on Unsplash
  4. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 15. PHPUnit Prophecy Photo by Scott Umstattd on Unsplash
  16. 16. ANATOMIE D’UN TEST Photo by Michael Browning on Unsplash
  17. 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. 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. 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()
  20. 20. public function he_should_announce_todays_special()
  21. 21. public function he_announces_todays_special()
  22. 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. 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. 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. 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. 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. 27. Photo by Gemma Evans on Unsplash ARRANGE ACT ASSERT
  28. 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. 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. 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. 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
  32. 32. ARRANGE ACT ASSERT GIVEN WHEN THEN Photo by Baher Khairy on Unsplash
  33. 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. 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. 35. class Serveur { public function annonceLeMenu() { $plat = 'Gencives de porc !'; return sprintf( 'Le chef vous propose aujourd'hui %s', $this->transformeNomDuPlat($plat) ); } }
  36. 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. 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. 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. 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. 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. 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. 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. 43. class Serveur { public function recoitUneCommandePourUnPlatDuJour() { } }
  44. 44. class Serveur { public function recoitUneCommandePourUnPlatDuJour() { for($i = 0; $i < 100; $i++) { $this->cuisine->ilFautUnPlatDuJour(); } } }
  45. 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. 46. class Serveur { public function recoitUneCommandePourUnPlatDuJour() { $this->cuisine->ilFautUnPlatDuJour(); } }
  47. 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); } }
  48. 48. Mock Arrange Spy Assert Photo by Alexander Maasch on Unsplash
  49. 49. EGALITE DES OBJETS Photo by Brenan Greene on Unsplash
  50. 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. 51. class PizzaSurgelee { public function __construct($ingredients) { $this->ingredients = $ingredients; } public function ingredients() { return $this->ingredients; } }
  52. 52. class Pizzaiolo { public function preparePizzaMargheritaMaison(){ $pizzaSurgelee = $this->acheteUnePizzaMargheritaSurgelee(); return $this->rechauffeLaPizza($pizzaSurgelee); } }
  53. 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. 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. 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. 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. 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. 58. class PizzaMaison { public function __construct($ingredients) { $this->ingredients = $ingredients; } public function ingredients() { return $this->ingredients; } }
  59. 59. class PizzaMaison { public function __construct($ingredients) { $this->ingredients = $ingredients; } public function ingredients() { return $this->ingredients; } }
  60. 60. TEST CLASS PER FIXTURE Photo by Lou Stejskal on Flickr
  61. 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. 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. 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. 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. 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. 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. 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. 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. 69. // UneEndiveDeBaseTest.php public function setUp() { $this->endive = new Endive(); } // UneEndiveCuiteTest.php public function setUp() { $this->endive = new Endive(); $this->endive->cuire(); }
  70. 70. class UneEndiveCrueTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->endive = new Endive(); } }
  71. 71. class UneEndiveCrueTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->endive = new Endive(); } }
  72. 72. class Endive { public static function crue() { return new self(); } }
  73. 73. class UneEndiveCrueTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->endive = Endive::crue(); } }
  74. 74. DON’T MOCK WHAT YOU DON’T OWN Photo by Naomi Hébert on Unsplash
  75. 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. 76. namespace IKEA; class Realistisk { /** * @return Tallrik */ public function laga($tallrik, $varaktighet) { sleep($varaktighet); return $this->fårEnVarmTallrik(get_class($tallrik) , $varaktighet); } }
  77. 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. 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. 79. class Realistisk { public function laga($tallrik, $varaktighet) { sleep($duree); return $this->fårEnKallTallrik(get_class($tallrik), $varaktighet); } }
  80. 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. 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. 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. 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. 84. interface Four { public function cuire($plat, $duree); }
  85. 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. 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. 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. 88. class Gratin { public function cuireAvec(Realistisk $realistisk, $duree) { $tallrik = $realistisk->laga($this, $duree); return $tallrik->fåTallrik(); } }
  89. 89. class Gratin { public function cuireAvec(Four $four, $duree) { return $four->cuire($this, $duree); } }
  90. 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. 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. 92. NE DEPENDEZ PAS DU SYSTEME Photo by James Harris on Unsplash
  93. 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. 94. class Quiche { public function __construct(Datetime $dateCuisson) { $this->dateCuisson = $dateCuisson; } public function peutEtreConsommee() { return $this->dateCuisson->modify('+2 day') < new Datetime(); } }
  95. 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. 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. 97. class Horloge { public function maintenant() { return new Datetime(); } }
  98. 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. 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. 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. 101. class Quiche { public function peutEtreConsommeeLe(Datetime $dateDeConsommation) { return $this->cuisineeLe->modify('+2 day') < $dateDeConsommation; } }
  102. 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. 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. 104. OBJECT MOTHER Photo by Eaters Collective on Unsplash
  105. 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. 106. class Ingredient { public function __construct($type, $nom) { $this->type = $type; $this->nom = $nom; } }
  107. 107. class Ingredient { public function __construct($type, $nom, $DLC) { $this->type = $type; $this->nom = $nom; $this->DLC = $DLC; } }
  108. 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. 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. 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. 111. function uneViande() { return IngredientMother::viande(); } function unLegume() { return IngredientMother::legume(); } function unFromage() { return IngredientMother::fromage(); } function uneSauce() { return IngredientMother::sauce(); }
  112. 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. 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. 114. BUILDERS Photo by Jorge Zapata on Unsplash
  115. 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. 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. 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. 118. class IngredientBuilder { public function build() { return new Ingredient($this->nom, $this->dlc); } }
  119. 119. class IngredientBuilder { public function nomme($nom) { $this->nom = $nom; return $this; } public function avecUneDLCLe($dlc) { $this->dlc = $dlc; return $this; } }
  120. 120. class IngredientBuilder { public function nomme($nom) { $this->nom = $nom; return $this; } public function avecUneDLCLe($dlc) { $this->dlc = $dlc; return $this; } }
  121. 121. class IngredientBuilder { public function __construct() { $this->nom = "pomme de terre"; $this->dlc = new Datetime(); } }
  122. 122. function UnIngredient() { return new IngredientBuilder(); }
  123. 123. UnIngredient() ->nomme('Poisson panné') ->avecUneDLCLe(new Datetime('2018-01-12')) ->build();
  124. 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. 125. DATA PROVIDER Photo by Julian Andres Carmona Serrato on Unsplash
  126. 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. 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. 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. 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. 130. const EST_VEGETARIEN = true; const NEST_PAS_VEGETARIEN = false;
  131. 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. 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. 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. 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. 135. /** * @dataProvider plats */ public function test_est_vegetarien_sil_ne_contient_que_des_ingredients_vegetariens ($plat, $estVegetarien) { $this->assertEquals($estVegetarien, $plat->estVegetarien()); }
  136. 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. 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. 138. Assurez vous que vous testez ce que vous voulez tester. Photo by rawpixel.com on Unsplash
  139. 139. Exprimez les règles métiers dans les noms des tests. Photo by rawpixel.com on Unsplash
  140. 140. Utilisez le même vocabulaire dans le nom du test et dans l’exemple. Photo by rawpixel.com on Unsplash
  141. 141. Ne couplez pas le test à l’implémentation. Photo by rawpixel.com on Unsplash
  142. 142. Écoutez les tests pour guider l’implémentation. Photo by rawpixel.com on Unsplash
  143. 143. documentation tests design Photo by rawpixel.com on Unsplash
  144. 144. @SelrahcD C’est tout ! documentation tests design Photo by rawpixel.com on Unsplash

×