-->

mercredi 25 avril 2012

Intégration des tests dans le cycle projet scrum et l'équipe

Cet article à été co-écrit avec Thibaut DAVID (Voir son Blog)


Définitions utiles à la compréhension de l'article:
Product Backlog Item (PBI): Un PBI correspond à une fonctionnalité de l'application
Exemple de PBI: Administrateur / Ajouter utilisateur /
Acceptance Test (AT): Un AT est un item qui permet de définir les règles de fonctionnement de chaque PBI (1 PBI -> n AT), les AT correspondent à tous les cas de tests permettant de couvrir la fonctionnalité afin de s'assurer de son bon fonctionnement.

  1. Les différents types de tests

Dans cet article nous allons voir les différents types de test qui ont été mis en place dans notre SI afin de bien comprendre le contexte de travail. Dans les prochains articles, nous nous attarderons principalement sur les tests fonctionnels automatisés (Coded UI Test) et leurs mises en place.



Ce quadrant des tests agile permet d'avoir une vue d'ensemble sur tous les types de test qu'il est possible de mettre en place dans un contexte agile et permet de mieux comprendre les impacts de ceux-ci sur les équipes de développement.

Source: Brian Marick






Dans un contexte agile Scrum, il est important de définir les tests que nous souhaitons mettre en place pour tester au mieux l'application dans les délais impartis, en effet, connaitre ce que nous devrons développer comme tests permet de prendre en compte cette charge lors de l'estimation de la complexité et de la durée des PBI.

Nous effectuons des Sprint de 2 semaines et nous avons décidé de mettre en place  4 types de tests :
  • Q1 Les tests unitaires (automatisés) en vocabulaire TFS ce sont les « Units Tests » (développeurs)
  • Q2 Les tests de navigation (automatisés) en vocabulaire TFS ce sont les « Web Tests » (développeurs)
  • Q2 Les tests fonctionnels  (automatisés) en vocabulaire TFS ce sont les « Coded UI Tests » (testeur)
  • Q3 Les tests fonctionnels exploratoires (manuels) (testeur)
Les tests de charge ne sont pas systématiquement mis en place car nos applications sont principalement dans un contexte intranet avec un maximum de 2000 agents.
Toutefois, il est arrivé de mettre en place des tests de charge pour le déploiement d'application internet, dans ce cas, nous avons utilisé les web tests existants pour les réutiliser en tant que test de charge.
  1. Les tests automatisés


L’utilisation des tests automatisés de toute nature (unitaire, web, coded ui…) permet :
·              De s’assurer que les refactoring réalisés dans le cadre du développement de nouvelles fonctionnalités au fil des sprints ne sont pas générateurs de bugs de régression.
·              D’architecturer et de découper d’une meilleure façon le code.
Tous les tests unitaires et les tests de navigation sont exécutés systématiquement à chaque check-in par le serveur de build.
Lorsqu’un build échoue (pour un problème de compilation ou de test) sa résolution doit devenir la priorité de toute l’équipe. Elle ne doit pas remettre à plus tard la correction de ce build, sous peine de masquer d’autres problèmes et de se retrouver, au bout de quelques heures, avec un empilement de problèmes d’intégration.
A chaque check-in le serveur de build compile le projet, déploie les composants de l’application sur les serveurs de test, déploie la base de donnée sur l’instance de test, déploie les données de tests dans la base de données de test et joue les tests sur cet environnement. (Unit Test et Web Test). Les tests fonctionnels eux sont lancés par un build séparé qui utilise le résultat du build précédant.
  1. Tests unitaires (obligatoire)

La réalisation de tests unitaires pour les méthodes business, repository et contrôleur est obligatoire et idéalement le faire en TDD aidera à améliorer la structure du code.
Afin de s’assurer que la testabilité des composants est faisable nous utilisons plusieurs outils et patterns :
  • Le pattern repository
  • L’injection de dépendances avec Microsoft Unity 2.0
  • Le mocking d’objets avec RhinoMock
Les tests unitaires ne doivent jamais dépendre de la base de données ou d’un service web ou d’une quelconque ressource externe. Dans ce cas il faut Mocker cette ressource.
  1. Tests web (obligatoire et systématique)

Les objectifs couverts par l’utilisation des tests web sont :
  • Détecter les erreurs HTTP 404, 500 sur chaque page de l’application et leurs ressources (images, css, javascript…)
  • De valider que les utilisateurs n’ont pas accès aux pages dont ils n’ont pas les droits. Présence d’erreur http 403.
  • Détecter que le temps de chargement de chaque page est acceptable.
  • Tester l’intégration de l’application avec son environnement (ressources externes graphiques, css, scripts, base de données, logger…)
  • Tester le déploiement de l’application.
On s’attache ici à faire des tests dit de navigation. On ne clique pas sur un bouton,  on ne remplit pas de formulaire…. On ne fait qu’afficher une page, puis une autre. D’autres tests dit de scénario sont envisageables avec ce type de test, ils sont plus complexes et demandent un peu plus d’investissement en temps de développement et en maintenance. Il est à noter que la systématisation des tests de scénario est à mettre en balance avec les capacités en ressources à les créer et les maintenir.
La règle est que chaque création de page doit être accompagnée d’un test web simple qui accède à cette page en tant qu’utilisateur ayant les droits et le cas échéant en tant qu’utilisateur n’ayant pas les droits ou des droits limités.
Comme dit plus haut, ces tests s’appuient sur des données de test qui sont déployées avant l’exécution de chaque test.
  1. Les CodedUiTest ou tests fonctionnels

L’objectif de ces tests est de détecter des erreurs sur les interactions de l’utilisateur.
NB : Ils ne sont pas exécutés par le serveur de build à chaque check in.
Ces tests s’effectuent uniquement au niveau utilisateur. Il peut s’avérer nécessaire de développer des applications spécifiques (et/ou temporaires) permettant de modifier ou d’accéder à certaines données du projet.
Un projet de test fonctionnel sur Visual Studio est composé de deux parties :
Les actions (UIMAp), qui sont les étapes élémentaires de nos tests (cliquer sur un bouton, vérifier la valeur d’un champ, accéder à un page web, …), les fonctionnalités (CodedUITest), qui sont un ensemble de fonction (une fonction = un Acceptance Test) permettant de couvrir les PBI.
Organisation du projet sous Visual Studio
Projet_de_test
EnsembleFonctionnel1
Fonctionnalité1.cs
Fonctionnalité2.cs
Fonctionnalité3.cs
EnsembleFonctionnel2
Fonctionnalité4.cs
Fonctionnalité5.cs
EnsembleFonctionnel3
Fonctionnalité6.cs
Fonctionnalité7.cs
Fonctionnalité8.cs
Common
Classeutile.cs
TestRunner.cs
UIMap
EnsembleFonctionnel1.uitest
EnsembleFonctionnel1.cs
EnsembleFonctionnel1.Designer.cs
EnsembleFonctionnel2.uitest
EnsembleFonctionnel2.cs
EnsembleFonctionnel2.Designer.cs
EnsembleFonctionnel3.uitest
EnsembleFonctionnel3.cs
EnsembleFonctionnel3.Designer.cs


Il est important de faire en sorte qu’à la fin du scénario, on soit revenu au même état qu’au début. Par exemple si on ajoute une donnée dans la base de données, il faut la supprimer à la fin. Cela permet de pouvoir lancer les scénarios que l’on veut dans l’ordre que l’on veut.
  1. Création et déploiement du jeu de données de test

Pour que les tests automatisés soient significatifs il faut avoir un minimum de données dans la base de données. Ces données doivent être bien connues et définies par la stratégie de test, c’est pourquoi elles sont systématiquement déployées avant chaque session de test, après, bien sûr, que la base de données ait été vidée.
La génération des données se base sur des sources de données dans des fichiers CSV (un fichier par table SQL) et un fichier T4 qui génère les requêtes SQL qui permettront d’insérer ces données dans la base.

  1. Les tests exploratoires


L'exécution des tests exploratoires manuels doit se faire sur un environnement différent des tests automatisés pour ne pas corrompre les données lors de l'exécution des tests automatiques. Mais aussi pour faire des tests avec une base de données plus complète et donc plus proche de l'environnement de production. Ces tests seront alors pertinent et relateront le comportement qui sera visible en production.

Ces tests permettent de faire les tests d'interface, en effet, un bouton trop gros ou un peu décalé ne sera pas remonté comme un bug par les tests automatisés, il faut donc être très vigilent à l'apparence de l'application lors de ces tests.

Les tests exploratoires doivent également s'assurer du bon fonctionnement de l'application dans les cas "extrèmes", nous allons donc chercher à naviguer de manière non conforme au fonctionnement initialement prévu. Le but de ces tests est de s'assurer que l'application réponde aux demandes utilisateurs avec le résultat attendu quel que soit l'utilisation qu'il en fait.
  1. Répartition des tests sur les environnements

Voici le détails des environnements qui ont été mis en place avec la correspondance des tests déployés sur chacun.

Lab: Environnement virtuel distinct mis en place pour chaque projet afin de créer et de déployer les tests automatisés, les données de cet environnement sont totalement maitrisées. (permet de lancer l'exécution des tests automatiser sans bloquer de machine, le testeur peur continuer à travailler sur son poste de travail).
Test: Environnement utilisé pour les tests d'intégration, exécute les web test à chaque check-in de code.
Dev: Machine local du développeur, il doit s'assurer que les tests unitaires passent sur sa machine avant de lancer le check-in
Recette: Environnement mis en place qui permet de faire des tests exploratoires dans un contexte "iso" production. Cet environnement est mis à disposition de la MOA (maitrise d'ouvrage: entité porteuse du besoin)



1 commentaire: