L'amélioration des tests unitaires par le refactoring

13
L'amélioration des tests unitaires par le refactoring Pascal Laurin Mai 2015 @plaurin78 [email protected] www.pascallaurin.com Microsoft .NET MVP Développeur & Architecte chez GSoft

Transcript of L'amélioration des tests unitaires par le refactoring

Page 1: L'amélioration des tests unitaires par le refactoring

L'amélioration des tests unitaires par le refactoring

Pascal Laurin

Mai 2015

@[email protected]

www.pascallaurin.com

Microsoft .NET MVPDéveloppeur & Architecte chez GSoft

Page 2: L'amélioration des tests unitaires par le refactoring

Maintenance

Si on n’est pas capable de comprendre un test qui plante, il ne

sert pas à grand chose

Remplacer les tests inutiles

Apprendre refactoring

Moins risqué qu’avec du code de production

Portée plus réduite dans les tests

Un bon défi

On tombe parfois sur de bon challenges

On n’a pas toujours l’occasion de partir de zéro

Pourquoi refactorer les tests unitaires

Page 3: L'amélioration des tests unitaires par le refactoring

Facile à comprendre

Facile à lire

On doit comprendre immédiatement ce qui se passe s’il échoue

Indépendant

Les tests doivent pouvoir s’exécuter dans n’importe quel ordre

Ne doit pas avoir de dépendances externes

Rapide

Exécution en moins de 0.01 secondes (ou 100 tests/seconde)

Doit tester une seule chose

Sinon il y a plusieurs raison d’échouer et le problème va être plus

difficile à diagnostiquer

3

Les bons tests unitaires

Page 4: L'amélioration des tests unitaires par le refactoring

Nom de la méthode de testDoit ce lire comme le résumé du test

Code du testsStructurer par block Arrange, Act et Assert

Nom de variables significatives

Utilisation de méthodes utilitaires Méthodes de création, arrange et assert pour faciliter la lecture

Utilisation de classes utilitaires et classes de base pour la réutilisation des méthodes utilitaires

Cacher ce qui n'est pas pertinent aux testsSetup répétitif, plomberie d'architecture, les mocks, les valeurs littérales qui ne sont pas importantes, etc...

Éviter les valeurs hard-coderUtilisation de valeurs aléatoire (avec AutoFixture)

4

Facile à comprendre

Page 5: L'amélioration des tests unitaires par le refactoring

Pas basé sur l'état des tests précédents

Chaque test est responsable de l’état initial du système sous test

Éviter les bases de données et les web services externes

DDD, architecture hexagonale, mocker les dépendances

externes

Voir les prochaines slides

5

Indépendant

Page 6: L'amélioration des tests unitaires par le refactoring

Le domaine d’affaire au centre

Les ports expose un API pour accéder au domaine

Les adaptateurs font le pont entre les ports et les

dépendances externes

6

Architecture Hexagonale (Ports & Adapters)

Domain

UI

API

Data Store

External

ServicesPorts

Adapters

Page 7: L'amélioration des tests unitaires par le refactoring

Séparer les différents sous-domaines

d’affaires dans leurs propres

« domaines / hexagones »

7

DDD et Bounded Contexts

Page 8: L'amélioration des tests unitaires par le refactoring

On teste juste le domaine

Le test utilise les ports entrants dans le domaine

On mocks ou stubs la partie adaptateur

8

Tests Unitaires

Domain

Test

Unitaire

Mocks ou

StubsPorts

Adapters

Page 9: L'amélioration des tests unitaires par le refactoring

On teste juste les adaptateurs

Le test utilise les ports sortants du domaine

Les adaptateurs appel les vrais dépendances externes

9

Tests d’Intégrations

Domain

Test

d’Intégration

Vrais

dépendances

externes

Ports

Adapters

Page 10: L'amélioration des tests unitaires par le refactoring

Pas d'appel externe

Utilisation d’Interfaces pour fournir des « tests doubles » dans les

test unitaires

Utiliser le principe d’Inversion de Contrôle (IoC) et Injection de

Dépendances (DI)

Utiliser des Mocks (et mocking framework) pour se faciliter la vie

Séparer les tests d'intégrations/systèmes

Tests unitaires pour le domaine d’affaire

Tests d’intégration pour les adaptateurs vers les systèmes

externes

10

Rapide

Page 11: L'amélioration des tests unitaires par le refactoring

Séparer les tests

Créer deux ou plusieurs tests à partir d’un test qui en fait trop

Extraire les tests d’intégrations

En cas d’échec le message doit être clair

Ajouter des traces au besoin

Toujours fournir une explication sur les Assert

Utiliser une libraires spécialiser (ie Fluent Assertions)

Arrange qui compare les objets attendus des objets

actuels

En implémentant ToString() (et/ou Equals() et GetHashCode())

Sérialisation Json pour comparer et afficher l’état des objets

11

Tester une seule chose

Page 12: L'amélioration des tests unitaires par le refactoring

C'est difficile avant d'avoir l'architecture en place

Moins adapté pour la plomberie

Si on se trompe on doit changer beaucoup de tests

Tester au bon niveau pour ne pas avoir à modifier les

tests tout le temps

Éviter de tester les méthodes et classes privées

Focus sur les API publiques du domaine (les Ports)

Penser à extraire le code complexe dans son propre sous-

système au besoin

Commands and Queries

Facilite les tests car on ne teste pas les requêtes de la même

façon que les commandes (modifications au système)

12

Planifier le développement piloté par les tests

TDD

Page 13: L'amélioration des tests unitaires par le refactoring

Références

SlideShare pour la présentation

• http://www.slideshare.net/PascalLaurin

BitBucket pour le code

• http://bit.ly/1ITLwca

DDD book by Eric Evans

• http://www.amazon.ca/dp/0321125215

DDD Quickly

• http://www.infoq.com/minibooks/domain-driven-design-quickly

FakeItEasy

• http://fakeiteasy.github.io/

AutoFixture

• https://github.com/AutoFixture/AutoFixture

Fasterflect

• https://fasterflect.codeplex.com/

Questions?

@plaurin78

[email protected]

www.pascallaurin.com