Au cours des derniers mois, j'ai rédigé plus de 600 tests unitaires (Peut-être plus, j'ai perdu le compte). Grâce à cette présentation, vous pourrez éviter de devenir aussi cinglé que moi en bénéficiant de mon expérience, alors que je vous expliquerais comment rédiger des tests avec les Fakes de Microsoft (autrefois appelés Moles), les obstacles à éviter, des trucs pour sauver du temps lors de la rédaction de tests, et à quelle déité païenne vous devez faire des sacrifices pour que tout fonctionne. À moins que je me sois trompé de livre...
Conférencier: Frédéric Simard
2. À propos de moi
Presque 14 ans d'expérience en développement, dont 13 en
.Net
Tech Lead au Ministère de l'Immigration pour le compte de
CGI
Étudiant à la Maîtrise en Génie Logiciel à l'École de
Technologie Supérieure
Passionné par l'ergonomie, l'architecture logicielle et
l’intelligence artificielle
Ma dernière conférence au Groupe des Développeurs
Microsoft Montréal remonte à plus de 10 ans
3. Pourquoi rédiger des tests unitaires?
C'est le filet de sécurité qui nous permet de valider les
changements qui sont faits à une méthode
Les tests unitaires nous forcent à remettre en question la
conception interne d'une méthode
Ils vérifient que les bonnes données donnent les bonnes
résultats, mais aussi que les mauvaises données sont gérées
adéquatement (happy path vs alternate/exceptions path)
4. Qu'est-ce que les Fakes*?
C'est le Framework pour écrire des tests unitaires de
Microsoft. Il a été introduit dans VS 2012.
Nécessite la .dll:
Microsoft.VisualStudio.QualityTools.UnitTestFramework
Comparable à Isolator de la compagnie TypeMock.
Les Fakes ne peuvent pas être utilisés avec VS 2010
*Avant 2012, il y avait les Moles. Ceux-ci sont devenus les Fakes, mais des
modifications sont requises pour passer de Moles à Fakes
5. Qu'est-ce que les Stubs?
Dans le framework des Fakes, les stubs fonctionnent de la
même façon que les autres frameworks classiques (NUnit,
RhinoMock, MOQ)
Ce sont des objets vides qui implémente un interface avec du
code qui ne fait rien, ou presque.
On a la capacité de spécifier ce que l’on désire qui soit fait
quand un appel de méthode est fait.
Ils sont idéals pour limiter la portée de la méthode que l’on
désire tester
Ce devrait être l’outil le plus utilisé quand l’architecture de
votre solution a été fait pour limiter le couplage et maximiser
la cohésion, car il requièrent que la classe utilise un interface.
6. Qu'est-ce que les Shims?
Les shims ont été développés pour permettre d'isoler votre code des librairies qui
sont externes à votre solution.
C’est l’équivalent des mocks dans le framework Fakes, mais ceux-ci ont des
capacités que les mocks n’ont habituellement pas. Comme un mock, un shim est
une copie complète ou partielle de la classe choisie.
Comme les mocks, ils permettent de créer un détour sur les méthodes choisies.
Ils permettent aussi d’intercepter des appels au constructeurs ainsi qu’au
méthodes statiques!
Mscorlib ne peut pas être le sujet de shim, ni la plupart de l'assembly System
(mauvaise idée!)
9. DEMO: Stub
Création d’un stub
Spécification du résultat d’un appel de méthode
Spécification d’une méthode déléguée
10. Démo: Shim
ShimContext.Create()
Behavior
Fallthrough: operation régulière de la classe
BehaveAsCurrent dépend du mode.
BehaveAsNotImplemented
Constructor, StaticConstructor
AllInstances vs Instance spécifique
11. Problèmes rencontrés avec les Fakes
Il semble y avoir certains cas où les shims ne fonctionnent pas lorsque les
tests unitaires sont exécutés en groupe. Individuellement, il n’y a pas de
problème. Le cas est lié au vstest.executionengine.x86 qui n’est soit pas
compatible ou ne démarre pas. Ceci se produit dans le cas où:
On utilise un serveur de compilation non-TFS;
On essaie d’obtenir la couverture du code lorsqu’il y a un fichier de
configuration «Test settings»
Solution: sur le serveur, on a créé un filtre qui exclu l’exécution des tests avec
l’attribut [TestCategory(« shim »)]. Les tests avec des Shims sont vérifiés sur les
postes de développeurs.
Avec un serveur de compilation qui n’est pas TFS (TeamCity, pour être
précis) il semble se produire un cas étrange lorsque nous avons des
projets de tests multiples qui utilisent les mêmes .dll de fakes. Il s’agit
d’une sorte de « race condition » où le premier qui résout la .dll
fonctionne, mais les autres entrent en conflit.
Solution: mettre tous les tests dans un seul projet, regroupé dans des dossiers
différents.
12. Créer des tests qui utilisent la réflexion
Lorsqu’on a une certaine quantité de classes qui sont identiques en grande partie
au point de vue fonctionnel, il y a possibilité de couvrir un ensemble de tests par
réflexion.
Idéalement, les tests devraient être refactorisés en utilisant un pattern approprié
(i.e. Template Method)
Mais si ce n’est pas possible:
Assembly.Load
13. Conclusion
Le framework de Fakes est intéressant par sa capacité de
faire les choses. Toutefois, certains le considère
« dangereux » parce qu’il permet de faire des choses qui
devraient être résolues par une architecture appropriée.
Toutefois, de façon pratique, on a pas toujours le choix.
Il est simple à utiliser une fois qu’on est familier avec et que
les configurations sont faites.