7 astuces pour améliorer vos tests unitaires



Documents pareils
Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

LE LANGAGE POWERSHELL

Construction d un EDD avec SQL 2008 R2. D. Ploix - M2 Miage - EDD - Création

TP1. Outils Java Eléments de correction

Environnements de développement (intégrés)

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

SYNC FRAMEWORK AVEC SQLITE POUR APPLICATIONS WINDOWS STORE (WINRT) ET WINDOWS PHONE 8

Programmation par les Objets en Java

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

Cours 1: Java et les objets

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

Tp 1 correction. Structures de données (IF2)

Chapitre 10. Les interfaces Comparable et Comparator 1

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Projet de programmation (IK3) : TP n 1 Correction

Java Licence Professionnelle CISII,

Solutions du chapitre 4

Formation, Audit, Conseil, Développement, UX WinRT Silverlight WPF Android Windows Phone

Premiers Pas en Programmation Objet : les Classes et les Objets

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Exercices sur les interfaces

Alfstore workflow framework Spécification technique

Bases Java - Eclipse / Netbeans

TD/TP PAC - Programmation n 3

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Gestion distribuée (par sockets) de banque en Java

Cours d initiation à la programmation en C++ Johann Cuenin

as Architecture des Systèmes d Information

Module.NET 3 Les Assemblys.NET

Les structures. Chapitre 3

Cours d Algorithmique et de Langage C v 3.0

Généralités sur le Langage Java et éléments syntaxiques.

Conventions d écriture et outils de mise au point

TD3: tableaux avancées, première classe et chaînes

Java Licence professionnelle CISII,

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

ETUDE DE CAS en UML : GESTION DES COMMANDES DE PIECES FABRIQUEES PAR LA SOCIETE C

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Bases de programmation. Cours 5. Structurer les données

Programmation avec des objets : Cours 7. Menu du jour

Modélisation PHP Orientée Objet pour les Projets Modèle MVC (Modèle Vue Contrôleur) Mini Framework

Initiation à l algorithmique

Vérifier la qualité de vos applications logicielle de manière continue

4. Groupement d objets

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

2. Comprendre les définitions de classes

Programmer en JAVA. par Tama

Bases de données et fournisseurs de contenu

Apache Camel. Entreprise Integration Patterns. Raphaël Delaporte BreizhJUG

TP, première séquence d exercices.

Programmation Objet Java Correction

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Une introduction à Java

Programmation MacOSX / ios

Java c est quoi? Java pourquoi?

OpenPaaS Le réseau social d'entreprise

Auto-évaluation Programmation en Java

Création d objet imbriqué sous PowerShell.

Evaluation et mise en place d un serveur de messages pour Chamilo 2.0

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Méthode de Test. Pour WIKIROUTE. Rapport concernant les méthodes de tests à mettre en place pour assurer la fiabilité de notre projet annuel.

Définition des Webservices Ordre de paiement par . Version 1.0

Introduction à la programmation concurrente

UE Programmation Impérative Licence 2ème Année

ARDUINO DOSSIER RESSOURCE POUR LA CLASSE

Objets et Programmation. origine des langages orientés-objet

Plan du cours. Historique du langage Nouveautés de Java 7

Programmation par composants (1/3) Programmation par composants (2/3)

Exercices INF5171 : série #3 (Automne 2012)

Logiciel de Base. I. Représentation des nombres

Spring par la pratique

Le stockage local de données en HTML5

Mobyt Intégration par Webservice TABLE DES MATIERES

Héritage presque multiple en Java (1/2)

Corrigé des exercices sur les références

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Chapitre VI- La validation de la composition.

Tutoriel d installation de Hibernate avec Eclipse

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

La base de données XML exist. A. Belaïd

Langage Java. Classe de première SI

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Introduction au langage C

Table des matières PRESENTATION DU LANGAGE DS2 ET DE SES APPLICATIONS. Introduction

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Plan. Tests. 1. Introduction. 1. Introduction

XML par la pratique Bases indispensables, concepts et cas pratiques (3ième édition)

DotNet. Plan. Les outils de développement

Initiation à LabView : Les exemples d applications :

Intégration du moteur d envoi de SMS pour : Prestashop

Réalisation de SMSMail

Cours en ligne Développement Java pour le web

Transcription:

7 astuces pour améliorer vos tests unitaires Pascal Laurin Novembre 2015 Microsoft.NET MVP Développeur & Architect chez GSoft @plaurin78 pascal.laurin@outlook.com www.pascallaurin.com http://fr.slideshare.net/pascallaurin https://bitbucket.org/pascallaurin

Agenda 1. Trouver les bons noms 2. Avoir des messages d erreur clairs 3. Être facile à comprendre 4. Être rapide 5. Être indépendant 6. Tester une seule chose 7. Éviter les valeurs hard-coder

Principes des bons tests unitaires 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 raisons d échouer et le problème va être plus difficile à diagnostiquer 3

1. Trouver les bons noms Nom de la classe de test Comprendre sur quoi le test s applique Recherche rapide Nom de la méthode de test Doit se lire comme le résumé du test Surtout en cas d échec du test Dans le code du test Nom de variables significatives Utilisation du langage du domaine d affaire Objectif Documentation du système

1. Trouver les bons noms 5

2. Avoir des messages d erreur clairs En cas d échec le message doit être clair Pour diagnostiquer le problème rapidement Ajouter des traces au besoin Toujours fournir une explication sur les Assert Utiliser une libraires spécialiser (ie Fluent Assertions) Comparaison entre objets attendus et objets actuels En implémentant ToString() (et/ou Equals() et GetHashCode()) Sérialisation Json pour comparer et afficher l état des objets Objectif Trouver la source du problème le plus rapidement possible

2. Avoir des messages d erreur clairs 7

3. Être facile à comprendre Code du test Structure avec Arrange, Act et Assert 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 tests Setup répétitif, plomberie d'architecture, les mocks, les valeurs littérales qui ne sont pas importantes, etc... Objectif Garder le test pertinent longtemps (écrit une fois, lu plusieurs fois)

3. Être facile à comprendre [Fact] public void AddProductToOrder_ForExistingOrder_ShouldSaveOrderWithTheNewProduct() { const int OrderId = 12; const int NumberOfLine = 2; // Arrange var existingorder = CreateSomeOrder(OrderId, NumberOfLine); this.arrangeorderrepositoryloadorderreturns(existingorder); // Act this.orderservice.addproducttoorder(orderid, productid: 34, quantity: 56); } // Assert this.assertorderrepositorysaveorderwith(expectedcount: NumberOfLine + 1, expectednewproductid: 34, expectednewquantity: 56); private static Order CreateSomeOrder(int orderid, int numberofline) {...} private void ArrangeOrderRepositoryLoadOrderReturns(Order existingorder) {...} private void AssertOrderRepositorySaveOrderWith(int expectedcount, int expectednewproductid, int expectednewquantity) {...} 9

4. Être rapide Aucun 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 Objectif Rouler les tests unitaires après chaque modification au système

4. Être rapide public class OrderService { private readonly IOrderRepository orderrepository; public OrderService(IOrderRepository orderrepository) { this.orderrepository = orderrepository; } public void AddProductToOrder(int orderid, int productid, int quantity) { var order = this.orderrepository.loadorder(orderid); order.addorderline(productid, quantity); } } this.orderrepository.saveorder(order); public OrderServiceTests() { this.fakeorderrepository = A.Fake<IOrderRepository>(); this.orderservice = new OrderService(this.fakeOrderRepository); } 11

5. Être indépendant Ne pas être 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 services web externes Objectif Pouvoir exécuter un test seul ou tous les tests sans manipulation ou initialisation quelconque: éviter les faux positifs.

5. Être indépendant // Arrange var existingorder = CreateSomeOrder(OrderId, NumberOfLine);... private static Order CreateSomeOrder(int orderid, int numberofline) { var existingorder = new Order { Id = orderid }; for (var i = 0; i < numberofline; i++) { existingorder.addorderline(productid: 123456 + i, quantity: 999); } } return existingorder; 13

6. Tester une seule chose 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 Séparer les tests unitaires Créer deux ou plusieurs tests à partir d un test qui en fait trop Extraire les tests d intégrations Objectif En cas d échec il n y a qu une seule cause: diagnostique rapide

7. Éviter les valeurs hard-coder Utilisation de librairie de génération de valeurs aléatoire i.e. AutoFixture Ne garder que les valeurs pertinentes au test Objectif Identifier clairement les valeurs qui vont influencer le test : aide la compréhension

7. Éviter les valeurs hard-coder [Fact] // Avant public void AddProductToOrder_ForExistingOrder_ShouldSaveOrderWithTheNewProduct() { const int OrderId = 12; const int NumberOfLine = 2; // Arrange var existingorder = CreateSomeOrder(OrderId, NumberOfLine); this.arrangeorderrepositoryloadorderreturns(existingorder); // Act this.orderservice.addproducttoorder(orderid, productid: 34, quantity: 56); } // Assert this.assertorderrepositorysaveorderwith(expectedcount: NumberOfLine + 1, expectednewproductid: 34, expectednewquantity: 56); 16

7. Éviter les valeurs hard-coder [Fact] // Après public void AddProductToOrder_ForExistingOrder_ShouldSaveOrderWithTheNewProduct() { var orderid = this.fixture.create<int>(); var productid = this.fixture.create<int>(); var quantity = this.fixture.create<int>(); const int NumberOfLine = 2; // Arrange var existingorder = this.createsomeorder(orderid, NumberOfLine); this.arrangeorderrepositoryloadorderreturns(existingorder); // Act this.orderservice.addproducttoorder(orderid, productid: productid, quantity: quantity); } // Assert this.assertorderrepositorysaveorderwith(expectedcount: NumberOfLine + 1, expectednewproductid: productid, expectednewquantity: quantity); 17

Questions? Références BitBucket pour le code http://bit.ly/1itlwca FakeItEasy http://fakeiteasy.github.io/ AutoFixture https://github.com/autofixture/autofixture @plaurin78 pascal.laurin@outlook.com www.pascallaurin.com http://fr.slideshare.net/pascallaurin https://bitbucket.org/pascallaurin