chouette! encore un bug!
DESCRIPTION
TRANSCRIPT
Chouette! Encore un bug!
Pascal Van Cauwenberghe
Bonjour
www.nayima.beblog.nayima.be
NAYIMAWe make play work
Consultant. Project Manager. Créateur de Jeux
CLAUSE DE NON-RESPONSABILITÉ
Clause de non-responsabilité (1)
• Cette présentation contient du code– Sans garantie que ça compile
• Cette présentation peut contenir 0, 1 ou plus insectes– A éviter pour les entomophobes
Clause de non-responsabilité (2)
• Basé sur des histoires vraies– Equipes différentes– Projets différents– Langages différents– Pays différents
• Chantier en cours– Notre code contient encore des bugs
Chouette! Encore un bug!
Comment passer toute la journée à corriger un tout petit bug
Maman, d’où viennent les bugs?
Il était une fois...
Le projet
L’application
Nous
Contexte
• Grande application web• Mission critical• Premier projet Agile de l’équipe• Nous devons modifier et étendre une petite
partie de l’application
Scene 1: un développeur trouve un bug
Que faites vous quand on vous dit “j’ai trouvé un bug...” ?
MERCI!
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. ....
Scene 2:Qu’est-ce qu’on fait avec le bug?
CECI N’EST PAS UN BUG
CECI EST UNE OPPORTUNITE
ASTUCE
• On ne cherche pas à reprocher• On ne veut pas trouver le “coupable”• Il faut un environnement sans blâme
• Attention au langage:– “Exercice”, “Apprendre”, “Améliorer”– “Nous”, “Notre code”, “Notre problème”
• Approche “Solution Focus”
Scene 3:L’équipe fait une Root Cause Analysis
5 développeurs + architecte
“Le client a droit à un remboursement jusqu’au moment de la livraison”
Qui voit le problème?boolean refundAllowed(Product product) { Datetime now = Datetime.now;
Datetime final = Datetime.parse("yyyy-MM-dd“, product.deliveryAt());
return now <= final ;}
MERCI!
On teste l’application
• Livraison le 26/05/2012 à 16:00• Il est maintenant 25/05/2012 12:00
• 25/05/2012 12:00 <= 26/05/2012 00:00 ?
On teste l’application
• Livraison le 26/05/2012 à 16:00• Il est maintenant 25/05/2012 12:00
• 25/05/2012 12:00 <= 26/05/2012 00:00 ?
Remboursement: OUI
On teste l’application
• Livraison le 25/05/2012 à 16:00• Il est maintenant 25/05/2012 12:00
• 25/05/2012 12:00 <= 25/05/2012 00:00 ?
On teste l’application
• Livraison le 25/05/2012 à 16:00• Il est maintenant 25/05/2012 12:00
• 25/05/2012 12:00 <= 25/05/2012 00:00 ?
Remboursement: NON
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. ...
Qu’est-ce qu’on fait maintenant?Est-ce qu’on corrige le bug?
C’est tellement facile!
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. ...
Un nouveau testvoid testRefundGivenWhenDeliveryLaterToday() {Datetime now = DateTime.now ;String endofDay = now.strftime(“yyyy-MM-dd") + " 23:59" ;Product product = ...product.deliveryAt(endOfDay) ;BusinessRule businessRule = ...bool refund = businessRule.refundAllowed(product);assertTrue(refund,“Remboursement jusqu'au moment de
la livraison, aussi si c'est le même jour") ;}
Un nouveau testvoid testRefundGivenWhenDeliveryLaterToday() {Datetime now = DateTime.now ;String endofDay = now.strftime("YYYY-MM-DD") + " 23:59" ;Product product = ...product.deliveryAt(endOfDay) ;BusinessRule businessRule = ...bool refund = businessRule.refundAllowed(product);assertTrue(refund,“Remboursement jusqu'au moment de
la livraison, aussi si c'est le même jour") ;}
Est-ce qu’on peut corriger le bug maintenant?
On corrige le bugboolean refundAllowed(Product product) { Datetime now = Datetime.now;
Datetime final = Datetime.parse("yyyy-MM-dd
HH:MM”, product.deliveryAt());
return now <= final ;}
Un nouveau testvoid testRefundGivenWhenDeliveryLaterToday() {Datetime now = DateTime.now ;String endofDay = now.strftime("YYYY-MM-DD") + " 23:59" ;Product product = ...product.deliveryAt(endOfDay) ;BusinessRule businessRule = ...bool refund = businessRule.refundAllowed(product);assertTrue(refund,“Remboursement jusqu'au moment de
la livraison, aussi si c'est le même jour") ;}
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. CORRIGER LE PROBLEME6. TOUS LES TESTS REUSSISSENT
Reactions de l’équipe (1)
• “Ce truc agile prendra beaucoup de temps si on va faire ça pour tous les bugs!”
• “Oui mais, on a plus de confiance qu'on a bien corrigé le bug en qu'on n'a pas cassé autre chose”
• “On a vraiment suivi notre principe ‘qualité sans compromis’: on a amélioré le code, même si le bug n'est pas dans notre code et avant que le client réclame”
Reactions de l’équipe (2)
• “On devrait contacter l'équipe responsable pour leur dire qu'on a corrigé le bug.”
• “Il y a peut-être déjà des réclamations des clients. Il faudrait aussi informer le service support client”
ASTUCE
• Maintenez une liste de choses à faire après la Root Cause Analysis (RCA)
• “On devrait...” => “On va...”
ON VA...
• Contacter l’équipe dev responsable• Informer le service support client
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. CORRIGER LE PROBLEME6. TOUS LES TESTS REUSSISSENT7. EXECUTER LES ACTIONS ISSUES DU RCA
“Travail bien fait!”
“Retournons au boulot!”
LA FIN
Et ils vécurent heureux à tout jamais
Ce n’est pas encore
fini !
Scene 4:Après la correction
Le testeur rejoint les développeurs et l’architecte
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. CORRIGER LE PROBLEME6. TOUS LES TESTS REUSSISSENT7. EXECUTER LES ACTION ISSUES DU RCA8. AMELIORER LES TESTS
Comment améliorer nos tests?
On aurait du trouver ce bug plus tôt
Comment améliorer nos tests?
On aurait du va trouver ce genre de bug plus tôt
Contexte (2)
• Presque 80% de code coverage par les tests automatiques sur toute l’application
• Ce module a une couverture de tests de 100%• Mais contient quand même un bug• Pourquoi?• Regardons les tests...
Qui voit le problème?
void testRefundGiven() { Product product = ... product.deliveryAt(“2050-12-31 19:00”) ; BusinessRule businessRule = ... bool allowed = businessRule.refundAllowed(product)
}
MERCI!
Comment améliorer les tests?
• Il n’y a pas d’ ASSERT !– Facile d’atteindre 100% de couverture
• Pourquoi 2050?– Qu’est-ce qui se passe le 1 janvier 2051?
• Il faut au moins 4 tests– Livraison avant aujourd’hui– Livraison aujourd’hui avant maintenant– Livraison aujourd’hui après maintenant– Livraison après aujourd’hui
Pourquoi?
• Les développeurs ne savent pas comment bien tester du code qui contient des dates– “2050” apparait souvent dans les tests
• Très peu de développeurs avec experience en unit testing
• Pas de formation ou coaching sur les aspects techniques Agile
ON VA...
• Contacter l’équipe dev responsable• Informer le service support client• Ajouter des tests pour les dates, qui peuvent
servir comme exemple• Montrer les exemples aux autres équipes
Reactions de l’équipe (3)
• Développeurs: « on a encore beaucoup à apprendre sur le unit testing »
• Architecte: « j'ai toujours eu des doutes au sujet de l'efficacité des tests automatiques. Maintenant je comprends mieux pourquoi. »
• Testeur: « Si vous voulez, je peux vous aider à définir les tests. »
Creusons encore un peu... Pourquoi des tests sans ASSERT?
• Peu d’experience en testing• But: “augmenter la couverture par les tests
automatiques” au lieu de “augmenter la qualité”
• Pression pour livrer des fonctionnalités• Développement TEST LAST au lieu de TEST FIRST• Pas de formation ou coaching sur les aspects
techniques Agile
ON VA...
• Contacter l’équipe dev responsable• Informer le service support client• Ajouter des tests pour les dates, qui peuvent
servir comme exemple• Montrer les exemples aux autres équipes• Appliquer le TDD en binôme avec le coach• Ajouter « manque de coaching technique » à
la liste des risques du coach meeting
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. CORRIGER LE PROBLEME6. TOUS LES TESTS REUSSISSENT7. EXECUTER LES ACTION ISSUES DU RCA8. AMELIORER LES TESTS9. AMELIORER LA FACON D’ECRIRE LES TESTS
LA FINEt ils vécurent
heureux à tout jamais
“On a encore beaucoup à apprendre”
Ce n’est pas encore
fini !
Scene 5:Après les tests
Un bug ne vient jamais tout seul
Est-ce que ce bug est unique?
On cherche dans le code...
• On trouve 10 instances où on parse cette date– 5 fois avec HH:MM– 5 fois sans HH:MM
• Chacun analyse un cas• Resultat: encore deux bugs
Qu’est-ce que vous dites?
MERCI!
Encore une fois
MERCI!
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. CORRIGER LE PROBLEME6. TOUS LES TESTS REUSSISSENT7. EXECUTER LES ACTION ISSUES DU RCA8. AMELIORER LES TESTS9. AMELIORER LA FACON D’ECRIRE LES TESTS10. DES PROBLEMES SIMILAIRES? GOTO 2
Reactions de l’équipe (4)
• “Qualité sans compromis”. C’est facile à dire mais très dur à implementer
• “Ecrire les tests et corriger les problèmes devient de plus en plus de la routine. Ca va de plus en plus vite!”
ENFIN, LA FIN?
Ce n’est pas encore
fini !
Est-ce que vous voyez encore un problème?
Creusons encore un peu... Pourquoi est-ce qu’on s’est trompé?
• On ne se rend pas compte qu’il y a une date + temps
• On a 10x le même code• => 10 opportunités de se tromper
• Eliminons la duplication
Améliorer Product
class Product {... // A enlever quand obsolète String deliveryAt() ; // Nouveau. Refactoring graduel des clients
DateTime deliveryAtDateTime() ;...}
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. CORRIGER LE PROBLEME6. TOUS LES TESTS REUSSISSENT7. EXECUTER LES ACTION ISSUES DU RCA8. AMELIORER LES TESTS9. AMELIORER LA FACON D’ECRIRE LES TESTS10. RECHERCHER DES PROBLEMES SIMILAIRES. GOTO 211. RENDRE IMPOSSIBLE DE REFAIRE LA MEME ERREUR
ASTUCE
• Si vous pensez qu’il faut écrire du commentaire pour votre code, repensez votre code
Avec commentaire
class A { void methodeA() ; // Il faut d’abord appeler methode A void methodeB() ; void methodeC() ;}...a.methodeB() ; // ERREURa.methodeA() ; // ERREUR!!
Sans commentaire
class A { B methodeA() ;}
class B { void methodeB() ; void methodeC() ;}
a.methodeA().methodeB() ;
Maman, d’où viennent les strings?
Creusons encore un peu...
Le projet
L’application
Systeme A
Systeme B
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
Le projet (vision)
L’application
Systeme A
Systeme B
ABCDEFGHIJKLMNO
ABCDEFGHIJKLMNO
ON VA...
• Contacter l’équipe dev responsable• Informer le service support client• Ajouter des tests pour les dates, qui peuvent servir
comme exemple• Montrer les exemples aux autres équipes• Appliquer le TDD en binôme avec le coach• Ajouter « manque de coaching technique » à la liste
des risques du coach meeting• Encapsuler toutes les données qui viennent de
l’exterieur
GRAND REFACTORING
Proposition A3
Proposition A3Description du problème
AVANT APRES
Etapes:1. .jdlkjds2. Kmlkdmlkd3. Dkqjdlkjds4. Sqkjlkdlksqmk5. BIERE !
Visualisation
ASTUCE
• L’A3 est visible pendant toute la période de refactoring
• Affichez l’A3 là où on ne peut pas le louper
• Limitez le nombre d’A3 qu’on peut afficher
Scene 6:Acte final
Résultats
1. On a travaillé tout l’après-midi avec une équipe de 7 personnes + un consultant pour corriger un bug de 6 caractères. Est-ce raisonnable?
2. On a trouvé beaucoup moins de bugs en test que dans des projets “normaux”. Est-ce qu’il y a un lien?
3. Ceci a soulagé le travail de l’équipe test, goulot d’étranglement du projet. Est-ce qu’il faut économiser sur l’effort d’une équipe non-goulot?
4. Le projet a été livré en 5 mois au lieu des 8 estimés. Est-ce que la qualité coute cher?
En résumé
Algoritme du code parfait
1. TROUVER UN BUG2. DIRE “MERCI!”3. REPRODUIRE LE PROBLEME4. AJOUTER (AU MOINS) UN TEST QUI ECHOUE5. CORRIGER LE PROBLEME6. TOUS LES TESTS REUSSISSENT7. EXECUTER LES ACTION ISSUES DU RCA8. AMELIORER LES TESTS9. AMELIORER LA FACON D’ECRIRE LES TESTS10. RECHERCHER DES PROBLEMES SIMILAIRES. GOTO 211. RENDRE IMPOSSIBLE DE REFAIRE LA MEME ERREUR
Mais surtout
MERCI!
Le challenge
• J’applique ceci avec mes équipes• On est loin du code parfait...• Je mesure les effets pendant un an• Je présente les résultats à la Conférence 2013• Si vous appliquez ces techniques• Contactez-moi• On présente nos résultats ensemble
CECI EST UNE OPPORTUNITE
LA FIN
Et ils vécurent heureux à tout jamais
7/7 SESSION FEEDBACK
MERCI
His Blog: blog.nayima.be
NAYIMAWe make play work
Consultant. Project Manager. Créateur de Jeux