Atelier IceScrum 7 Juin
Plus d'info sur Sigmat.fr
"""""
iceScrum fait partie de la famille des outils de gestion de projet agile (bien qu'il fasse plus que de la gestion de projet). Il vient d'être remarqué dans une enquête sur les outils agiles récemment publiée : Tools used for agile projects (le texte est en anglais, mais l'auteure est française).
iceScrum est un projet Open Source qui a une origine entièrement toulousaine. Les membres actuels de la communauté et de l'équipe de développement et de support restent très majoritairement toulousains.
Plusieurs d'entre eux seront présents lors de l'atelier organisé par la SigmaT le lundi 7 juin à la Maison des associations, à partir de 17h30.
Vous pourrez assister à une démo spéciale de l'outil et leur poser toutes les questions qui vous intéressent sur iceScrum.
"""""
Sigmat 14, le 18 Juin
Ma démarche de test
Voilà le lien
http://lolcx.blogspot.com/2010/05/strategie-de-test.html
Scrum et CMMI Niveau 5 : Potion magique pour les guerriers du code
Je viens de lire le papier de Jeff Sutherland, Carsten Ruseng Jakobsen et Kent Johnson sur Scrum and CMMI Level 5 : The Magic Potion for Code Warriors
Bon, ça date un peu (Mai 2007), mais que voulez-vous, je ne suis pas à jour, c'est tout.
Ce que j'en retire, il faut y voir :
- Agile comme une boite à outil répondant aux besoins d'institutionnalisation (différent d'industrialisation)
- Lean comme une étude d'opportunités
- CMMI comme support à la conduite de changement et la propagation des bonnes pratiques au reste de l'entreprise.
Et tout ça pour avec chiffres à la clé démontrant le bien fondé de la démarche.
Côté productivité, mais éminents collègues du SigmaT me font remarquer qu'il serait plus judicieux de parler d'efficacité. Effectivement si l'on regarde le mode de calcul de la productivité utilisé, c'est le rapport du nombre total de lignes de code produites pour la totalité des heures comptées sur un projet. Donc toutes activités confondues. Hors l'amélioration par l'élimination du gaspillage fait que mathématiquement le nombre d'heure total diminue. Le ratio de LOC/h diminue donc mécaniquement. On peut effectivement plutôt parler d'efficacité. Le résultat est là : réduction des coûts.
En tout cas, bonne expérience montrant que la combinaison du mieux de chaque améliore le tout.
Pour ceux comme moi qui ne sont pas à jour, je vous engage à lire ce papier et vous en faire votre propre opinion!
Strategie de test
Préambule
Ma démarche de test
- Définir clairement ce qui doit ou pas être testé et comment, quand, par qui.
- L’éternelle roue de Deming : Plan-Do-Check-Act que l’on utilise comme une fractale.
- Au delà des métriques. Ça n’a aucun sens de demander une couverture à 70%. Que fait-on des 30% restant, à quoi correspondent-ils, comment choisir ce qui est dans les 30 ou dans les 70 ?
- Autre approche, on teste tous ce qui est de type DAO, classes de service, classes métiers, classes outils. Cette approche est déjà plus efficace dans l’aide au choix.
- C’est aussi trouver le bon niveau de test entre coût de développement et retour sur investissement
- Faire un test est couteux, mais il faut le ramener au nombre de fois où l’on pourra le jouer. Avec une contrainte de temps et de budget comme imposé par les contrats au forfait, il n’est inimaginable de TOUT tester. Certaines exigences seront plus couteuses à tester que d’attendre le bug et de le corriger (là, ça va pas plaire, mais c’est la dur réalité des projets), pour la simple et bonne raison, qu’il sera traité dans un autre budget (garantie, tma) et un autre temps.
- Là encore, il va donc falloir aider l’équipe à choisir.
- d’oublier les approches manuelles
- d’expliciter les limites
- de traiter le qualitatif et le quantitatif
- C’est irréalisable par un humain
- Les limites sont aussi importantes que les cas standards pour l’utilisateur de la librairie
- Le retour sur investissement est important : l’information fournie sur la fonction versus le volume du code de test
- Garantir le besoin au niveau « mécanique » : qualitatif et quantitatif
- Fournir un moyen de contrôle de stabilité : tests de non régression
- Définir les limites d’utilisation : mieux que de la spec détaillée
Reprenons
- impossible de tout tester
- il y aura donc des bugs
- tests en couches
- tests automatiques sur résultat de référence
- être alerté d’un changement de comportement, ce n’est pas encore un bug. Il faut vérifier alors si c’est l’application qui n’est pas cohérente ou le test (ou le résultat de référence) qui n’a pas évolué.
- de savoir quelle couche l’a découvert. Par exemple, si le bug est découvert sur les tests d’IHM, mais pas par les tests unitaires, normalement le bug est au niveau de l’interaction entre le code de gestion et l’interface utilisateur (MVC)
Tests en couches
- Les tests unitaires s’occupent de vérifier le code.
- Les tests IHM, testent l’interaction utilisateur avec ce code.
- Les tests fonctionnels ou d’acceptance testent la conformité aux besoins (exigences fonctionnelles) du client, au cahier des charges.
- Les tests d’intégration n’interviennent que s’il on a de l’intégration entre sous systèmes. Pas entre composants, c’est du niveau tests unitaires.
- la mécanique : des tests unitaires pour la couche technique d’échange, objectif: Contrôler le modèle échangé
- l’interface métier : vérifier qu’au-delà du modèle d’échange, les deux sous systèmes l’interprètent de la même manière
- et enfin le fonctionnel, c’est l’aspect utilisateur du système complet, qui ne s’intéresse qu’à la partie métier pure, ce que l’utilisateur va faire avec son système….
Tests automatiques sur résultats de référence
Le Jeu
ID : | US1 |
Nom : | Créer un nouvel utilisateur |
Description : | En tant que : * ADMINISTRATEUR (utilisateur ayant des droits d'administration) Je peux : * créer un utilisateur Afin de : * insérer un utilisateur dans le référentiel de données |
Critères d’acceptance : | * Vérifier que seul un utilisateur ayant le droit d'administration à accès à l'écran de création d'un utilisateur * Vérifier que les champs de saisie "login" et "mot de passe" sont obligatoires (le bouton "Créer" n'est actif que si les champs ne sont pas vides) * Vérifier que les champs de saisie "login" et "mot de passe" respectent le format spécifié (le bouton "Créer" n'est actif que si les champs "login" et "mot de passe" contiennent respectivement au moins 4 et 6 caractères) * Vérifier que si un utilisateur avec le login saisi existe déjà en base un message d'avertissement s'affiche : "Un utilisateur avec cet identifiant existe déjà" * Vérifier qu'après l'action de création, un message d'information s'affiche : "Utilisateur créé avec succès" * Vérifier qu'après l'action de création, l'écran de création d'un utilisateur est vierge * Vérifier qu'après l'action de création, un enregistrement est présent dans la table USER avec les attributs saisis et la date du jour dans le champ CREATION_DATE |
- pouvoir identifier l’utilisateur de l’appli. Il manque une user story précisant qu’il faut se signer sur l’appli pour tester le premier critère, donc on teste mais on bouchonne. Mais en même temps la user story ne précise pas comment l’utilisateur fait pour accéder à l’écran de création, un bouton, un lien, un url ??? Dans ce cas, il faut demander précision au product owner, normalement lors du workshop ou pendant le sprint, dans ce cas, on ajoute une exigence à la story.
- Réponse :
Compléments | - un bouton (ou lien) "Nouvel utilisateur" inactif (ou invisible, encore mieux) pour ceux qui n'ont pas les droits. On n'informe pas la personne qu'elle n'a pas les droits, ça peux la vexer :-) . |
- Il faut un écran de base d’où sera exécuté l’action et un écran de création d’un utilisateur.
- Une base de données avec une table USER avec champs login, motdepasse et creation_date. (Ce n’est pas un besoin fonctionnel, mais le client le demande, alors !)
- test si utilisateur est admin alors écran création utilisateur dispo (bouton « Nouvel utilisateur» actif)
- test si utilisateur pas admin alors bouton « nouvel utilisateur » invisible
- C’est un outil de test dit « keyword driven ». Hormis une phase d’apprentissage de l’outil, il ne nécessite aucune compétence de développement.
- Il permet de tester l’interaction avec le sous système. Les IHMs : de type web couplé avec Sélenium, ou de type java swing. Les process simples, ou telnet, ssh…
- Et de 3, parce que j’en ai eu le besoin, on peut facilement ajouter des keywords de base, cela nécessite un peu de développement.
Scénario en mode non admin.
- Lancer l’application en mode non admin
- Sélection de la fenêtre principale
- Vérifier que le bouton « Nouvel Utilisateur » n’est pas visible (c’est ce keyword que j’ai du ajouter)
Test Mode Non Admin
Test Case | Action | Arguments | ||
[Setup] | Lancer appli en mode non Admin | |||
Button Should Not Be Visible | ${boutonNewUser} | |||
Keyword | Action | Arguments | ||
Start Application | org.lcx.myapp.MySampleApp | |||
Select Window | ${AppName} | |||
Scénario en mode admin.
- Lancer Appli En Mode Admin
- Lancer l’application en mode admin
- Sélection la fenêtre principale
- Ouvrir Ecran Creation Utilisateur
- Vérifier que le bouton « Nouvel Utilisateur » est actif
- Cliquer sur le bouton « Nouvel Utilisateur »
- Vérifier que l’écran est ouvert
- Les Champs Sont Obligatoires
- Vérifier que le bouton créer est inactif
- Saisir 4 caractères dans le login et 6 dans le password
- Vérifier que le bouton créer est actif
- Vider les champs login et password
- Vérifier que le bouton créer est inactif
- Les Champs Sont Au Bon Format
- Vérifier que le bouton créer est inactif
- Saisir 3 caractères dans le login et 5 dans le password
- Vérifier que le bouton créer est toujours inactif
- Saisir 4 caractères dans le login et 6 dans le password
- Vérifier que le bouton créer est actif
- Ce test n’est pas suffisant, il faudra un test unitaire pour compléter le contrôle de la règle de gestion
- Créer Un Utilisateur
- Saisir 4 caractères dans le login et 6 dans le password
- Cliquer sur le bouton créer
- Vérifier l’affichage du message de création
- Fermer le message
- Vérifier que les champs login et password sont vides.
- Vérifier que les données existent en base dans la table User. (je n’ai volontairement pas testé la date)
- Créer Un Utilisateur en double
- Re-saisir le même login et password
- Cliquer sur le bouton créer
- Vérifier le message d’erreur
- Fermer le message
- Supprimer les données de la table User
Test Fonctionel Mode Admin
Setting | Value | |||
Suite Teardown | Delete table user |
Test Case | Action | Arguments | ||
[Setup] | Lancer appli en mode Admin | |||
Button Should Be Enabled | ${boutonNewUser} | |||
Ouvrir ecran creation utilisateur | ||||
Les champs sont obligatoires | ||||
Les champs sont au bon format | ||||
Creer un utilisateur | ||||
Creer Un Utilisateur en double | ||||
Keyword | Action | Arguments | ||
Start Application | org.lcx.myapp.MySampleApp | -admin | ||
Select Window | ${AppName} | |||
Push Button | ${boutonNewUser} | |||
Select Context | ${newUserPanel} | |||
${buttonTest} = | Get Button Text | ${boutonCreer} | ||
Should Be Equal | Create | ${buttonTest} | ||
Clear Text Field | ${login} | |||
Clear Text Field | ${password} | |||
Button Should Be Disabled | ${boutonCreer} | |||
Insert Into Text Field | ${login} | toto | ||
Insert Into Text Field | ${password} | tatata | ||
Button Should Be Enabled | ${boutonCreer} | |||
Clear Text Field | ${login} | |||
Clear Text Field | ${password} | |||
Button Should Be Disabled | ${boutonCreer} | |||
Clear Text Field | ${login} | |||
Clear Text Field | ${password} | |||
Insert Into Text Field | ${login} | 123 | ||
Button Should Be Disabled | ${boutonCreer} | |||
Insert Into Text Field | ${password} | 12345 | ||
Button Should Be Disabled | ${boutonCreer} | |||
Insert Into Text Field | ${login} | 1234 | ||
Button Should Be Disabled | ${boutonCreer} | |||
Insert Into Text Field | ${password} | 123456 | ||
Button Should Be Enabled | ${boutonCreer} | |||
Select Window | ${AppName} | |||
Insert Into Text Field | ${login} | John | ||
Insert Into Text Field | ${password} | 123456 | ||
Push Button | ${boutonCreer} | |||
Check Message | Utilisateur | Utilisateur cree avec succes | ||
Select Window | ${AppName} | |||
${newLoginValue} = | Get Text Field Value | ${login} | ||
Should Be Empty | ${newLoginValue} | |||
${newPasswordValue} = | Get Text Field Value | ${password} | ||
Should Be Empty | ${newPasswordValue} | |||
Connect To Database | com.mysql.jdbc.Driver | jdbc:mysql://localhost/mysampledb | mysampleuser | |
... | mysampleuser | |||
Check Content For Row Identified By Where Clause | login,password | John|123456 | user | |
... | login="John" | |||
Disconnect From Database | ||||
[Arguments] | ${title} | ${message} | ||
Select Dialog | ${title} | |||
${messageText} | Get Label Content | OptionPane.label | ||
Should Be Equal | ${message} | ${messageText} | ||
Close All Dialogs | ||||
Select Window | ${AppName} | |||
Insert Into Text Field | ${login} | Maurice | ||
Insert Into Text Field | ${password} | 123456 | ||
Push Button | ${boutonCreer} | |||
Check Message | Utilisateur | Utilisateur cree avec succes | ||
Select Window | ${AppName} | |||
Insert Into Text Field | ${login} | Maurice | ||
Insert Into Text Field | ${password} | 654321 | ||
Push Button | ${boutonCreer} | |||
Check Message | Avertissement | Un utilisateur avec cet identifiant existe deja | ||
Connect To Database | com.mysql.jdbc.Driver | jdbc:mysql://localhost/mysampledb | mysampleuser | |
... | mysampleuser | |||
Delete All Rows From Table | user | |||
Disconnect From Database | ||||
Tests développeurs
Conclusion
- D’un, je respecte le contrat défini par les critères d’acceptance,
- Deux, je communique avec le client sur la précision de son besoin,
- Trois, je garantie un jeu de test de non régression automatisé.
Annexe Tests unitaires
- a = 1, b = 2, c = 3 è pas de résultat
- a = 1, b = 4, c = 4 è racine double X1=X2
- a = 1, b = 5, c = 3 è deux racines différentes X1 != X2
- a = -1, b de 10 à 100000, c = 1