<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog de Bruno Orsier</title>
	<atom:link href="https://blog.developpez.com/bruno-orsier/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/bruno-orsier</link>
	<description></description>
	<lastBuildDate>Thu, 04 Apr 2013 16:06:21 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>R&#233;trospectives, la directive premi&#232;re</title>
		<link>https://blog.developpez.com/bruno-orsier/p11890/developpement-agile/rtrospectives-la-directive-premire</link>
		<comments>https://blog.developpez.com/bruno-orsier/p11890/developpement-agile/rtrospectives-la-directive-premire#comments</comments>
		<pubDate>Thu, 04 Apr 2013 16:06:21 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[Développement agile]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/bruno-orsier/?p=88</guid>
		<description><![CDATA[La directive première (la &#34;prime retrospective&#34;) est une phrase que j&#8217;utilise avec les équipes novices : Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand. &#160;&#160;&#160; &#8212; Norm Kerth Voici la version française : Indépendamment de ce que nous découvrons, nous comprenons et nous croyons sincèrement que [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>La directive première (la &quot;prime retrospective&quot;) est une phrase que j&rsquo;utilise avec les équipes novices :</p>
<blockquote><p>Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand.</p>
</blockquote>
<blockquote><p>&#160;&#160;&#160; &#8212; Norm Kerth</p>
</blockquote>
<p>Voici la version française :</p>
<blockquote><p>Indépendamment de ce que nous découvrons, nous comprenons et nous croyons sincèrement que chacun a fait du mieux qu&rsquo;il pouvait, compte tenu de ce qu&rsquo;il savait à l&rsquo;époque, de ses compétences et de ses prérogatives, des ressources disponibles et de la situation du moment. <a title="http://www.fabrice-aimetti.fr/dotclear/public/traductions/pagesretros/retroPrimeDirective-fr.html" href="http://www.fabrice-aimetti.fr/dotclear/public/traductions/pagesretros/retroPrimeDirective-fr.html">http://www.fabrice-aimetti.fr/dotclear/public/traductions/pagesretros/retroPrimeDirective-fr.html</a></p>
</blockquote>
<p>Cette formule me paraissait au début un rituel un peu vide de sens, qui n’aurait peut-être de sens que pour des Anglo-Saxons friands de telles formules creuses, et qui ne marcherait pas vraiment avec des Français.</p>
<p>Que pensez-vous de cette formule ? Est-ce que vous l’utilisez ? Uniquement avec des équipes novices ou bien aussi des confirmées ? Est-ce qu’elle fonctionne en France ?</p>
<p>J’ai récemment eu le plaisir de découvrir un billet de Martin Fowler sur ce sujet, et il met précisément le doigt sur ce qui me dérangeait au début avec cette formule : </p>
<blockquote><p>This kind of advice generates in me a feeling of deep revulsion. Immediately it brings to mind images of motivational posters, school prayers, and two-minutes hate. Empty rituals, designed to quench curiosity and innovation, presided over by those whose minds are too empty to share my distaste.</p>
</blockquote>
<p>En gros il relie cette formule aux divers rituels conçus pour étouffer la curiosité et l’innovation ! </p>
<p>Mais il poursuit son billet en reconnaissant que ce type de formule peut avoir de réels bénéfices, d’autant plus qu&rsquo;un mécanisme psychologique appelé “amorçage” (<em>priming</em>) est mis en jeu – et que ce mécanisme a une puissance assez effrayante sur nos cerveaux. </p>
<p>Donc il ne faut pas se priver de l’utilisation positive et puissante d’un tel rituel.</p>
<p>Après avoir présenté cette directive première, je fais aussi souvent référence à <a href="http://fr.wikipedia.org/wiki/William_Edwards_Deming" target="_blank">Deming</a>, qui avait constaté que <strong>la majorité des problèmes organisationnels viennent des systèmes</strong> (l’ensemble des procédures, la structure hiérarchique, la culture, les relations entre entités de l’organisation) <strong>et non pas des gens qui travaillent dans le système</strong>.</p>
<p>Pour moi c’est l’essence de l’activité de rétrospective: trouver comment modifier le système dans notre zone d’influence pour améliorer notre situation. Et finalement la formule de Norm Kerth ci-dessus est une excellente introduction à cette recherche.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Des tableaux pour l&#8217;int&#233;gration d&#8217;un &#233;quipier dans une &#233;quipe Scrum</title>
		<link>https://blog.developpez.com/bruno-orsier/p11886/developpement-agile/equipe/des-tableaux-pour-lintgration-dun-quipier-dans-une-quipe-scrum</link>
		<comments>https://blog.developpez.com/bruno-orsier/p11886/developpement-agile/equipe/des-tableaux-pour-lintgration-dun-quipier-dans-une-quipe-scrum#comments</comments>
		<pubDate>Wed, 03 Apr 2013 08:23:36 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[équipe]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/bruno-orsier/?p=84</guid>
		<description><![CDATA[Il est assez simple d’intégrer un nouvel équipier dans une équipe Scrum existante. En effet le travail est bien structuré (définition de DONE, backlog déjà défini, rôles précis, réunions bien précises, …). En plus d’un outil de gestion de backlog électronique nous utilisons énormément des tableaux physiques comme radiateurs d’informations. Nous avons un tableau d’une part pour suivre le travail du sprint en cours, comme ci-dessous. Le nouvel arrivant dans l’équipe peut facilement comprendre les [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Il est assez simple d’intégrer un nouvel équipier dans une équipe Scrum existante. En effet le travail est bien structuré (définition de DONE, backlog déjà défini, rôles précis, réunions bien précises, …). En plus d’un outil de gestion de backlog électronique nous utilisons énormément des tableaux physiques comme radiateurs d’informations.</p>
<p>Nous avons un tableau d’une part pour suivre le travail du sprint en cours, comme ci-dessous. Le nouvel arrivant dans l’équipe peut facilement comprendre les diverses étapes à suivre pour un élément de backlog, car il voit les éléments bouger tous les matins lors de la réunion quotidienne. Le tableau permet aussi de capitaliser certaines expériences de l’équipe – par exemple nous avons récemment ajouté une colonne “PROFILING” pour nous imposer de rechercher systématiquement les fuites mémoires (une des causes de défauts critiques pour nos applications, que nous cherchons à éradiquer). Il y a alors peu de chances pour que le nouveau ne soit pas sensibilisé immédiatement au problème des fuites mémoires.</p>
<p><a href="http://blog.developpez.com/bruno-orsier/files/2013/04/image.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" title="image" border="0" alt="image" src="http://blog.developpez.com/bruno-orsier/files/2013/04/image_thumb.png" width="467" height="351" /></a></p>
<p>D’autre part, au dos du tableau ci-dessus, nous avons réparti le travail pour les sprints restants, ce qui donne une bonne visibilité pour les prochains mois.</p>
<p><a href="http://blog.developpez.com/bruno-orsier/files/2013/04/image1.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" title="image" border="0" alt="image" src="http://blog.developpez.com/bruno-orsier/files/2013/04/image_thumb1.png" width="475" height="357" /></a></p>
<p><strong>Nous venons d’introduire un nouveau type de tableau, spécialement étudié pour intégrer un nouvel arrivant</strong>. L’idée vient de <font color="#000000">George Dinwiddie</font> (voir <font style="font-weight: normal"><a href="http://blog.gdinwiddie.com/2013/03/27/adding-a-new-team-member/" target="_blank">Adding a new team member</a> sur son blog), </font> et nous l’essayons pour la première fois – cela semble une bonne alternative à notre ancienne habitude de désigner un mentor spécifique pour un nouveau équipier. Dans l’approche de George Dinwiddie, c’est plutôt l’équipe tout entière qui va jouer le rôle de mentor, tandis que le nouveau va pouvoir contrôler son rythme de progression. </p>
<p>Le principe consiste à faire une réunion d’équipe pour identifier toutes les tâches et activités nécessaires à l’intégration. On créée une fiche par tâche ou activité, et les volontaires pour y participer indiquent leurs initiales. Toutes les fiches sont ensuite reportées sur un tableau comme celui que nous avons fait hier :</p>
<p><a href="http://blog.developpez.com/bruno-orsier/files/2013/04/image2.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" title="image" border="0" alt="image" src="http://blog.developpez.com/bruno-orsier/files/2013/04/image_thumb2.png" width="244" height="325" /></a></p>
<p>Par exemple, la fiche encadrée en rouge correspond à la nécessaire activité de formation au profilage mémoire qui permet de détecter les fuites mémoires mentionnées plus haut.</p>
<p>Les fiches sont organisées en fonction de leur dépendances et de leur progression logique. Nous ajouterons de nouvelles fiches si nous découvrons des activités de formation nécessaire en cours de route.</p>
<p>Le nouvel arrivant est alors responsable de passer les fiches de TODO à IN PROGRESS puis DONE en fonction de sa progression, et de solliciter les volontaires. </p>
<p>Simple, non ? En conséquence, l’équipier se sent bien accueilli car il constate la bonne volonté de l’équipe pour l’intégrer.</p>
<p>Et vous, quelles sont vos idées pour intégrer de nouvelles personnes dans une équipe Scrum ?</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Quelques r&#233;f&#233;rences pour apprendre le BDD</title>
		<link>https://blog.developpez.com/bruno-orsier/p11819/bdd/quelques-rfrences-pour-apprendre-le-bdd</link>
		<comments>https://blog.developpez.com/bruno-orsier/p11819/bdd/quelques-rfrences-pour-apprendre-le-bdd#comments</comments>
		<pubDate>Wed, 06 Mar 2013 21:42:39 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[BDD]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/bruno-orsier/?p=63</guid>
		<description><![CDATA[On m’a demandé récemment quelques références sur le sujet du BDD – c’est un thème que j’ai déjà abordé dans des billets qui datent un peu. Voici quelques points de départ qui eux sont d’actualité : En fonction du langage de programmation: en .NET, voir Specflow : www.specflow.org en Java, voir jBehave : http://jbehave.org/ en Ruby, voir Cucumber : http://cukes.info/ Il existe aussi des outils moins dépendants d’un langage, comme GreenPepper : http://www.greenpeppersoftware.com/confluence/display/GPW/Home/, Fitnesse : [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>On m’a demandé récemment quelques références sur le sujet du BDD – c’est un thème que j’ai déjà abordé dans des billets qui datent un peu. Voici quelques points de départ qui eux sont d’actualité :</p>
<p>En fonction du langage de programmation:</p>
<ul>
<li>en .NET, voir Specflow : <a href="https://mail.persistent.co.in/OWA/redir.aspx?C=635bb828da144e5e8a6627df2767ee96&amp;URL=http%3a%2f%2fwww.specflow.org">www.specflow.org</a></li>
<li>en Java, voir jBehave : <a href="https://mail.persistent.co.in/OWA/redir.aspx?C=635bb828da144e5e8a6627df2767ee96&amp;URL=http%3a%2f%2fjbehave.org%2f">http://jbehave.org/</a></li>
<li>en Ruby, voir Cucumber : <a href="http://cukes.info/">http://cukes.info/</a></li>
</ul>
<p>Il existe aussi des outils moins dépendants d’un langage, comme</p>
<ul>
<li>GreenPepper : <a href="http://www.greenpeppersoftware.com/confluence/display/GPW/Home/">http://www.greenpeppersoftware.com/confluence/display/GPW/Home/</a>, </li>
<li>Fitnesse : <a href="http://fitnesse.org/">http://fitnesse.org/</a>&#160;</li>
</ul>
<p>Pour prendre du recul par rapport aux outils, il faut étudier les travaux de Dan North, qui a introduit la notion de BDD vers 2003 je crois, et qui a écrit cette <a href="http://dannorth.net/introducing-bdd/" target="_blank">introduction au BDD</a> (en anglais, mais <a href="http://philippe.poumaroux.free.fr/index.php?post/2012/02/06/Introduction-au-Behaviour-Driven-Developement" target="_blank">traduite en français</a> par <em>Philippe Poumaroux</em>). On peut voir le BDD comme la spécification du comportement attendu d’un logiciel.</p>
<p>Il est aussi très utile d’étudier le concept de <strong>Spécification par l’exemple</strong>, concept inventé par Gojko Adzic. On peut trouver une introduction ici : <a href="http://specificationbyexample.com/key_ideas.html">http://specificationbyexample.com/key_ideas.html</a>, mais Gojko a aussi écrit un livre complet sur la question, <a href="http://www.amazon.fr/Specification-Example-Gojko-Adzic/dp/1617290084" target="_blank">Specification By Example</a>. </p>
<p>Ces deux concepts, spécification par l’exemple et spécification du comportement attendu, permettent de comprendre l’utilité des outils mentionnés plus haut.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Le caddying, comment ça marche ?</title>
		<link>https://blog.developpez.com/bruno-orsier/p8806/developpement-agile/le_caddying_comment_ca_marche_1</link>
		<comments>https://blog.developpez.com/bruno-orsier/p8806/developpement-agile/le_caddying_comment_ca_marche_1#comments</comments>
		<pubDate>Tue, 20 Apr 2010 10:27:32 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[Développement agile]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pourquoi le caddying Le caddying est une nouvelle étape dans notre mise en place de méthodes de développement agiles (SCRUM principalement), et c&#8217;est une tentative de privilégier &#171;&#160;les individus et leurs interactions plutôt que les processus et les outils&#160;&#187; (cf. le manifeste agile). Notre besoin était de trouver un moyen simple d&#8217;alimenter une dynamique d&#8217;amélioration continue. Au début nous nous sommes beaucoup appuyés sur une démarche très orientée processus. Toutefois il me semble que sans [&#8230;]]]></description>
				<content:encoded><![CDATA[<h1>Pourquoi le caddying</h1>
<p>Le caddying est une nouvelle étape dans notre mise en place de méthodes de développement agiles (SCRUM principalement), et c&rsquo;est une tentative de privilégier &laquo;&nbsp;les individus et leurs interactions plutôt que les processus et les outils&nbsp;&raquo; (cf. le <a href="http://agilemanifesto.org/">manifeste agile</a>). Notre besoin était de trouver un moyen simple d&rsquo;alimenter une dynamique d&rsquo;amélioration continue. Au début nous nous sommes beaucoup appuyés sur une démarche très orientée processus. Toutefois il me semble que sans une réelle dynamique d&rsquo;amélioration continue, une pratique &laquo;&nbsp;orientée processus&nbsp;&raquo; de SCRUM comporte un fort risque de délivrer régulièrement et de manière prédictible des produits médiocres. La qualité des produits et la performance des équipes ne viennent pas automatiquement ni magiquement en suivant plus ou moins à la lettre un processus. Au mieux, la qualité augmente un peu parce que vous accordez plus d&rsquo;attention aux tests, tandis que certains gaspillages sont supprimés étant donné que SCRUM est naturellement <em>lean</em>, mais vous atteignez vite un plateau.</p>
<p>L&rsquo;idée du caddying est venue de discussions sur ces thèmes avec François Beauregard qui nous avait expliqué ce concept de caddying mis en place dans <a href="http://www.pyxis-tech.com/fr/">Pyxis</a>. Nous avons ensuite adapté la démarche à notre contexte, essentiellement en donnant un axe assez technique au caddying pour l&rsquo;instant.</p>
<p>Notre caddying a certains points communs avec le mentorat, terme qui selon <a href="http://fr.wikipedia.org/wiki/Mentorat">Wikipedia</a> &laquo;&nbsp;désigne une relation interpersonnelle de soutien, d&rsquo;échanges et d&rsquo;apprentissage, dans laquelle une personne d&rsquo;expérience, le <a href="http://fr.wikipedia.org/wiki/Mentor">mentor</a>, investit sa sagesse acquise et son expertise afin de favoriser le développement d&rsquo;une autre personne, le mentoré, qui a des compétences à acquérir et des objectifs professionnels à atteindre&nbsp;&raquo;. Mais il nous paraît plus sain d&rsquo;éviter des termes chargés de sens vagues ou d&rsquo;a priori comme coach ou mentor, qui requièrent de laborieuses clarifications (voir <a href="http://www.noop.nl/2010/04/managing-vs-coaching-vs-mentoring.html">Managing vs. Coaching vs. Mentoring</a>). </p>
<p>Aussi nous parlons simplement de caddy et de joueur (en référence à ces deux &laquo;&nbsp;rôles&nbsp;&raquo; dans le golf). <em>Attention, le caddy n&rsquo;est pas un simple porteur de clubs, c&rsquo;est un joueur expérimenté qui connaît bien le parcours, et qui est indispensable même aux meilleurs joueurs mondiaux.</em></p>
<p>Ce billet décrit concrètement comment se passe le caddying dans notre contexte (édition de logiciels scientifiques), en présentant les thèmes sur lesquels nous travaillons, la mise en place concrète, les avantages et inconvénients identifiés après un peu plus de six mois de pratique.</p>
<p><span id="more-31"></span></p>
<h1>Nos thèmes</h1>
<p>Les thèmes &laquo;&nbsp;émergent&nbsp;&raquo; en fonction de plusieurs facteurs :</p>
<ul>
<li>besoins stratégiques de l&rsquo;entreprise. Par exemple nous souhaitons améliorer la performance de nos applications scientifiques, et pour cela il serait utile d&rsquo;avoir des développeurs mieux formés sur le développement multi-thread. </li>
<li>envie d&rsquo;un caddy de partager ses connaissances (par exemple ergonomie, ou encore GTD) ou d&rsquo;approfondir un sujet qui le passionne (par exemple la programmation fonctionnelle) </li>
<li>besoin de formation identifiés par certains joueurs (par exemple augmenter leur connaissances métier, ou mieux maîtriser leur ordinateur) </li>
</ul>
<p>Nous avons actuellement les thèmes suivants :</p>
<ul>
<li><strong>bureautique</strong> : cela permet à un joueur qui n&rsquo;est pas informaticien de bénéficier des connaissances d&rsquo;un développeur, pour mieux comprendre des aspects de l&rsquo;informatique qui l&rsquo;intéressent. Par nature le contenu est très varié, et complètement déterminé par les questions du joueur. Par exemple la dernière séance de 2H a été consacrée à maintenir le PC bien à jour avec <a href="http://secunia.com/vulnerability_scanning/personal">Secunia Personal Software Inspector (PSI)</a>, sauvegarder des partitions avec <a href="http://www.acronis.com/homecomputing/products/trueimage/">Acronis True Image</a> ou <a href="http://www.runtime.org/driveimage-xml.htm">DriveImage XML</a>, et partitionner un disque avec <a href="http://gparted.sourceforge.net/">GParted</a> (et pour cela il a fallu explorer la notion de partition). </li>
<li><strong>ergonomie</strong> : ici les joueurs apprennent des notions théoriques, puis passent nos logiciels au crible de critères d&rsquo;ergonomie et réalisent des tests d&rsquo;utilisabilité. Cela a des conséquences assez rapidement puisque leurs conclusions vont être implémentées dans les prochaines versions. D&rsquo;autre part notre processus de développement sera modifié pour prendre en compte leur expérience et travaux, et cela va contribuer à augmenter la maturité de nos équipes sur la question, et augmenter la satisfaction des clients. </li>
<li><strong>tests agiles</strong> : un joueur étudie à son rythme le livre <a href="http://lisacrispin.com/wordpress/agile-testing-book-is-now-out/">Agile Testing</a>, a identifié les blogs des principaux gourous du test agile, et publie régulièrement des billets internes sur les aspects pertinents par rapport à nos pratiques (les quadrants du test agile, les tests exploratoires, les spécifications exécutables). Cette activité qui n&rsquo;existait pas du tout auparavant contribue à augmenter notre maturité sur le test en général. Un autre joueur travaille sur la compréhension et l&rsquo;implémentation d&rsquo;un &laquo;&nbsp;<a href="http://en.wikipedia.org/wiki/Presenter_First">presenter</a>&nbsp;&raquo; dans une application réaliste, afin de nous faire progresser sur la question difficile des tests d&rsquo;interfaces graphiques. </li>
<li><strong>programmation multi-thread</strong> : avec un caddy expérimenté, plusieurs joueurs travaillent en randori sur divers problèmes, comparent des solutions (notamment leurs performances &#8211; ça tombe bien, c&rsquo;est un de nos thèmes stratégiques), et approfondissent de nombreuses notions (verrous, opérations atomiques, framework QtConcurrent, MapReduce). Pour l&rsquo;instant tout cela est en C++, pour des développeurs C++, mais il serait intéressant plus tard d&rsquo;impliquer d&rsquo;autres développeurs qui eux travaillent en C#. </li>
<li><strong>programmation fonctionnelle</strong> (F#, Erlang)  :  Ici joueur et caddy apprennent ensemble les concepts de la programmation fonctionnelle. Ce thème est intéressant par ses applications à moyen terme : maîtriser la programmation fonctionnelle est certainement un bon moyen d&rsquo;apprendre à écrire du code plus propre et plus facilement parallélisable (ça tombe bien, cela peut améliorer les performances). De plus, la programmation fonctionnelle s&rsquo;adapte bien aux algorithmes &laquo;&nbsp;scientifiques&nbsp;&raquo;. </li>
<li><strong>GTD</strong> :  avec un caddy qui a <a href="http://luc-jeanniard.blogspot.com/2009/12/caddie-coach-gtd-getting-things-done-v2.html">appris tout seul la méthode</a>, les joueurs apprennent à mieux s&rsquo;organiser par la méthode <a href="http://fr.wikipedia.org/wiki/Getting_Things_Done">Getting Things Done</a>, de David Allen. Ici l&rsquo;organisation est particulière, avec une longue séance initiale pour mettre en place la méthode (des m3 de papier inutile sont généralement éliminés à ce stade), et de courtes séances régulières pour ancrer la méthode. </li>
<li><strong>connaissances métier</strong> : plusieurs développeurs ont exprimé le besoin d&rsquo;être mieux formés sur l&rsquo;utilisation qui est faite des logiciels qu&rsquo;ils développement, et donc ils travaillent régulièrement avec une de nos spécialistes &laquo;&nbsp;métier&nbsp;&raquo;. Ils ont choisi avec leur caddy de devenir capables de faire passer tout seuls les tests d&rsquo;acceptance de leur logiciels sur nos instruments (c&rsquo;est une bonne idée car ces tests représentent un goulot d&rsquo;étranglement dans la livraison de logiciels par manque de personnes capables de les faire passer). </li>
<li><strong>agilité</strong> : Ici un joueur Scrummaster échange régulièrement avec son caddy sur la manière dont il pratique Scrum, les difficultés qu&rsquo;il rencontre, les billets ou articles récents. </li>
<li><strong>lean </strong>: ce thème a permis notamment d&rsquo;aider nos &laquo;&nbsp;product owners&nbsp;&raquo; à mieux gérer leur backlog et à mieux écrire leurs histoires utilisateur. Il a permis également de réorganiser notre laboratoire avec la <a href="http://fr.wikipedia.org/wiki/5S">méthode des 5S</a>. </li>
<li><strong>lecture rapide</strong> : ici un lecteur moyen cherche à doubler sa vitesse de lecture, grâce à deux séances de travail par semaine, basées sur l&rsquo;étude de livres comme <a href="http://www.amazon.fr/Méthode-Lecture-rapide-François-Richaudeau/dp/272562343X">Méthode de Lecture rapide</a> et <a href="http://www.amazon.com/Days-Faster-Reading-Abby-Marks-Beale/dp/0446676675">10 Days to Faster Reading</a>. </li>
</ul>
<p>Nous avons également des caddies volontaires pour un thème &laquo;&nbsp;troubleshooting&nbsp;&raquo; et pour un thème &laquo;&nbsp;communication et facilitation&nbsp;&raquo; mais aucun joueur ne s&rsquo;est proposé pour l&rsquo;instant. Cela illustre le fait que le caddying ne marche que quand il y a rencontre entre un besoin et une offre de services !</p>
<h1>Comment ça marche en pratique</h1>
<h2>Fonctionnement</h2>
<p>Il n&rsquo;y a pas de processus très formalisé pour décider des thèmes &#8211; en pratique il suffit que deux personnes se désignent comme caddy et joueur pour que le travail sur un nouveau thème puisse démarrer ! La principale contrainte est de rester dans des limites de temps raisonnable (20% de son temps par semaine pour un caddy, et de l&rsquo;ordre de 2H par semaine pour un joueur).</p>
<p>Le temps ? C&rsquo;est le mot-clé ! Souvent on me demande comment cette initiative (et d&rsquo;autres, comme participer régulièrement aux coding dojos du CARA, ou encore notre journée &laquo;&nbsp;labo&nbsp;&raquo; régulière) est possible, comment on nous laisse faire tout cela au lieu de nous faire travailler à fond sur les projets en cours. Eh bien pour l&rsquo;instant personne n&rsquo;a démontré que ces initiatives ralentissaient la sortie d&rsquo;un logiciel. J&rsquo;ai une hypothèse là-dessus : comme les cartes de valeur (value stream mapping) dans le cas du développement logiciel montrent des ratios d&rsquo;efficacité <a href="http://www.agilex.fr/2009/09/stream-value-mapping/">assez faibles</a>, il est possible que ces initiatives consomment bien plus de temps dans les périodes d&rsquo;inefficacité que dans les périodes d&rsquo;efficacité. En quelque sorte, nous utiliserions le temps autrefois gaspillé pour nous améliorer ! Mais c&rsquo;est une hypothèse qui reste à démontrer.</p>
<p>Le fonctionnement est très flexible, et laissé à l&rsquo;appréciation du caddy et de ses joueurs. L&rsquo;idée de départ était surtout une relation en tête-à-tête, mais en pratique plusieurs caddies travaillent avec un groupe de joueurs en même temps, surtout quand les caddies sont très demandés. Certains joueurs indiquent tout de même qu&rsquo;ils auraient préféré un accompagnement individuel (afin de ne pas perdre du temps quand certains contenus ne les intéressent pas), mais nous n&rsquo;avons pas toujours assez de temps de caddy (certains caddies ont d&rsquo;autres rôles comme ScrumMaster, ou encore travaillent à temps partiel).</p>
<p>Quand il n&rsquo;y a qu&rsquo;un seul joueur, nous avons comme principe de laisser le joueur poser les réunions avec son caddy. Ainsi le joueur est complètement responsable du planning, et peut déterminer le rythme qui lui convient &#8211; charge au caddy de s&rsquo;adapter. Quand le joueur tarde à poser les réunions, c&rsquo;est peut-être signe que la relation s&rsquo;essouffle et qu&rsquo;il est peut-être temps de conclure.</p>
<p>La durée de l&rsquo;accompagnement est donc libre également, et va de quelques semaines à plusieurs mois, en fonction de la densité du contenu exploré, et de l&rsquo;énergie que caddy et joueurs veulent consacrer au thème.</p>
<p>Ce travail est assez exigeant pour le caddy qui doit souvent approfondir ses propres connaissances, et parfois préparer du matériel pédagogique. J&rsquo;espère donc qu&rsquo;il y aura plusieurs générations successives de joueurs pour un caddy donné, afin de plus rentabiliser le temps investi par le caddy. Cela paraît certain pour certains de nos thèmes (GTD, connaissances métier), pour d&rsquo;autres thèmes c&rsquo;est moins évident. </p>
<p>Nous avons également identifié un rôle de &laquo;&nbsp;meta-caddy&nbsp;&raquo;, que j&rsquo;ai décrit dans cet <a href="http://blog.developpez.com/bruno-orsier/p8207/developpement-agile/le-meta-caddy/">autre billet</a>. Mais ce n&rsquo;est pas un rôle très directif actuellement, car il nous semble plus important de laisser vivre le système et d&rsquo;expérimenter, plutôt que de chercher à le contrôler.</p>
<h2>Evaluation</h2>
<p>Nous demandons aux joueurs de s&rsquo;auto-évaluer en début et en fin de parcours (voire aussi en cours de route si c&rsquo;est utile), selon différents axes qu&rsquo;ils identifient avec leur caddy. Ci-dessous je montre certaines de ces auto-évaluations.</p>
<p>Voici une première <a href="http://luc-jeanniard.blogspot.com/2009/12/caddie-coach-gtd-getting-things-done-v2.html">illustration dans le thème GTD</a> (c&rsquo;est le caddy qui s&rsquo;est lui même auto-évalué pour identifier les axes intéressants pour ses joueurs) :</p>
<p><a href="http://luc-jeanniard.blogspot.com/2009/12/caddie-coach-gtd-getting-things-done-v2.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/c75113e5f5ac_E9A8/image.png" width="619" height="484" /></a> </p>
<p>Voici l&rsquo;auto-évaluation d&rsquo;un joueur dans le thème bureautique :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/c75113e5f5ac_E9A8/image_3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/c75113e5f5ac_E9A8/image_thumb.png" width="504" height="229" /></a> </p>
<p>et pour un autre joueur dans le thème ergonomie :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/c75113e5f5ac_E9A8/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/c75113e5f5ac_E9A8/image_thumb_3.png" width="551" height="241" /></a> </p>
<p>Dans tous les cas il y a de nettes progressions sur certains axes, et d&rsquo;autres axes avec peu de progrès, généralement parce qu&rsquo;ils n&rsquo;ont pas été suffisamment explorés pendant le caddying, souvent par manque de temps. Ces auto-évaluations permettent au joueur et au caddy de corriger le tir si besoin.</p>
<h1>Avantages</h1>
<p>Par rapport à une formation classique, cette formule présente l&rsquo;avantage d&rsquo;être &laquo;&nbsp;à la carte&nbsp;&raquo;, sous forme de cours quasiment particuliers très adaptés à nos besoins, et peu couteux. Quand nous avons organisé des formations auparavant, elles sont souvent été jugées trop théoriques, avec trop de participants, ou pas assez reliées à notre travail.</p>
<p>Dans le même ordre d&rsquo;idée, l&rsquo;avantage du caddying est que tout ce que l&rsquo;on apprend est immédiatement utilisable, et qu&rsquo;il est possible d&rsquo;avoir un suivi qui contribue à ancrer les nouvelles connaissances. En effet, même quand vous avez terminé votre travail avec un caddy, ce dernier reste disponible pour assurer un suivi à une fréquence différente, ou encore pour vous aider ponctuellement, même dans six mois.</p>
<p>Le caddying évite également les relativement longues interruptions que peuvent constituer les formations classiques, puisque le joueur ou le caddy ne sont indisponibles pour leurs équipes que peu de temps chaque semaine.</p>
<p>Le caddying ouvre aussi un espace qui n&rsquo;existait pas auparavant pour expérimenter, faire des erreurs, réaliser des prototypes. </p>
<p>En plus de cet espace, le caddying permet d&rsquo;acquérir un certain rythme de travail ou d&rsquo;étude. En effet il est facile de s&rsquo;intéresser à un nouveau sujet, mais difficile de s&rsquo;imposer une discipline pour l&rsquo;étudier suffisamment longtemps. Justement grâce aux réunions régulières avec une autre personne, le caddying contribue à plus de discipline. Cette discipline peut même être une raison suffisante pour démarrer un travail de caddying avec une autre personne, qui n&rsquo;a pas nécessairement besoin d&rsquo;être beaucoup plus experte que vous dans le domaine choisi &#8211; sa contribution sera surtout d&rsquo;aider à maintenir la régularité de travail sur le sujet.</p>
<p>C&rsquo;est aussi un nouvel espace pour partager des connaissances, réduire les effets silos entre projets ou équipes, mieux connaître ses collègues, faire de la veille technologique. Et parfois il encourage à tout simplement à aider ses collègues : ainsi des formes de &laquo;&nbsp;micro-caddying&nbsp;&raquo; apparaissent maintenant spontanément. Quand une personne demande à un collègue de l&rsquo;aider une ou deux heures, le terme de caddying est maintenant employé !</p>
<p>Enfin le caddying offre une possibilité de meilleure reconnaissance à ceux qui sont intéressés par une carrière technique, à condition qu&rsquo;ils puissent faire preuve de suffisamment de pédagogie.</p>
<h1>Inconvénients, difficultés</h1>
<p>Le principal inconvénient est que le caddying constitue une nouvelle source possible d&rsquo;interruption pour une équipe, qui peut se trouver en attente de quelque chose d&rsquo;un joueur ou d&rsquo;un caddy. Même s&rsquo;il s&rsquo;agit d&rsquo;interruptions courtes comme je le signalais plus haut, ce sont des interruptions fréquentes, qui s&rsquo;ajoutent à d&rsquo;autres sources : réunions, RTT, temps partiel. Quand cela est possible, il faut essayer d&rsquo;organiser les rencontres joueur-caddy en dehors des plages horaires où toute l&rsquo;équipe travaille ensemble ; par exemple le créneau 8h-9h est assez adapté dans certains cas.</p>
<p>Un autre inconvénient est le risque de fonctionner en &laquo;&nbsp;circuit fermé&nbsp;&raquo; : d&rsquo;une part il n&rsquo;y a pas beaucoup d&rsquo;apport ou d&rsquo;échange extérieur, comme cela peut être le cas quand vous suivez une formation inter-entreprise ; d&rsquo;autre part, les joueurs les plus convaincus sont souvent caddies dans d&rsquo;autres thèmes, ce qui peut finir par limiter l&rsquo;arrivée de nouveaux joueurs.</p>
<p>En fait plutôt que de réels inconvénients,  le caddying présente surtout certaines difficultés ou challenges. Par exemple :</p>
<ul>
<li>il est difficile d&rsquo;adapter les besoins des joueurs et les offres de services. Nous ne sommes pas forcément suffisamment compétents ou disponibles sur tous les thèmes souhaités. Ou encore les joueurs potentiels ne sont pas forcément intéressés par tous les services que des caddies aimeraient proposer. </li>
<li>les caddies potentiels ne sont pas forcément très bons en communication ou en pédagogie. Ainsi ils peuvent avoir du mal à faire une bonne &laquo;&nbsp;publicité&nbsp;&raquo; pour leurs thèmes, à simplement donner envie à des joueurs de s&rsquo;inscrire.</li>
<li>il est difficile de bien communiquer sur les services proposés par les caddies (en général il n&rsquo;y a pas de document type support de formation que l&rsquo;on peut consulter à l&rsquo;avance). Ainsi il peut être difficile de toucher des joueurs potentiels qui ne voient pas bien ce qui est proposé. Dans le même ordre d&rsquo;idée, certains joueurs n&rsquo;aiment pas trop le fait que le programme d&rsquo;étude ne soit pas fixé à l&rsquo;avance. </li>
<li>il faudra trouver le moyen de faire perdurer cette démarche de caddying, afin d&rsquo;éviter que le succès initial ne soit qu&rsquo;un feu de paille. Pour le moment nous sommes dans une phase exploratoire, et le caddying fonctionne sur la base du volontariat de tous et l&rsquo;exemple donné par les managers (plusieurs se sont inscrits comme joueurs). Est-ce que dans le futur le volontariat pur suffira, ou bien il faudra mettre au point des incitations ou des obligations ?  </li>
</ul>
<p>Enfin le caddying n&rsquo;a pas vocation à résoudre tous les problèmes. Il est très adapté pour permettre à 2 ou 3 personnes d&rsquo;acquérir de nouvelles compétences ou connaissances sur une durée de 3-6 mois au minimum, mais il n&rsquo;est sans doute pas le meilleur moyen pour des  groupes plus importants, ou pour &laquo;&nbsp;monter en compétences&nbsp;&raquo; très rapidement. C&rsquo;est pourquoi le caddying ne vise pas particulièrement à remplacer des formations classiques, à l&rsquo;extérieur de l&rsquo;entreprise.</p>
<h1>Conclusion</h1>
<p>J&rsquo;ai donc présenté notre implémentation concrète d&rsquo;un système particulier de mentorat, que nous appelons caddying. De tels systèmes ne sont pas nouveaux, car de nombreuses entreprises en ont déjà mis en place. Toutefois les systèmes existants semblent souvent viser uniquement les managers ou leaders, afin de faciliter ou accélérer leur carrière. Ainsi il est possible que notre particularité soit d&rsquo;avoir mis en place quelque chose qui soit applicable à tous les employés, indépendamment de leur position hiérarchique. Dans ce cas ce serait une bonne application du manifeste agile que je citais en introduction !</p>
<p> </p>
<p><em>Merci aux caddies qui ont pris le temps de relire et corriger ce billet, ainsi qu&rsquo;à <a href="http://ouelcum.wordpress.com/">Laurent Tardif</a> pour un échange sur ce thème.</em></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compte-rendu XP Day Suisse 2010</title>
		<link>https://blog.developpez.com/bruno-orsier/p8781/developpement-agile/compte_rendu_xp_day_suisse_2010</link>
		<comments>https://blog.developpez.com/bruno-orsier/p8781/developpement-agile/compte_rendu_xp_day_suisse_2010#comments</comments>
		<pubDate>Thu, 01 Apr 2010 15:47:49 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[Développement agile]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Ce lundi 29 mars j&#8217;ai eu le plaisir d&#8217;assister à la deuxième édition de la conférence XP Day Suisse, qui se tenait à Genève, tout comme l&#8217;année dernière (voir le compte-rendu de Pierre Caboche). Cette conférence bénéficie du soutien de plusieurs sponsors, dont developpez.com (merci pour l&#8217;invitation gratuite dont j&#8217;ai profité), et d&#8217;une équipe d&#8217;organisateurs dynamiques et passionnés. J&#8217;ai d&#8217;ailleurs trouvé excellente toute l&#8217;organisation, que ce soit le choix du lieu, le &#171;&#160;time-boxing&#160;&#187; des diverses [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Ce lundi 29 mars j&rsquo;ai eu le plaisir d&rsquo;assister à la deuxième édition de la <a href="http://www.xpday.ch/">conférence XP Day Suisse</a>, qui se tenait à Genève, tout comme l&rsquo;année dernière (voir le <a href="http://conception.developpez.com/reportage/agilite/xp-day-suisse-2009/">compte-rendu</a> de Pierre Caboche). Cette conférence bénéficie du soutien de plusieurs sponsors, dont <a href="http://www.developpez.com/">developpez.com</a> (merci pour l&rsquo;invitation gratuite dont j&rsquo;ai profité), et d&rsquo;une équipe d&rsquo;organisateurs dynamiques et passionnés. J&rsquo;ai d&rsquo;ailleurs trouvé excellente toute l&rsquo;organisation, que ce soit le choix du lieu, le &laquo;&nbsp;time-boxing&nbsp;&raquo; des diverses séances, les buffets, les zones de temps réservées aux échanges informels et au réseautage, le vote immédiat en fin de séances par gommettes de couleurs, le bon sac en toile de jute durable avec comme &laquo;&nbsp;goodies&nbsp;&raquo; juste le jeu de cartes de l&rsquo;<a href="http://agile-alchemist.com/">alchimiste agile</a>. Félicitations donc aux organisateurs qui nous ont permis de passer une excellente journée.</p>
<p>
<span id="more-30"></span></p>
<p><em>Un petit bémol toutefois sur le fait qu&rsquo;il faut absolument payer l&rsquo;inscription par un virement international (enfin, pour les Français) : un de mes collègues a eu la désagréable surprise de découvrir que sa banque prenait en commissions diverses la moitié du prix de l&rsquo;inscription ! Toujours pour les Français, sachez que nos amis Suisses sont moins fanas de la carte de crédit que nous, et qu&rsquo;il vaut mieux avoir de l&rsquo;argent suisse pour régler le parking situé sous le Geneva Business Center (environ 20 CHF pour la journée).</em></p>
<p>La conférence en chiffres :</p>
<ul>
<li>deux &laquo;&nbsp;pistes parallèles&nbsp;&raquo; dans un auditorium et une grande salle </li>
<li>douze sessions en tout, dont 3 en anglais </li>
<li>une douzaine d&rsquo;orateurs </li>
<li>environ 95 personnes présentes (100 places maximum étaient possibles). </li>
</ul>
<p>Comme a fallu faire des choix entre les sessions en parallèle, j&rsquo;ai assisté à 6 d&rsquo;entre elles, et parmi celles-ci, voici les 3 que j&rsquo;ai préférées :</p>
<ol>
<li>Apprenez les techniques de coaching avec le magicien d&rsquo;Oz, par <em>Portia Tung</em> et <em>Pascal Van Cauvenberghe</em>. </li>
<li>Test automatiques autour d&rsquo;un IHM, par <em>Didier Besset</em>. </li>
<li>Les 7 péchés capitaux du développeur, par <em>Freddy Mallet</em>. </li>
</ol>
<p>J&rsquo;étais très content de rencontrer enfin Portia et Pascal que je ne connaissais que virtuellement, ayant déjà utilisé avec succès certains de leurs jeux comme <a href="http://www.agilecoach.net/coach-tools/bottleneck-game/">I&rsquo;m not a Bottleneck! I&rsquo;m a Free Man!</a> J&rsquo;ai bien apprécié la découverte d&rsquo;un nouveau jeu, au contenu très utile puisqu&rsquo;il consiste à travailler sur l&rsquo;art de poser des questions et sur le co-coaching (ou peer coaching). Portia a tout d&rsquo;abord captivé la salle avec un petit conte :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb.png" width="184" height="244" /></a> </p>
<p>puis nous avons travaillé par groupes de 3 :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb_3.png" width="244" height="184" /></a> </p>
<p>(ils sont 4, mais ce sont les autres orateurs, ils ont du avoir une dérogation). Voici une photo de l&rsquo;ensemble de la salle :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb_4.png" width="244" height="184" /></a> </p>
<p>Vous pouvez télécharger tout le support du jeu (intitulé The Yellow Brick Road) <a href="http://www.agilefairytales.com/dist/The-Yellow-Brick-Road-2-0.zip">ici</a>. Et surtout, vous pouvez lire cette mise en application immédiate au retour de la conférence : <a href="http://luc-jeanniard.blogspot.com/2010/03/une-retrospective-pas-comme-les-autres.html">Une rétrospective pas comme les autres</a>. Ce retour d&rsquo;expérience tout frais montre bien l&rsquo;intérêt d&rsquo;une telle session dans une conférence, et plus généralement montre bien l&rsquo;intérêt de nous enseigner régulièrement de nouvelles compétences non techniques (nous, les gens qui ont une formation technique). J&rsquo;espère qu&rsquo;il y a aura une session sur ce thème dans notre conférence agile à Grenoble en 2010. A suivre !</p>
<p>Le retour d&rsquo;expérience sur les tests d&rsquo;IHM m&rsquo;a également beaucoup intéressé, et correspond bien à ce que j&rsquo;attends d&rsquo;une telle conférence : du concret, du factuel, des détails sur une application difficile mais compréhensible par tout le monde (contrôle du trafic aérien), du code, des idées à expérimenter au travail (la notion de primitives de tests), une piste théorique (les DSLs et les idées de Martin Fowler).</p>
<p> <a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb_5.png" width="184" height="244" /></a> (Didier Besset qui présentait le retour d&rsquo;expérience des tests IHM &#8211; et le nouveau T-shirt des organisateurs).</p>
<p>Enfin, Freddy Mallet nous a présenté <a href="http://sonar.codehaus.org/">SONAR</a>, un outil d&rsquo;<strong>inspection continue</strong></p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb_6.png" width="354" height="240" /></a> </p>
<p>qui permet de chasser les &laquo;&nbsp;7 péchés capitaux&nbsp;&raquo; du développeur : </p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb_7.png" width="354" height="227" /></a> </p>
<p>J&rsquo;aurais préféré voir une plus longue démonstration &laquo;&nbsp;live&nbsp;&raquo; de l&rsquo;outil, et moins de transparents, mais le sujet était intéressant et répond bien à mes préoccupations (j&rsquo;ai fait pas mal d&rsquo;expériences avec NDepend ces derniers temps). J&rsquo;ai également apprécié le témoignage de l&rsquo;orateur qui met en pratique ses idées, en continuant à toujours écrire des tests en premier pour le développement de son outil, et ce bien qu&rsquo;il subisse une forte pression (il a monté sa propre entreprise). Hélas Freddy m&rsquo;a confirmé que son outil ne permettait pas d&rsquo;analyser le code Delphi, et c&rsquo;est bien dommage pour nous qui avons une base de code importante dans ce langage.</p>
<p>J&rsquo;ai moins accroché avec les autres présentations que j&rsquo;ai suivies, car elles étaient plus éloignées de mes centres d&rsquo;intérêt. Les 3 sessions ci-dessus correspondaient mieux à ce que j&rsquo;attends de ce genre de conférences :</p>
<ul>
<li>sessions sur des outils non techniques (communication, coaching, développement de compétences) </li>
<li>sessions sur des outils techniques permettant de réduire la dette technique, améliorer la qualité du code. </li>
<li>retours d&rsquo;expériences détaillés sur des logiciels de taille réaliste. </li>
</ul>
<p>Voici les votes informels sur les sessions :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_8.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb_8.png" width="184" height="244" /></a> <a href="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/CompterenduXPDaySuisse2010_9B5E/image_thumb_9.png" width="184" height="244" /></a> </p>
<p>Vous devriez trouver prochainement les diverses présentations sur le site <a title="http://www.xpday.ch/" href="http://www.xpday.ch/">http://www.xpday.ch/</a>. Certaines sont déjà disponibles sur les sites de leurs auteurs, par exemple celle de Thierry Cros est ici : <a href="http://etreagile.thierrycros.net/home/index.php?post/2010/03/31/XpDay-Suisse-%3A-gouvernance-agile">XpDay Suisse : gouvernance agile</a>.</p>
<p>Dernière minute : le même Thierry vient de publier <a href="http://etreagile.thierrycros.net/home/index.php?post/2010/03/31/XpDay-Suisse-%3A-impressions-de-voyage">XpDay Suisse : impressions de voyage</a>.</p>
<p><em>Merci à Sylvain Labussiere pour l&rsquo;accès aux photos de la conférence, à Luc Jeanniard pour la relecture du billet et certaines photos.</em></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Des chiffres sur un de nos projets !</title>
		<link>https://blog.developpez.com/bruno-orsier/p8761/developpement-agile/des_chiffres_sur_un_de_nos_projets</link>
		<comments>https://blog.developpez.com/bruno-orsier/p8761/developpement-agile/des_chiffres_sur_un_de_nos_projets#comments</comments>
		<pubDate>Fri, 26 Mar 2010 14:25:28 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[Développement agile]]></category>
		<category><![CDATA[Tests unitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[J&#8217;aime bien lire des billets qui contiennent des informations factuelles sur de vrais projets, car cela permet de se situer par rapport à d&#8217;autres équipes et entreprises. Récemment j&#8217;ai vu notamment le billet Démarches de tests fonctionnels, de Christian Blavier, qui citait des chiffres intéressants (dans les commentaires du billet) : Voici quelques métriques que je viens de réunir dans différents contextes : - secteur media, sur un projet avec 3 développeurs qui dure depuis [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>J&rsquo;aime bien lire des billets qui contiennent des informations factuelles sur de vrais projets, car cela permet de se situer par rapport à d&rsquo;autres équipes et entreprises. Récemment j&rsquo;ai vu notamment le billet <a href="http://blog.octo.com/demarches-de-tests-fonctionnels/">Démarches de tests fonctionnels</a>, de Christian Blavier, qui citait des chiffres intéressants (dans les commentaires du billet) :</p>
<blockquote><p>Voici quelques métriques que je viens de réunir dans différents contextes :      <br />- secteur media, sur un projet avec 3 développeurs qui dure depuis 9 mois on a plus de 100 scénarios de test GreenPepper       <br />- secteur media, plusieurs équipes de 3 développeurs, ils ajoutaient en moyenne 5 tests fitnesse par itération de 2 semaines, soit plus d&rsquo;une centaine de tests par an       <br />- encore media, équipe de 7 développeurs avec 2 MOA à plein temps et qui font des tests GP depuis 18 mois : 8743 assertions (dans 122 pages) soit 153 assertions en moyenne par itération d&rsquo;une semaine       <br />- secteur assurance, une équipe de 2 développeurs + 1 MOA sur 6 mois pour tester une plateforme de services (20 web services) : 200 pages de tests Fitnesse et 5000 assertions. Un retour d&rsquo;exp complet est disponible ici : <a href="http://usi2008.universite-du-si.com/WebcastArchi.aspx">http://usi2008.universite-du-si.com/WebcastArchi.aspx</a> (session A10)       <br />- secteur open source <img alt=";-)" src="http://blog.octo.com/wp-includes/images/smilies/icon_wink.gif" /> , octopus microfinance et son harnais de test GP disponible ici : <a href="http://wiki.octopusnetwork.org/display/OPUS/Home">http://wiki.octopusnetwork.org/display/OPUS/Home</a></p>
</blockquote>
<p>Dans ces mêmes commentaires, Louis Pellerin ajoutait :</p>
<blockquote><p>De mon expérience avec GreenPepper pour le produit Talia que nous développons (un produit sans réelle interface utilisateur), nous avions une proportion d&rsquo;environ 80 spécifications exécutables (GreenPepper) pour plus de 200 tests unitaires et intégrés (mstest).</p>
</blockquote>
<p>Il y a aussi le billet <a href="http://pyxis-tech.com/blog/2010/02/23/pendant-ce-temps-la-a-boulogne/">Pendant ce temps-là, à Boulogne.</a>, d&rsquo;Emmanuel Gaillot, qui donne les chiffres suivants :</p>
<blockquote><p>L&rsquo;équipe compte actuellement 6 programmeurs (dont le responsable produit), 2 graphistes, 3 modérateurs et une poignée de <em>stake-holders</em>. Tout ce monde travaille dans un ancien atelier réhabilité à Boulogne, dans une même pièce. L&rsquo;application web est développée en <a href="http://fr.wikipedia.org/wiki/Test_Driven_Development">TDD</a> (à l&rsquo;exception des vues). Elle est actuellement couverte par 951 assertions, réparties sur 563 tests automatisés qui s&rsquo;exécutent en 35 secondes environ.</p>
<p>En 4 mois de boulot, nous avons consommé 150 pages de flipchart, 15 marqueurs, 100 fiches cartonnées, 2000 post-its de couleurs et tailles variées, 10 stylos feutre, 5 stylos bic, 2 bloc-notes, 50 feuilles A4, un playmobil et 300 viennoiseries.</p>
</blockquote>
<p>Si vous connaissez d&rsquo;autres billets ou articles du même style je suis preneur. </p>
<p>En attendant voici quelques informations du même type sur l&rsquo;un de nos projets : <strong>38 sprints</strong> de développement (durée 3 semaines), une équipe de développement de (en moyenne) 4 développeurs et 1 chimiste testeur/représentant des utilisateurs (plus 1 ScrumMaster, et 1 Product Owner).</p>
<p><span id="more-29"></span></p>
<p>L&rsquo;équipe a réalisé un total de <strong>837 tests</strong> :</p>
<ul>
<li>
<p>469 tests unitaires  </p>
</li>
<li>
<p>235 tests d&rsquo;intégration</p>
</li>
<li>
<p>132 tests fonctionnels (81 manuels et 51 automatiques)</p>
</li>
</ul>
<p>ce qui représente <strong>84% de tests (unitaires + intégration) et 16% de tests fonctionnels, </strong>mais encore <strong>90% de tests automatiques. </strong>Les tests fonctionnels manuels coûtent seulement <strong>2-3 heures</strong> de validation à l&rsquo;équipe, qui peut donc les jouer plusieurs fois par sprint si besoin.</p>
<p>Tous ces tests sont le résultat d&rsquo;un effort permanent de toute l&rsquo;équipe : TDD, automatisation des tests fonctionnels, &laquo;&nbsp;refactoring&nbsp;&raquo; permanent des tests fonctionnels.</p>
<p>Les tests unitaires et d&rsquo;intégration représentent environ 3000 assertions. Ils sont exécutés avec <a href="http://dunit.sourceforge.net/">DUnit</a>.</p>
<p>Voici un graphique montrant l&rsquo;évolution de la répartition des tests au fil du temps, sur les sprints les plus récents :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image_thumb.png" width="644" height="234" /></a> </p>
<p> </p>
<p>Voici la légende <a href="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image_3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image_thumb_3.png" width="121" height="179" /></a> et la répartition finale <a href="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image_thumb_4.png" width="304" height="179" /></a> (où j&rsquo;ai regroupé tests fonctionnels automatiques et manuels en une seule catégorie).</p>
<p>Cette répartition paraît assez satisfaisante : on a bien une <strong>pyramide</strong> de tests, il y plus de tests unitaires que de tests d&rsquo;intégration, et plus de tests d&rsquo;intégration que de tests fonctionnels. D&rsquo;autre part le nombre de tests fonctionnels manuels est resté sous contrôle, et c&rsquo;était l&rsquo;un des objectifs de l&rsquo;équipe de pouvoir exécuter tous leurs tests manuels en moins d&rsquo;une demi-journée ; le graphique montre d&rsquo;ailleurs qu&rsquo;en cours de route, certains tests manuels ont été remplacés par des tests automatiques, afin de ne pas se laisser déborder par les tests manuels.</p>
</p>
<p>C&rsquo;est un projet qui compte environ 180.000 lignes de code Delphi. C&rsquo;est un projet de taille moyenne pour nous, nous avons des projets beaucoup plus petits, et de plus rares projets 5 ou 6 fois plus gros.</p>
<p>Sur ce projet, comme sur un projet précédent d&rsquo;ailleurs, nous avions décidé de maîtriser la <a href="http://fr.wikipedia.org/wiki/Nombre_cyclomatique">complexité cyclomatique</a> (nous étions motivés par la constatation sur d&rsquo;anciens projets que des méthodes de complexité 50 voire 70 étaient de véritables nids à bugs critiques). Le graphique ci-dessous montre sur les sprints les plus récents l&rsquo;évolution du nombre total de méthodes (en bleu), et l&rsquo;évolution du nombre total de méthodes dont la complexité cyclomatique est supérieure à 7 (notre limite). <strong>Sur ce projet, nous avons donc programmé plus de 6200 méthodes de complexité inférieure à 7</strong>. Toutefois nous tolérons l&rsquo;existence de quelques dizaines de méthodes complexes car le bénéfice de baisser leur complexité ne nous semble pas assez important. Mais ces méthodes complexes ne représentent que 0.6% du nombre de total de méthodes ! </p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image_5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/243e33ee334c_EDB7/image_thumb_5.png" width="644" height="312" /></a> </p>
</p>
<p>La définition de la limite acceptable (7 dans notre cas) peut donner lieu à bien des débats, et vous trouverez fréquemment des recommandations comme 15 ou 25. Mais à mon avis, même une limite de 7 vous donne bien des opportunités de coder des bugs, car cela vous laisse libre de coder suffisamment de<em> if, while, for et conditions booléennes</em> tous ensemble. Donc pour moi il est important de s&rsquo;imposer une limite assez basse pour vraiment tirer parti de la réduction de la complexité.</p>
<p>Ces données illustrent deux axes sur lesquels nous nous sommes bien améliorés ces dernières années : maîtrise des tests, maîtrise de la complexité du code. Et qu&rsquo;en est-il de la satisfaction des clients sur ce projet ? Eh bien c&rsquo;est assez embarrassant, je ne sais pas encore quelle est la réponse ! En effet, en nous améliorant, nous avons essentiellement <strong>déplacé le goulet d&rsquo;étranglement</strong> dans d&rsquo;autres secteurs de l&rsquo;entreprise qui actuellement peinent à absorber notre production, et à livrer leur part du travail (pourtant ils ont vu passer plus de 30 livraisons qui fonctionnaient, ils n&rsquo;auraient pas dû être surpris, non ?). </p>
<p>Après tout, rien de très surprenant, c&rsquo;est en gros ce que prédit la théorie des contraintes.  Mais cela indique que dans de futurs projets, tout en continuant à nous améliorer sur d&rsquo;autres axes (comme <a href="http://blog.developpez.com/bruno-orsier/p8534/developpement-agile/pourquoi-sarsquo-interesser-au-bdd-behav/">travailler avec des exemples et pratiquer le BDD</a>), il va falloir travailler à introduire de l&rsquo;agilité dans tous les secteurs qui contribuent à la livraison d&rsquo;un produit chez des clients ! Nous atteignons peut-être les limites de ce que nous pouvons faire avec des améliorations locales. </p>
<p><em>Merci à mes collègues Sandrine et Jean pour leur aide dans la collecte des données.</em></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Du BDD vers le TDD, et vice-versa</title>
		<link>https://blog.developpez.com/bruno-orsier/p8594/tests-unitaires/du_bdd_vers_le_tdd_et_vice_versa</link>
		<comments>https://blog.developpez.com/bruno-orsier/p8594/tests-unitaires/du_bdd_vers_le_tdd_et_vice_versa#comments</comments>
		<pubDate>Thu, 04 Feb 2010 16:00:26 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[BDD]]></category>
		<category><![CDATA[Tests unitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Avant de passer au compte-rendu du dojo d&#8217;aujourd&#8217;hui, voici un nouvel éclairage sur l&#8217;articulation entre TDD et BDD, que j&#8217;emprunte à ce billet Behavior Driven Development with NBehave (trouvé grâce à cet autre billet Bien Tester une application Asp.net MVC sur le BDD par Guillaume Saint Etienne). Je pense que dans les dojos précédents nous avons bien compris et bien pratiqué le cycle RED/GREEN/REFACTOR du TDD : Nous voulons maintenant comprendre comment cela s&#8217;articule avec [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Avant de passer au compte-rendu du dojo d&rsquo;aujourd&rsquo;hui, voici un nouvel éclairage sur l&rsquo;articulation entre TDD et BDD, que j&rsquo;emprunte à ce billet <a href="http://pebblesteps.com/post/Behavior-Driven-Development-with-NBehave.aspx" target="_blank">Behavior Driven Development with NBehave</a> (trouvé grâce à cet autre billet <a href="http://www.dotnetguru2.org/gse/index.php/2010/01/21/bien-tester-une-application-asp-net-mvc" target="_blank">Bien Tester une application Asp.net MVC</a> sur le BDD par Guillaume Saint Etienne).</p>
<p>Je pense que dans les dojos précédents nous avons bien compris et bien pratiqué le cycle RED/GREEN/REFACTOR du TDD :</p>
<p><a href="http://pebblesteps.com/post/Behavior-Driven-Development-with-NBehave.aspx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/e64affed95e6_8F87/image4.png" width="248" height="46" /></a> </p>
<p>Nous voulons maintenant comprendre comment cela s&rsquo;articule avec le BDD (partant du principe que nous sommes convaincus que cela vaut le coup de <a href="http://blog.developpez.com/bruno-orsier/p8534/developpement-agile/pourquoi-sarsquo-interesser-au-bdd-behav/" target="_blank">s&rsquo;intéresser au BDD</a>). </p>
<p>Je trouve que le schéma ci-dessous de <a href="http://pebblesteps.com/post/Behavior-Driven-Development-with-NBehave.aspx" target="_blank">Behavior Driven Development with NBehave</a> illustre assez bien la manière de procéder, du BDD vers le TDD :</p>
<p><a href="http://pebblesteps.com/post/Behavior-Driven-Development-with-NBehave.aspx" target="_blank"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/e64affed95e6_8F87/image.png" width="456" height="106" /></a> </p>
<p><span id="more-47"></span></p>
<p>Voici comment je comprends ce schéma :</p>
<ul>
<li>On se laisse donc guider par une user story (ce qui évite un risque du TDD qui est de s&rsquo;égarer sur des questions peu pertinentes pour l&rsquo;utilisateur final, étant donné que l&rsquo;on travaille très près du code). </li>
<li>La première étape est d&rsquo;avoir des scénarios &laquo;&nbsp;Pending&nbsp;&raquo; &#8211; en Cucumber cela correspond au premier fragment de pont que Cucumber génère automatiquement. </li>
<li>En implémentant ces scénarios, on définit itérativement l&rsquo;API des classes métier. Pour cela on suit un cycle RED/GREEN/REFACTOR au niveau de l&rsquo;outil de BDD, et on ne cherche pas nécessairement à implémenter le comportement réel et final : on peut utiliser des comportements &laquo;&nbsp;codés en dur&nbsp;&raquo;, ou simplistes &#8211; c&rsquo;est ce qu&rsquo;illustrait le dojo précédent finalement. C&rsquo;est la partie &laquo;&nbsp;Stubbed Scenario&nbsp;&raquo; ci-dessus. </li>
<li>Une fois que l&rsquo;API est stable, on implémente le comportement réel, et pour cela on pratique le RED/GREEN/REFACTOR en changeant d&rsquo;outil : cette fois on fait du TDD avec un outil du type xUnit. </li>
<li>Et l&rsquo;on obtient un test d&rsquo;acceptance (sous forme de scénario exécutable) à la fin du processus. </li>
</ul>
<p>Aujourd&rsquo;hui dans le dojo nous avons travaillé essentiellement au niveau &laquo;&nbsp;Real Behavior&nbsp;&raquo;, l&rsquo;API de notre classe <em>CalibrationCurve</em> avait en effet été stabilisée grâce au travail de la dernière fois, nous n&rsquo;avons pas eu à la retoucher. Par contre nous avons complètement reprogrammé son comportement interne.</p>
<p>Pour commencer à programmer, nous nous sommes appuyés sur le test unitaire suivant :</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<pre id="codeSnippet" class="csharpcode"><span class="kwrd">class</span> LinearRegressionTest ? Test::Unit::TestCase<br /><br />  def setup<br />    @curve = CalibrationCurve.<span class="kwrd">new</span><br />    @curve.ajoute_points(0, 10)<br />    @curve.ajoute_points(10, 100)<br />  end<br /><br />  def test_calcul_slope<br />    assert_in_delta(0.111, @curve.calcule_slope, 0.001)<br />  end<br /><br />  def test_calcule_ordinate<br />    assert_in_delta(-1.111, @curve.calcule_ordinate, 0.001)<br />  end<br /><br />end<br /></pre>
<p></div>
<p><em><font size="2">(désolé, pour d&rsquo;obscures raisons le moteur de blog ne me laisse pas insérer le caractère &laquo;&nbsp;inférieur&nbsp;&raquo;, et j&rsquo;ai mis &#8804; à la place dans les morceaux de code qui en avaient besoin)</font></em></p>
<p>On peut noter que nous n&rsquo;avons pas inventé de nouvelles données du test, nous avons simplement utilisé les données déjà présentes dans le scénario qui échouait à la fin de la dernière séance :</p>
<p><img src="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_5.png" /> </p>
<p>Avec le recul, on peut se demander si ce test unitaire n&rsquo;est pas complètement redondant avec le scénario, et s&rsquo;il présente vraiment de l&rsquo;intérêt ! En effet nous exerçons l&rsquo;API de notre classe exactement comme dans le pont entre le scénario et la classe CalibrationCurve. </p>
<p>Par contre, en programmant les calculs nous avons identifié un cas limite (un seul point fourni par l&rsquo;utilisateur) et nous avons dû prendre une décision sur le comportement attendu. Voici un test unitaire qui couvre ce cas :</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<pre id="codeSnippet" class="csharpcode"><span class="kwrd">class</span> LinearRegressionTestLimite ? Test::Unit::TestCase<br /><br />  def setu&lt;<br />    @curve = CalibrationCurve.<span class="kwrd">new</span><br />    @curve.ajoute_points(0, 0)<br />  end<br /><br />  def test_slope_should_be_zero<br />    assert_equal(@curve.calcule_slope, 0)<br />  end<br /><br />  def test_ordinate_should_be_zero<br />      assert_equal(@curve.calcule_ordinate, 0)<br />    end<br /><br />end</pre>
<p></div>
<p>On peut alors se demander si cette information doit rester &laquo;&nbsp;cachée&nbsp;&raquo; dans un test unitaire, ou bien s&rsquo;il faut la faire remonter à l&rsquo;utilisateur, via un complément de scénario. La décision dépend surement d&rsquo;un dialogue avec les utilisateurs : est-ce que ce cas limite est pertinent pour eux ou non ? est-ce qu&rsquo;ils sont intéressés par spécifier le comportement attendu ?</p>
<p>En tout cas ce petit exemple nous indique déjà que le schéma ci-dessus <strong>Story ==> Acceptance Test</strong> n&rsquo;est pas si linéaire que cela : <strong><font color="#ff0000">en travaillant en TDD, nous pouvons découvrir des compléments de scénarios !</font></strong></p>
<p>Sur un point plus technique, nous avons également éprouvé le besoin d&rsquo;un test unitaire pour nous assurer du bon fonctionnement de notre extension du module Enumerable, auquel nous avons ajouté une méthode <em>mean</em> comme ci-dessous :</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<pre id="codeSnippet" class="csharpcode">module Enumerable<br />  def mean<br />    sum = self.inject(0.0) <span class="kwrd">do</span> |sum, xi|<br />      sum = sum + xi<br />    end<br />    <span class="kwrd">return</span> sum / self.size<br />  end  <br />end</pre>
<p></div>
<p>Comme nous ne connaissions pas suffisamment le principe du <em>inject</em>, le test unitaire nous a rassuré sur le bon fonctionnement de notre extension <em>mean</em> :</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<pre id="codeSnippet" class="csharpcode"><span class="kwrd">class</span> EnumerableTest ? Test::Unit::TestCase<br /><br />  def setup<br />    @array = [10, 100]<br />  end<br /><br />  def test_mean<br />    assert_equal(55, @array.mean)<br />  end  <br />end</pre>
<p></div>
<p>En ce qui me concerne, je garderais comme test unitaire uniquement ce dernier point très technique, et je me contenterais du scénario et d&rsquo;un complément de scénario pour le cas limite. Et vous, comment feriez-vous ?</p>
<p>Pour finir, le code de <em>CalibrationCurve</em> qui passe avec succès nos scénarios et tests unitaires :</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<pre id="codeSnippet" class="csharpcode"><span class="kwrd">class</span> CalibrationCurve<br /><br />  def initialize<br />    @x = []<br />    @y = []<br />  end<br /><br />  def compute<br />    xbar = @x.mean   <br />    ybar = @y.mean<br />    sx2= @x.map{|xi| (xi-xbar)**2}.mean<br /><br />    sum = 0<br />    @x.each_with_index <span class="kwrd">do</span> |xi, i|<br />      sum = sum + (@x[i]-xbar)*(@y[i]-ybar)<br />    end<br />    sxy = sum / @x.size<br /><br />    <span class="kwrd">if</span> sx2.abs != 0 then<br />      @a = sxy / sx2<br />      @b = ybar - @a*xbar<br />    <span class="kwrd">else</span><br />      @a = 0<br />      @b = 0<br />    end<br />  end<br /><br />  def ajoute_points (area,concentration)<br />    @x.push(concentration)<br />    @y.push(area)<br /><br />    compute<br />  end<br /><br />  def calcul_concentration(area)<br />    <span class="kwrd">return</span> (area - @b) / @a<br />  end<br /><br />  def calcule_slope<br />    <span class="kwrd">return</span> @a<br />  end<br /><br />  def calcule_ordinate<br />    <span class="kwrd">return</span> @b<br />  end<br /><br />end</pre>
<p></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BDD, l&#8217;exemple des courbes de calibration</title>
		<link>https://blog.developpez.com/bruno-orsier/p8590/developpement-agile/bdd_larsquo_exemple_des_courbes_de_calib</link>
		<comments>https://blog.developpez.com/bruno-orsier/p8590/developpement-agile/bdd_larsquo_exemple_des_courbes_de_calib#comments</comments>
		<pubDate>Wed, 03 Feb 2010 12:28:26 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[BDD]]></category>
		<category><![CDATA[Développement agile]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Dans le 18e coding dojo du Club Agile Rhône Alpes, ce 5 janvier dernier, j&#8217;avais pris un exemple réel issu de nos plans de tests, et basé sur les courbes de calibration, un concept très utilisé en chimie (et donc dans nos applications). Demain, dans la 20ème session, nous poursuivrons sur cet exemple. Comme pas mal de jours ont passé, ce billet est destiné à nous rafraîchir la mémoire sur la question, à moi le [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Dans le <a href="http://groups.google.fr/group/cara-dojo/browse_thread/thread/192b5623e0e5d1de" target="_blank">18e coding dojo</a> du <a href="http://clubagile.org/" target="_blank">Club Agile Rhône Alpes</a>, ce 5 janvier dernier, j&rsquo;avais pris un exemple réel issu de nos plans de tests, et basé sur les <a href="http://en.wikipedia.org/wiki/Calibration_curve" target="_blank">courbes de calibration</a>, un concept très utilisé en chimie (et donc dans nos applications). Demain, dans la <a href="http://groups.google.fr/group/cara-dojo/browse_thread/thread/ff615604b9efdc5d/655a8949709eb347?show_docid=655a8949709eb347" target="_blank">20ème session</a>, nous poursuivrons sur cet exemple. Comme pas mal de jours ont passé, ce billet est destiné à nous rafraîchir la mémoire sur la question, à moi le premier !</p>
<p><span id="more-46"></span></p>
<p>Le but du dojo est de faire exécuter un scénario réaliste comme celui-ci dessous, que j&rsquo;avais mis au point avec une collègue chimiste :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_thumb.png" width="559" height="446" /></a> </p>
<p>Ce qui nous intéresse c&rsquo;est qu&rsquo;il faut implémenter un calcul de <a href="http://fr.wikipedia.org/wiki/R%C3%A9gression_lin%C3%A9aire" target="_blank">régression linéaire</a>,  et pour cela il sera probablement nécessaire de pratiquer un peu de TDD en plus du BDD ci-dessus, et c&rsquo;est pourquoi l&rsquo;exemple peut nous montrer comment s&rsquo;articulent BDD et TDD.</p>
<p>Dans la séance du 5 janvier j&rsquo;avais proposé un scénario simplifié, afin de prendre en main l&rsquo;environnement de développement (j&rsquo;utilise <a href="http://www.jetbrains.com/ruby/index.html" target="_blank">RubyMine</a>, mais on peut aussi travailler directement en ligne de commande avec Cucumber).</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_3.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_thumb_3.png" width="544" height="462" /></a> </p>
<p>L&rsquo;idée était d&rsquo;aligner tous les points sur une droite passant par zéro, comme cela on pouvait trouver l&rsquo;équation de la droite sans la régression linéaire (dans un premier temps), et donc juste se familiariser avec l&rsquo;IDE et les diverses notions (les scénarios, le pont, le code métier).</p>
<p>J&rsquo;avais aussi un deuxième scénario pour vérifier qu&rsquo;on savait bien faire des vérifications sur les nombres flottants :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_thumb_4.png" width="500" height="142" /></a> </p>
<p>Pas très excitant, mais important en calcul scientifique !</p>
<p>Et le troisième scénario proposait une droite qui ne passait plus par zéro :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_5.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_thumb_5.png" width="493" height="150" /></a> </p>
<p>Et justement le dojo s&rsquo;était arrêté sur l&rsquo;échec de ce dernier test &#8211; notre calcul de l&rsquo;équation était vraiment trop simpliste :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/1180c6cc8ff6_A297/image_thumb_6.png" width="353" height="438" /></a> </p>
<p>D&rsquo;après la rétrospective de la session, ces scénarios simplifiés n&rsquo;étaient pas forcément une bonne idée, car ils nous ont un peu éloigné de l&rsquo;objectif d&rsquo;aller vers du TDD. Il n&rsquo;est pas simple dans l&rsquo;animation des dojos de trouver le bon équilibre entre pédagogie et bonne progression !</p>
<p>Ils nous ont tout de même permis de mettre au point le pont suivant vers le code métier, pont qui sera utilisé tel quel dans la session de demain :</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<pre id="codeSnippet" class="csharpcode">Given /^the calibration mode is R=f\(Q\)$/ <span class="kwrd">do</span><br />   #nothing<br />end<br /><br />Given /^a calibration curve <span class="kwrd">for</span> component CO2 <span class="kwrd">with</span> the points:$/ <span class="kwrd">do</span> |table|<br />  @curve = CalibrationCurve.new  <br />  table.hashes.each <span class="kwrd">do</span> |hash|<br />    area = hash[<span class="str">"Area"</span>]<br />    concentration=hash[<span class="str">"Concentration"</span>]<br />    @curve.ajoute_points(area.to_f, concentration.to_f)<br />  end<br />end<br /><br /><span class="kwrd">Then</span> /^the computed concentration <span class="kwrd">for</span> area (.*) should be (.*)$/ <span class="kwrd">do</span> |area, expected_concentration|<br />  calcul_concentration = @curve.calcul_concentration(area.to_f)<br />  calcul_concentration.should be_close(expected_concentration.to_f, 0.001)<br />end<br /><br />When /^the slope should be (.*)$/ <span class="kwrd">do</span> |expected_slope|<br />  @curve.calcule_slope.should == expected_slope.to_f<br /><br />end<br /><br />When /^the ordinate at origin should be (.*)$/ <span class="kwrd">do</span> |expected_ordinate|<br />  @curve.calcule_ordinate.should == expected_ordinate.to_f<br />end<br /><br />When /^the following table should be valid:$/ <span class="kwrd">do</span> |table|<br />    table.hashes.each <span class="kwrd">do</span> |hash|<br />    area = hash[<span class="str">"Area"</span>]<br />    concentration=hash[<span class="str">"Concentration"</span>]<br />    @curve.calcul_concentration(area.to_f).should == concentration.to_f<br />  end<br />end<br /></pre>
<p></div>
<p>Alors à demain à l&rsquo;ENSIMAG salle 206 de 12 à 14h pour la suite !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Un exemple de rédaction de spécifications exécutables avec Cucumber</title>
		<link>https://blog.developpez.com/bruno-orsier/p8551/developpement-agile/un_exemple_de_redaction_de_specification</link>
		<comments>https://blog.developpez.com/bruno-orsier/p8551/developpement-agile/un_exemple_de_redaction_de_specification#comments</comments>
		<pubDate>Fri, 29 Jan 2010 15:03:46 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[BDD]]></category>
		<category><![CDATA[Développement agile]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour démarrer la discussion sur la rédaction de spécifications exécutables l&#8217;autre soir au CARA, j&#8217;avais pris l&#8217;exemple de la réalisation d&#8217;un logiciel de comptage de calories. L&#8217;exemple n&#8217;est pas gratuit : je trouve que la plupart des logiciels de ce genre ont une interface utilisateur très influencée par l&#8217;implémentation avec une base de données, et pas très influencée par les besoins utilisateurs. Pardonnez l&#8217;expression, mais ce genre de logiciel &#171;&#160;pue la base de données&#160;&#187;, alors [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Pour démarrer la discussion sur la rédaction de spécifications exécutables <a href="http://blog.developpez.com/bruno-orsier/p8534/developpement-agile/pourquoi-sarsquo-interesser-au-bdd-behav/" target="_blank">l&rsquo;autre soir au CARA</a>, j&rsquo;avais pris l&rsquo;exemple de la réalisation d&rsquo;un logiciel de comptage de calories. L&rsquo;exemple n&rsquo;est pas gratuit : je trouve que la plupart des logiciels de ce genre ont une interface utilisateur très influencée par l&rsquo;implémentation avec une base de données, et pas très influencée par les besoins utilisateurs. Pardonnez l&rsquo;expression, mais ce genre de logiciel &laquo;&nbsp;pue la base de données&nbsp;&raquo;, alors que la base de donnée n&rsquo;a que peu de valeur pour l&rsquo;utilisateur &#8211; c&rsquo;est juste un choix d&rsquo;implémentation bien pratique pour les développeurs. </p>
<p>Par conséquent, il me semble que travailler sur un tel logiciel est intéressant pour apprendre le BDD, car justement nous aimerions éviter de &laquo;&nbsp;polluer&nbsp;&raquo; les scénarios par des concepts purement techniques comme des questions de base de données. Le challenge est donc de parvenir à exprimer les scénarios avec des mots d&rsquo;utilisateur et pas du jargon informatique.</p>
<p>Dans ce billet je vais détailler mon point de départ et illustrer les premières leçons que j&rsquo;ai tirées des discussions. Bien sûr cela reste un exemple &laquo;&nbsp;jouet&nbsp;&raquo; mais je parviendrai peut-être à en faire une application complète dans quelque temps.</p>
<p>Je suis également passé à la rédaction de scénarios en français, ce qui est possible en Cucumber (tapez la commande <font face="Courier New">cucumber -i18n fr</font> pour avoir les équivalences).</p>
<p>Mon point de départ était la fonctionnalité suivante :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_thumb.png" width="492" height="76" /></a> </p>
<p>
<span id="more-45"></span></p>
<p>Les discussions ont fait apparaître que &laquo;&nbsp;qui veut perdre du poids&nbsp;&raquo; n&rsquo;avait aucune influence pour le moment (je voulais souligner que cela pourrait avoir de l&rsquo;importance dans de futures fonctionnalités, mais cette information superflue ici rend simplement plus difficile la compréhension de la fonctionnalité). Donc une<strong> leçon à retenir : ne pas &laquo;&nbsp;sur-spécifier&nbsp;&raquo;</strong> !</p>
<p>J&rsquo;ai ensuite écrit de très petits scénarios comme : </p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_thumb_3.png" width="644" height="173" /></a></p>
<p>ce qui m&rsquo;a permit ensuite d&rsquo;écrire un scénario couvrant une journée complète (<em>les lignes commençant par # sont des commentaires</em>) :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_thumb_4.png" width="647" height="252" /></a> </p>
<p>et ainsi de suite. Cela m&rsquo;a permis d&rsquo;arriver un scénario vérifiant la fonctionnalité &laquo;&nbsp;connaître le nombre total de calories pour la journée&nbsp;&raquo;.</p>
<p>Les petits scénarios m&rsquo;ont été utiles pour mettre au point le code derrière tout cela en faisant de petits pas (tout comme quand on pratique le TDD). Mais ils contribuent à l&rsquo;impression de &laquo;&nbsp;verbosité excessive&nbsp;&raquo; que mes scénarios ont donné durant la présentation, donc il faut surement accepter de les supprimer une fois que leur intention a été capturée par ailleurs dans le scénario final.</p>
<p>J&rsquo;ai ensuite travaillé sur une deuxième fonctionnalité :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_thumb_5.png" width="574" height="87" /></a> </p>
<p>Fonctionnalité que j&rsquo;ai souhaité vérifier de la manière suivante :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_thumb_6.png" width="678" height="271" /></a> </p>
<p>Un point qui a posé problème est que je ne vérifie pas la totalité du contenu de la table des aliments &#8211; cela ne me paraît pas nécessaire. Mais mes attentes sont peu claires pour le lecteur, et pour lever l&rsquo;ambiguïté il aurait sans doute suffit d&rsquo;écrire &laquo;&nbsp;<font color="#ff0000"><font color="#000000">la table des aliments contient</font> notamment</font><font color="#000000">:&nbsp;&raquo;. Il faut donc <strong>rédiger les vérifications avec beaucoup de précision et de clarté</strong>.</font></p>
<p>Un deuxième problème est que mon scénario est bien plus long que la copie d&rsquo;écran ci-dessus &#8211; en effet j&rsquo;avais à nouveau couvert avec mes exemples une journée complète. Ce qui est inutile vu que le calcul pour la journée était déjà couvert par la vérification de la fonctionnalité précédente ! Donc une autre<strong> leçon à retenir est de ne pas &laquo;&nbsp;sur-vérifier&nbsp;&raquo;</strong>.</p>
<p>La troisième fonctionnalité consistait à travailler à partir d&rsquo;une table pré-remplie :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_thumb_7.png" width="647" height="221" /></a> </p>
<p>etc.</p>
<p>Mes scénarios ci-dessus ont suscité un vif débat, car ils semblent représenter un effort démesuré par rapport au volume de code qui est testé derrière. En effet il s&rsquo;agit d&rsquo;implémenter une simple règle de trois, de parcourir des listes, d&rsquo;utiliser une table de hachage. Je pense que la critique était justifiée, et que mes scénarios auraient pu contenir moins d&rsquo;information, mais que cela ne remet pas en cause l&rsquo;intérêt du BDD et l&rsquo;intérêt de travailler avec des exemples (ces derniers méritant certainement d&rsquo;être réhabilités dans nos processus de développement logiciel &#8211; voir mon <a href="http://blog.developpez.com/bruno-orsier/p8534/developpement-agile/pourquoi-sarsquo-interesser-au-bdd-behav/">billet précédent</a>).</p>
<p>Un autre élément de débat était de savoir comment se positionner par rapport à une éventuelle interface graphique. Etant donné la manière dont j&rsquo;ai écrit et réalisé les fonctionnalités, l&rsquo;application n&rsquo;existe pas encore, je suis simplement en train de mettre au point une bibliothèque de classes, indépendamment de la manière dont elles seront ultérieurement présentées à un utilisateur. Cette approche était confortable par certains, mais d&rsquo;autres auraient préféré travailler à partir d&rsquo;une interface graphique (le risque étant de mettre au point un bon modèle métier bien testé, mais de ne pas satisfaire les utilisateurs qui veulent voir très vite une interface graphique).</p>
<p>Je pense que le schéma suivant de <a title="http://www.dddfrance.org/DDDViteFait" href="http://www.dddfrance.org/DDDViteFait" target="_blank">DDD Vite Fait</a> illustre l&rsquo;endroit où j&rsquo;essaie de me placer pour l&rsquo;instant &#8211; mes scénarios concernent le domaine, et pas l&rsquo;application, ce qui est source de confusion :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_8.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/13a27bf0274f_E501/image_thumb_8.png" width="354" height="212" /></a> </p>
<p>Pour finir ce billet, au cas ou vous soyez curieux de ce qu&rsquo;il y a derrière (c&rsquo;est généralement le cas quand je présente les scénarios), je vous montre le code que j&rsquo;ai écrit pour le pont entre les scénarios exécutables et les classes du domaine :</p>
</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<pre id="codeSnippet" class="csharpcode"># encoding: UTF-8<br /><br />require 'F:\ruby\cucumber\comptageCalories\ComptageCalories\compteur_calories.rb'<br />require 'F:\ruby\cucumber\comptageCalories\ComptageCalories\table_aliments.rb'<br /><br />Before <span class="kwrd">do</span><br />  @compteur = CompteurCalories.new<br />  @table_aliments = TableAliments.new<br />end<br /><br /><br />When /^le nombre total de calories devrait être (.*)$/ <span class="kwrd">do</span> |calories|<br />  #puts @compteur.total_calories<br />  @compteur.total_calories.should be_equal calories.to_i<br />end<br /><br />When /^une table des aliments vide$/ <span class="kwrd">do</span><br />  #rien<br />end<br /><br />When /^la table des aliments contient:$/ <span class="kwrd">do</span> |table|<br />  # table is a | confiture | 1 | cuillère à café | 30 |<br />  table.hashes.each <span class="kwrd">do</span> |hash|<br />    reference = @table_aliments.reference(hash[<span class="str">"aliment"</span>])<br />    reference.quantite.should == hash[<span class="str">"quantite"</span>]<br />    reference.unite.should == hash[<span class="str">"unite"</span>]<br />    reference.calories.should == hash[<span class="str">"calories"</span>]<br />  end<br />end<br /><br />When /^je mange (\d+\.?\d*) (.*) (de\s+|d')(.*\w|.*%) \((\d+) (.*) valant (.*) calories\)$/ <span class="kwrd">do</span>  |quantite_dans_unite,unite1, de, nom_aliment,reference_dans_unite,unite2,reference_en_calories|<br />  @table_aliments.ajoute(nom_aliment, reference_dans_unite,unite2, reference_en_calories)<br />  @compteur.ajoute(nom_aliment,quantite_dans_unite, reference_dans_unite, reference_en_calories)<br />end<br /><br />When /^je mange (\d+\.?\d*) (.*) (de\s+|d')(.*\w|.*%)$/ <span class="kwrd">do</span> |quantite_dans_unite,unite1, de, nom_aliment|<br />     reference = @table_aliments.reference(nom_aliment)                   <br />     reference_dans_unite = reference.quantite                                <br />     reference_en_calories = reference.calories<br />     @compteur.ajoute(nom_aliment,quantite_dans_unite, reference_dans_unite, reference_en_calories)  <br />end<br /><br /><br />When /^la table des aliments suivante:$/ <span class="kwrd">do</span> |table|<br />  # table is a | confiture | 1 | cuillère à café | 30 |<br />  table.hashes.each <span class="kwrd">do</span> |hash|<br />    @table_aliments.ajoute(hash[<span class="str">"aliment"</span>],hash[<span class="str">"quantite"</span>],hash[<span class="str">"unite"</span>],hash[<span class="str">"calories"</span>])<br />  end<br />end<br /></pre>
<p></div>
<div>Le pont implique de manipuler des expressions régulières et d&rsquo;utiliser classes et méthodes du domaine, il faut donc absolument un développeur pour le réaliser. Il y a certainement moyen de rendre le pont plus lisible &#8211; sans doute avec le concept récent de <a href="http://www.engineyard.com/blog/2009/cucumber-step-argument-transforms/" target="_blank">Step Argument Transforms</a> que m&rsquo;a signalé récemment <a href="http://21croissants.blogspot.com/" target="_blank">Jean-Michel Garnier</a>. Je regarderai comment faire dans un deuxième temps. D&rsquo;ailleurs, dans ma TODO list, il y a également l&rsquo;étude de <a href="http://www.engineyard.com/blog/2009/15-expert-tips-for-using-cucumber/" target="_blank">15 Expert Tips for Using Cucumber</a>.</div>
<div> </div>
<div>Je vous passe le code final, les deux classes CompteurCalories et TableAliments, elles représentent vraiment peu de code pour le moment ! Je les ai codées en Ruby, mais comme je l&rsquo;ai indiqué dans d&rsquo;autres billets il n&rsquo;y pas de difficulté technique à les réaliser en .NET.</div>
<div></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell, suppression sélective de fichiers</title>
		<link>https://blog.developpez.com/bruno-orsier/p8563/outils-pour-developpeurs/powershell/powershell_suppression_selective_de_fich</link>
		<comments>https://blog.developpez.com/bruno-orsier/p8563/outils-pour-developpeurs/powershell/powershell_suppression_selective_de_fich#comments</comments>
		<pubDate>Wed, 27 Jan 2010 09:51:06 +0000</pubDate>
		<dc:creator><![CDATA[Bruno Orsier]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici un nouvel exemple d&#8217;utilisation de Powershell, histoire de peut-être vous donner envie de pratiquer ce shell bien utile. Dans mes tests, j&#8217;ai souvent un processus qui tourne en boucle, d&#8217;ailleurs grâce un script posté dans un billet précédent. Ce processus génère un fichier de log à chaque fois, ce qui me fait des dizaines de milliers de fichiers. Pour éviter de remplir le disque dur, je voudrais garder uniquement les fichiers de log qui [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici un nouvel exemple d&rsquo;utilisation de Powershell, histoire de peut-être vous donner envie de pratiquer ce shell bien utile. Dans mes tests, j&rsquo;ai souvent un processus qui tourne en boucle, d&rsquo;ailleurs grâce un script posté dans un <a href="http://blog.developpez.com/bruno-orsier/p8505/outils-pour-developpeurs/powershell/un-exemple-avec-powershell/">billet précédent</a>. Ce processus génère un fichier de log à chaque fois, ce qui me fait des dizaines de milliers de fichiers. Pour éviter de remplir le disque dur, je voudrais garder uniquement les fichiers de log qui présentent un intérêt, par exemple ceux qui contiennent le mot ERROR. C&rsquo;est facile en PowerShell, avec un peu de pratique on peut le faire directement sur la ligne de commande :</p>
<p>
<span id="more-51"></span></p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image.png" target="_blank"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image_thumb.png" width="989" height="138" /></a> </p>
<p><em>(le message  d&rsquo;erreur vient d&rsquo;un fichier en cours d&rsquo;écriture)</em></p>
<p>Après avoir mis cela au point sur la ligne de commande comme ci-dessus, je met cette commande dans un fichier de script pour la réutiliser plus tard :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image_3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image_thumb_3.png" width="499" height="235" /></a> </p>
<p>On peut noter dans le script la barre verticale, indiquant un pipeline. Le pipeline passe la sortie de la première commande (la liste de fichier résultant de dir) à la deuxième commande qui consiste en un <em>foreach</em>. Dans le bloc du <em>foreach</em> on référence l&rsquo;objet courant (le fichier) avec la variable spéciale <font color="#ff0000">$_</font>.  <em>foreach</em> est un alias pour <em>ForEach-Object</em> (et peut encore se raccourcir en &laquo;&nbsp;%&nbsp;&raquo;, comme dans l&rsquo;exemple ci-dessous).</p>
<p>Simple, non ?</p>
<p>Un autre exemple dans la même veine consiste à supprimer les fichiers .DATA générés par mes expériences, mais pas trop tôt afin de ne pas interférer avec les analyses en cours &#8211; j&rsquo;attends donc 30 minutes par exemple. Voici un script pour faire cela (j&rsquo;ai encadré en rouge le calcul sur les dates) :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image_thumb_4.png" width="580" height="400" /></a> </p>
<p>Voilà le résultat sur la console :</p>
<p><a href="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image_5.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ftp-developpez.com/bruno-orsier/blog/images/814e49b529a8_B95A/image_thumb_5.png" width="762" height="129" /></a> </p>
<p>Il restera à mieux formater le taux de génération !</p>
<p>Le même script sous forme de code copiable, au cas où ca vous intéresse de le récupérer :</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><br />$DELAY=60*15<br /><br />$total_deleted = 0<br /><br /><span style="color: #0000ff">while</span> ($True) {<br />    $deleted = 0<br />    dir c:\data -recurse -include *.data | % { <br />        <span style="color: #0000ff">if</span> ( ((get-date)-$_.LastWriteTime).TotalMinutes -gt 30) {<br />                del $_ ; $deleted += 1<br />        }<br />    }<br />    $total_deleted += $deleted<br />    $generation_rate = ($deleted / $DELAY) * 60<br />        <br />    write-host (get-date), `<br />                <span style="color: #006080">"total already deleted "</span>, $total_deleted, `<br />                <span style="color: #006080">" generation rate "</span>, $generation_rate, <span style="color: #006080">" / minute"</span><br />                <br />    Sleep -Seconds $DELAY        <br />}<br /></pre>
<p></div>
<p>Voilà des exemples que j&rsquo;aurais été bien incapable de réaliser en DOS, et qui sont très faciles à faire en PowerShell.</p>
<p>Et vous, quels sont les scripts qui vous simplifient la vie ?</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
