TDD, 5 ans plus tard

Romain Berthon

#JobHacker

@RomainTrm

romainberthon.blog

TDD : le principe

Test Driven Development

TDD : bénéfices

  • Comportements testés automatiquement
    • Moins de debug
    • Régressions mises en évidence
  • Autorise le refactoring
    • Qualité de code supérieure

Vocabulaire

  • Système
  • Test unitaire
  • Test d'intégration

TDD : les débuts

  • Application CRUD
  • Architecture en couches

Class under test

Mocks

Inputs

Outputs

TDD : les débuts


Mock<IFoo> fooMock;
Mock<IBar> barMock;

// Given
fooMock.Setup(x => x.Foo(arg1)).Returns(arg2);

// When
var myClassUnderTest = new Class(fooMock, barMock);
var result = myClassUnderTest.DoSomething(arg1);

// Then
Assertion(result);
barMock.Verify(x => x.Bar(arg2));

TDD : les débuts

  • Changements de contrats difficiles
  • Refacto difficile

Couplage fort

TDD : les débuts

Cohérence du système ?

TDD : les débuts

  • Unités de code testés
  • Unité de code facile à refactorer ?
  • Système pas testé
  • Système difficile à refactorer

TDD : tester un système

Deux écoles :

  • Chicago school
  • London school

TDD : Chicago school

(Inside-out)

Robert C. Martin (aka Uncle Bob)

@unclebobmartin

TDD : London school

(Outside-in)

Sandro Mancuso

@sandromancuso

TDD : London school

(Outside-in)

Parenthèse BDD

  • Behavior Driven Development
  • Souvent utilisé pour désigner une syntaxe Gherkin (Gherkin != BDD)
  • Spécification par l'exemple des comportements métiers, rédaction avec des experts métiers
  • Permet de tester le système en mode "boite noire"

TDD : vers un système plus prédictible

  • Un système peu prédictible est un système difficile à tester
  • Pousser les effets de bords aux frontières du système
  • Rendre le système idempotent

TDD : vers un système plus prédictible

  • Un cas d'erreur typique : le temps
  • Le système n'a pas un comportement répétable
  • Le système n'a pas un comportement prédictible
  • Marche aussi avec :
    • un appel en base de données
    • un appel à une API
    • ...
  • Egalité par référence vs. égalité structurelle

Mon TDD aujourd'hui ?

Thomas Pierrain

@tpierrain

"Virez-moi cette pyramide de tests !"

Mon TDD aujourd'hui ?

Mon contexte :

  • Systèmes à minima event-drivé (Update par publication d'événements)
  • Maintient de projections (pas besoin de jointures SQL, ect.)

Mon TDD aujourd'hui ?

Définir l'état et tester système

Système

Given (events)

When

command / query

Then

Assertion

Etat ?

Mon TDD aujourd'hui ?

Réduire le couplage avec les tests

  • Une classe pour les tests qui :
    • "crée" l'application
    • publie des événements
    • donne accès aux API publiques
    • applique des assertions sur l'état du système

Mon TDD aujourd'hui ?

Réduire le couplage avec les tests


var app = MonApp.Create();

// Given
app.AddHistory(evt1, evt2, evt3);
app.DefineTime(givenTime);

// When
var controller = app.GetSomeController();
var result = controller.ExecuteCommand(arg1, arg2);

// Then
VerifyAssertion(result);
app.VerifyOnHistory(myAssertion);

Mon TDD aujourd'hui ?

Des comportements identiques

Système

IDataAccess

SqlDataAccess

InMemoryDataAccess

Infrastructure

Mon TDD aujourd'hui ?

Réduire le couplage avec les tests

Mon TDD aujourd'hui ?

Bénéfices et inconvénients

  • Suite de test solide
  • Peu de couplage à l'implémentation
  • Tests plus simples à écrire
  • Refacto simple
  • Boucle de feedback plus lente
  • Erreur plus difficile à analyser
  • Couplage aux couches applicatives

Pour aller plus loins

Mark Seemann

@ploeh

"From interaction-based to state-based testing"

Ce dont je n'ai pas parlé

  • Property-Based Testing
  • Tests inter-composants
  • Tests end-to-end

Merci !

Romain Berthon

#JobHacker

@RomainTrm

romainberthon.blog

TDD, 5 ans plus tard

By Romain Berthon

TDD, 5 ans plus tard

  • 207