Tutoriel: Intégrer le dhtmlxGrid dans une application Spring ROO

Tags

, , ,

Par Anthony Lopes Barata.

L’objectif de ce tutoriel est de remplacer les tableaux générés par Spring ROO par des composants dynamiques dhtmlxGrid et ainsi permettre d’y ajouter des fonctionnalités en utilisant l’API dhtmlx ou des fonctions Javascript diverses. Nous nous appuierons sur le tutoriel de création d’une application Spring Roo (Pizza Shop) avec Jetty intégré (facultatif).

La dhtmlxGrid intégrée à l'application Spring ROO Pizza Shop

Le composant dhtmlxGrid intégré à l'application Spring ROO Pizza Shop

– Il faut tout d’abord ajouter les fichiers nécessaires au chargement de la dhtmlxGrid dans le répertoire src/main/webapp de l’application (disponibles sur http://dhtmlx.com/docs/products/dhtmlxGrid/index.shtml ).

– Puis créer un fichier alternatif de génération de tableau: dupliquer src/main/webapp/WEB-INF/tags/form/fields/table.tagx et renommer la copie en table_dhtmlxGrid.tagx, dans le même répertoire.

– Dans ce fichier alternatif, supprimer le contenu entre les balises html <table> et </table> (incluses) qui sert à créer une table html classique (que l’on cherche donc à remplacer), et remplacer par le script de la dhtmlxGrid.

Ici:

<link rel="STYLESHEET" type="text/css" href="/Pizza/dhtmlxGrid/codebase/dhtmlxgrid.css"></link>
<link rel="stylesheet" type="text/css" href="/Pizza/dhtmlxGrid/codebase/skins/dhtmlxgrid_dhx_skyblue.css"></link>

<script type="text/javascript" src="/Pizza/dhtmlxGrid/codebase/dhtmlxcommon.js">
<!--Placez ici le code de votre script// -->
</script>
<script type="text/javascript" src="/Pizza/dhtmlxGrid/codebase/dhtmlxgrid.js">
<!--Placez ici le code de votre script// -->
</script>
<script type="text/javascript" src="/Pizza/dhtmlxGrid/codebase/dhtmlxgridcell.js">
<!--Placez ici le code de votre script// -->
</script>

<div id="gridbox" style="width: 500px; height: 270px; background-color: white;"></div>
<script>
mygrid = new dhtmlXGridObject('gridbox');
mygrid.setImagePath("/dhtmlxGrid/codebase/imgs/");
mygrid.setHeader("name");
mygrid.setInitWidths("500");
mygrid.setColAlign("right");
mygrid.setColTypes("ed");
mygrid.setColSorting("str");
mygrid.init();
mygrid.setSkin("dhx_skyblue");
mygrid.load("/Pizza/toppings/json", "json");
</script>

Note: il semble que STS gère mal les balises <script src="..." /> et il faut donc dissocier balise ouvrante et fermante, en plaçant entre les deux au moins une balise de commentaire, afin que le chargement du fichier .js fonctionne.

– Nous allons modifier le tableau de la liste des toppings, accessible en cliquant sur “List all toppings” dans le menu de l’application. Pour que l’application utilise notre nouveau fichier, il faut modifier dans le fichier src/main/webapp/WEB-INF/views/toppings/list.jspx les balises <table:table> en <table:table_dhtmlxGrid> et supprimer la ligne <table:column id="c_com_springsource_roo_pizzashop_domain_Topping_name" property="name" z="hHx0eYgxErmr3HAdqNm5089ZxlI="/> qui ne sert plus. On peut dès à présent constater que le tableau des toppings a été remplacé par une dhtmlxGrid si au moins un topping a été créé.

– Toutefois, on constate qu’aucune donnée présente dans l’application n’est chargée dans la grille. Il faut donc faire le lien entre les deux. Nous allons ici utiliser le format de fichier JSON facilement généré par Spring ROO et lu nativement par la dhtmlxGrid (tout comme le CSV et le format XML). Pour cela, entrer les commandes suivantes dans un shell Roo pour générer les classes de manipulation des données en JSON:

json add --class ~.domain.Topping
web mvc json add --jsonObject ~.domain.Topping --class ~.web.ToppingController

– Il faut récupérer le contrôle sur les fonctions générées automatiquement.

Pour cela, couper les fonctions listJson() et updateFromJsonArray(String) du fichier src/main/java/com/springsource/roo/pizzashop/web/ToppingController_Roo_Controller_Json.aj et les coller dans la classe src/main/java/com/springsource/roo/pizzashop/web/ToppingController.java.

Sous STS, dans le fichier src/main/java/com/springsource/roo/pizzashop/web/ToppingController_Roo_Controller_Json.aj, dans la vue ‘Outline’, faire un clic droit > refactor > push in sur chacune des deux fonctions pour réaliser la même opération.

– Maintenant qu’elles sont accessibles, nous pouvons les modifier:

Ajouter la classe interne ToppingView dans la classe ToppingController et modifier la fonction listJson() comme ceci:

package source.web;

import java.util.ArrayList;

//imports...

@RequestMapping("/toppings")
@Controller
@RooWebScaffold(path = "toppings", formBackingObject = Topping.class)
@RooWebJson(jsonObject = Topping.class)
public class ToppingController {
public class ToppingView{
public long id;
public List<String> data=new ArrayList<String>();
}
@RequestMapping(value="/json", headers = "Accept=application/json") //permet d'appeler fonction avec l'URL <emplacement du projet>/Pizza/toppings/json
@ResponseBody
public ResponseEntity<String> listJson() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
List<Topping> result = Topping.findAllToppings();
List<ToppingView> collection= new ArrayList<ToppingView>();
for(Topping topping:result){
ToppingView toppingView= new ToppingView();
toppingView.id=topping.getId();
toppingView.data.add(topping.getName());
collection.add(toppingView);
}
String json_result= "{rows: "+new JSONSerializer().exclude("*.class").deepSerialize(collection)+"}";
return new ResponseEntity<String>(json_result, headers, HttpStatus.OK);
}

//.....

}

– Un tableau des données de l’application est maintenant disponible à l’URL http://localhost:8090/pizzashop/toppings/json.
Nous allons donc ajouter dans le fichier src/main/webapp/WEB-INF/tags/form/fields/table_dhtmlxGrid.tagx créé précédemment, la ligne mygrid.load("/Pizza/toppings/json", "json"); après la ligne myGrid.init();.

– Reste à ajouter le lien vers les fonctions présentes dans les tableaux classiques, à savoir la visualisation, l’édition et la suppression d’un topping. Il faut donc modifier le script du fichier src/main/webapp/WEB-INF/tags/form/fields/table_dhtmlxGrid.tagx comme ceci pour y ajouter ces colonnes:

function doOnAfterRowDeleted(id, pid) {
window.alert('id supprime:' + id);
deleteRow(id);
return true;
}

function deleteRow(id) {
url2 = "/Pizza/toppings/" + id;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("DELETE", url2, false);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// Code si requête OK
}
}
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(null);
}

mygrid = new dhtmlXGridObject('gridbox');
mygrid.setImagePath("/dhtmlxGrid/codebase/imgs/");
mygrid.setHeader("name, , , ");
mygrid.setInitWidths("300,30,30,30");
mygrid.setColAlign("left,center,center,center");
mygrid.setColTypes("ro,ro,ro,ro");
mygrid.setColSorting("str,str,str,str");
mygrid.attachEvent("onAfterRowDeleted", doOnAfterRowDeleted);
mygrid.init();
mygrid.setSkin("dhx_skyblue");
mygrid.load("/Pizza/toppings/json", "json");

Remarque: pour insérer une image cliquable dans la dhtmlxGrid, il faut préciser dans la colonne le type link ou str et donner comme valeur le code du lien à utiliser, comme nous allons le voir dans la prochaine étape.

– Nous allons maintenant modifier le fichier de la classe ToppingController pour qu’il alimente ces colonnes avec les bons liens lors du chargement de la dhtmlxGrid (fonction listJson()):

@RequestMapping(value="/json", headers = "Accept=application/json")
@ResponseBody
public ResponseEntity<String> listJson() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
List<Topping> result = Topping.findAllToppings();
List<ToppingView> collection= new ArrayList<ToppingView>();
for(Topping topping:result){
ToppingView toppingView= new ToppingView();
toppingView.id=topping.getId();
toppingView.data.add(topping.getName());
//view link
toppingView.data.add("<a href="/Pizza/toppings/"+topping.getId() +""><img src="images/show.png" /></a>");
//update link
toppingView.data.add("<a href="/Pizza/toppings/"+topping.getId() +"?form"><img src="images/update.png" /></a>");
//delete link
toppingView.data.add("<a href="javascript:void(0)" onClick="mygrid.deleteRow("+topping.getId()+")"><img src="images/delete.png" /></a>");
collection.add(toppingView);
}
String json_result= "{rows: "+new JSONSerializer().exclude("*.class").deepSerialize(collection)+"}";
return new ResponseEntity<String>(json_result, headers, HttpStatus.OK);
}

Les liens sont maintenant créés lors de l’appel à la fonction mygrid.load(…) lors du chargement ou du rafraîchissement de la page qui liste tous les toppings.

FIN TUTORIEL

Nous avons ainsi remplacé de façon ISO-fonctionnelle le composant tableau généré par défaut avec Spring ROO par le composant dhtmlxGrid, nous permettant de disposer de toute la puissance de ce composant AJAX.

– Concernant la pagination dans le cas de gros volumes de données, elle est présente nativement dans la version payante de la dhtmlxGrid et nous n’avons pas encore développé de fonction équivalente. Toutefois, une fonctionnalité de cette dhtmlxGrid, le “Smart Rendering” permet de ne charger que ce qui est affiché actuellement dans la table (et les lignes d’avant/après pour ne pas gêner la navigation). Cela devrait permettre en théorie de ne pas diminuer les performances de notre grille pour gérer de gros volumes de données. La pagination n’aurait alors plus qu’une vocation ergonomique.

Quelques possibilités d’évolution:

  • Modifications des données directement dans la grid, via des cellules éditables,
  • Intégration des formulaires CRUD dans des pop-ups sans changer de page en utilisant la bibliothèque javascript Dojo par exemple (cette API AJAX étant disponible par défaut dans les applications Spring ROO)
  • Ajout d’un champ de recherche en tête de colonne (cf exemple du site dhtmlx)
  • Ajout d’un tri des données pour chaque colonne.

Tutoriel: tester une application Spring avec Jetty Embedded

Tags

, , , , ,

Dans ce billet, je vais mettre en œuvre un serveur Jetty Embedded sur une application Spring, afin d’obtenir les fondations d’un système de tests automatisés et semi-automatisés.

En effet, l’objectif, en ce qui me concerne, est de faciliter la recette d’applications via les deux méthodes suivantes :

  1. Tests automatisés pour vérifier la conformité aux spécifications,
  2. Automatisation de la phase d’initialisation des données pour réaliser la partie “manuelle” de la recette. Cela permet de dérouler de multiples scénarios de recette basés sur des pré-requis différents en termes de données, sans avoir à réaliser cette initialisation de façon “artisanale”, généralement laborieuse.

Spring apporte, entre autres, deux avantages appréciables :

  1. Les applications Spring peuvent s’exécuter dans un simple container Web, tel que Jetty ou Tomcat,
  2. L’outillage Spring fournit des outils de mise en route rapide tels que Spring Fuse et Spring ROO.

Je vais m’appuyer sur le tutoriel Beginning With Roo, qui consiste à créer une application de gestion pour une pizzeria, nommée Pizza Shop. L’application permet de confectionner des pizzas et de gérer des commandes.

L’objectif est de mettre en place les fondations pour les deux types de tests décrits ci-dessus. En l’occurrence la partie initialisation des données consistera à créer de façon automatique des bases de pizza (tomate, crème fraîche), et des ingrédients. Les tests, qu’ils soient automatiques ou manuels, pourront donc s’appuyer sur ces données, pour vérifier par exemple qu’une pizza doit posséder une et une seule base, être composée d’un nombre d’ingrédients compris entre un minimum et un maximum, avoir un prix, etc…

pizzashopfinal

Objectif: automatiser l'initialisation des données de l'application

Ceux qui ont déjà réalisé ce tutoriel auront noté qu’à l’étape 6, “Loading the Web Server”, on déploie l’application sur un Tomcat ou un Jetty embedded, via l’une de ces commandes maven :

  • mvn tomcat:run
  • mvn jetty:run

ou bien dans un container configuré dans la vue “server” d’Eclipse / STS.

La méthode que je propose ici permet de faire l’équivalent de façon programmatique, et d’ajouter la phase d’initialisation des données, ouvrant ainsi la porte à l’automatisation des tests.

C’est parti, avec la version 1.2.2 de Spring ROO…

1/ Bâtir l’application Pizza Shop

Le script Spring ROO suivant reprend les commandes du tutoriel de façon à obtenir une ” pizza shop ” opérationnelle :

project --topLevelPackage com.springsource.roo.pizzashop --projectName Pizza --java 6 --packaging JAR
jpa setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY
entity jpa --class ~.domain.Topping
field string --fieldName name --notNull --sizeMin 2
entity jpa --class ~.domain.Base
field string --fieldName name --notNull --sizeMin 2
entity jpa --class ~.domain.Pizza
field string --fieldName name --notNull --sizeMin 2
field number --fieldName price --type java.lang.Float
field set --fieldName toppings --type ~.domain.Topping
field reference --fieldName base --type ~.domain.Base
entity jpa --class ~.domain.PizzaOrder
field string --fieldName name --notNull --sizeMin 2
field string --fieldName address --sizeMax 30
field number --fieldName total --type java.lang.Float
field date --fieldName deliveryDate --type java.util.Date
field set --fieldName pizzas --type ~.domain.Pizza
web mvc setup
web mvc all --package ~.web

Note 1 : personnellement, j’utilise STS. La première ligne de commande est donc remplacée par l’utilisation du wizard ” New > Spring ROO Project ” :

Wizard STS de création de projet Spring ROO

Wizard STS de création de projet Spring ROO

Note 2 : plutôt que de taper les commandes une à une, il est possible de les copier dans un fichier, puis d’exécuter le script entier:

script –file “chemin absolu du fichier script”

Il pourra être utile d’activer également tout ou partie des logs via l’une des commandes ROO suivantes (ou en modifiant directement le fichier log4j.properties pour ceux qui ne souhaitent pas abuser des commandes ROO):

logging setup –level DEBUG
logging setup –level DEBUG –package PROJECT

A partir de là, l’application est opérationnelle. Il est donc possible d’utiliser l’une des méthodes décrites à l’étape 6 du tutoriel pour la voir à l’œuvre, mais bien sûr, sans aucune donnée.

Sous STS, on créera les dossiers src/test/java et src/test/resources, puis, via un clic droit sur le projet, on lancera un ” Maven > Update Project… ” pour que tout soit en ordre.

2/ Configurer Jetty Embedded

Le script Spring ROO suivant va ajouter Jetty Embedded au classpath de test de l’application :

dependency add --groupId org.eclipse.jetty --artifactId jetty-server --version 7.2.2.v20101205 --scope TEST
dependency add --groupId org.eclipse.jetty --artifactId jetty-webapp --version 7.2.2.v20101205 --scope PROVIDED
dependency add --groupId org.eclipse.jetty --artifactId jetty-jsp-2.1 --version 7.2.2.v20101205 --scope  PROVIDED
dependency add --groupId org.mortbay.jetty --artifactId jsp-2.1-glassfish --version 2.1.v20100127 --scope PROVIDED
dependency remove --groupId javax.el --artifactId el-api --version 1.0
dependency remove --groupId javax.servlet --artifactId servlet-api --version 2.5
dependency remove --groupId javax.servlet.jsp --artifactId jsp-api --version 2.1

Ce script remplace notamment les dépendances javax.* indiquées par les version Jetty correspondantes. Il faudra également ajouter les exclusions suivantes au POM du projet pour la même raison :

<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl-api</artifactId>
    <version>1.2</version>
    <exclusions>
        <exclusion>
            <artifactId>servlet-api</artifactId>
            <groupId>javax.servlet</groupId>
        </exclusion>
        <exclusion>
            <artifactId>jsp-api</artifactId>
            <groupId>javax.servlet.jsp</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jstl-impl</artifactId>
    <version>1.2</version>
    <exclusions>
        <exclusion>
            <artifactId>servlet-api</artifactId>
            <groupId>javax.servlet</groupId>
        </exclusion>
        <exclusion>
            <artifactId>jsp-api</artifactId>
            <groupId>javax.servlet.jsp</groupId>
        </exclusion>
    </exclusions>
</dependency>

3/ Désactiver tilesConfigurer, incompatible avec JUnit

Spring MVC utilise Tiles, mais ce dernier a besoin d’un ServletContext pour fonctionner, non disponible dans un test JUnit.
Une solution pour y remédier (je suis preneur de toute autre) est de supprimer le bean tilesConfigurer du contexte Spring de test.
Ici, nous dupliquerons le fichier webmvc-config.xml qui se trouve dans src/main/webapp/WEB-INF/spring. Nous nommerons cette copie webmvc-config-test.xml et nous y commenterons le bean tilesConfigurer :

<!-- bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/layouts/layouts.xml</value>
            <value>/WEB-INF/views/**/views.xml</value>
        </list>
    </property>
</bean -->

Sans cette modification, nous obtiendrions l’erreur suivante à l’exécution du test :

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
[...]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tilesConfigurer' defined in URL [file:src/main/webapp/WEB-INF/spring/webmvc-config.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
[...]

4/ Ecrire le test, 1ère étape : démarrage de Jetty et déploiement de l’application

La classe suivante est à placer dans le dossier src/test/java, dans un package com.springsource.roo.pizzashop :

package com.springsource.roo.pizzashop;

import org.apache.log4j.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:/META-INF/spring/applicationContext*.xml", "file:src/main/webapp/WEB-INF/spring/webmvc-config-test.xml"})
@Transactional
public class Test {

private static final Logger logger = Logger.getLogger(Test.class);
private static int port = 8090;
private static String context = "pizzashop";
private static Server server;
private static String baseUrl;

public static void startServer() {
    // start up server
    server = new Server(port);
    // define deployment
    server.setHandler(new WebAppContext("src/main/webapp", "/" + context));
    try {
        logger.debug("startServer() before start");
        server.start();
    } catch (Exception e) {
        throw new RuntimeException("Probleme demarrage serveur", e);
    }
    // getLocalPort returns the port that was actually assigned
    int actualPort = server.getConnectors()[0].getLocalPort();
    baseUrl = "http://localhost:" + actualPort + "/" + context;
    logger.debug("startServer() serverStarted. baseUrl:" + baseUrl);
}

public static void stopServer() throws Exception {
    if (server != null)
        server.stop();
}

@org.junit.Test
public void test() throws Exception {
    startServer();
    stopServer();
}

}

La méthode startServer() démarre Jetty et déploie l’application à la volée. En plaçant un point d’arrêt sur le stopServer() de la méthode test(), on obtient le même comportement qu’avec les trois options proposées à l’étape 6 du tutoriel Spring ROO.

5/ Ecrire le test, 2ème étape : ajouter l’initialisation des données

Les annotations suivantes permettent aux tests de fonctionner dans le contexte Spring, et d’avoir ainsi accès à la couche de persistance définie pour l’application :

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:/META-INF/spring/applicationContext*.xml", "file:src/main/webapp/WEB-INF/spring/webmvc-config-test.xml" })

Il est alors possible d’instancier puis de “persister” les objets du domaine métier, pour réaliser l’initialisation des données. C’est ce que fait la méthode initData() ci-dessous :

@org.junit.Test
public void test() throws Exception {
    startServer();
    initData();
    stopServer();
}

public void initData() throws Exception {
    newBase("Tomate");
    newBase("Creme fraiche");
    newTopping("Emmental");
    newTopping("Mozzarella");
    newTopping("Chorizo");
    newTopping("Jambon");
    newTopping("Saumon");
    newTopping("Anchois");
    newTopping("Fruits de mer");
    newTopping("Champignons");
    newTopping("Oignons");
    newTopping("Gros piments");
    newTopping("Ananas");
}

public long newBase(String name) {
    Base newBase = new Base();
    newBase.setName(name);
    newBase.persist();
    newBase.flush();
    return newBase.getId();
}

public long newTopping(String name) {
    Topping newTopping = new Topping();
    newTopping.setName(name);
    newTopping.persist();
    newTopping.flush();
    return newTopping.getId();
}

Voilà de quoi réaliser une initialisation automatique de données, pour favoriser la pertinence et la vélocité des recettes :

  • Les tests automatisés permettent d’aller vers une recette exhaustive et rapide, tout en donnant moins de travail aux testeurs, …
  • … qui bénéficient également d’un bon confort lors de la phase manuelle de la recette, par la capacité d’initialiser automatiquement leurs données.

J’ai présenté ici la façon de faire pour de simples tests JUnit, mais cette méthode est d’autant plus utile dans le cadre de tests d’acceptation de type Concordion par exemple.

Serious Games : Transformez vos réunions, pour plus d’efficacité

Tags

, , , ,

L’engouement pour les “serious games” est de plus en plus vivace. Pris séparément, ces ateliers ludiques sont déjà très efficaces, mais on peut obtenir des résultats carrément étonnants en les combinant. Voici comment j’ai organisé la journée de lancement annuelle d’une équipe de 40 personnes… en exploitant les “serious games”.

Mais un “serious game” qu’est-ce que c’est ?

L’idée est de travailler sérieusement en jouant ! Oui, ce n’est pas un oxymore.
La mécanique de jeu permet de

  • Dynamiser les réunions en étant plus participatif.
  • Maximiser la collaboration et les échanges.
  • Créer de la motivation et de l’engouement.

Brièvement, le jeu place les participants dans un espace régit par des règles, avec son ou ses objectifs.
Par exemple, le Speed Boat nous met face à un bateau qui navigue en direction d’une île, métaphore du projet et de ses objectifs.
Chaque personne doit placer sur le schéma

  • Les freins qu’il a identifiés, matérialisés par des ancres qui retiennent le bateau.
  • Les éléments facilitants.
  • Les incontournables à mettre en œuvre.

L’exercice est ludique et visuel. Il facilite la prise de parole et les échanges.

Chaque individu possède une connaissance du contexte : des éléments connus de tous, des éléments qu’il est le seul à connaître et des éléments dont il ignore complètement l’existence !
Durant les échanges, on construit une connaissance collective, fruit de la mise en commun des connaissances de chacun.

On entre ainsi dans une phase de créativité ou chacun se ré-approprie ses connaissances, lève certaines ambiguïtés, et fait émerger de nouvelles idées.

Le résultat est toujours productif et surprenant.

Avec le Speed Boat, nous obtenons une analyse complète en moins d’une heure pour une assemblée de 5 à 20 personnes. Notez qu’il faudra structurer un peu différemment pour passer au dessus de 20 personnes, par exemple en utilisant la méthode de l’”Improvement Game”, décrite ci-après.

Toute cette mécanique est détaillée dans l’ouvrage Game Storming, qui fournit également un bon catalogue d’ateliers.
L’ouvrage Innovation Games quant à lui, décrit la mise en oeuvre et la planification d’ateliers. Il référence 12 ateliers très efficaces.

Allez plus loin en articulant les ateliers

Ces ateliers sont efficaces. Mais nous pouvons allez plus loin encore !
Les ateliers ont des natures diverses : ouverture (génération de nouvelles idées), exploration, consensus (ou clôture).

Certains jeux remplissent plusieurs de ces phases, comme le Speed Boat, qui permet à la fois de générer des items de manière structurée (exploration) et d’en extraire les principaux sous forme d’une matrice priorité/urgence (clôture).

Si l’on pousse un peu l’analyse, il s’agit de l’association de deux “jeux” de base, de catégorisation :

  • Catégorisation graphique : freins / facilitateurs / points incontournables.
  • Catégorisation matricielle : priorité / urgence.

Le premier est générateur d’artefacts, le second sert de clôture : on arrive à une priorisation de sujets à traiter.

Nous pouvons donc cumuler les ateliers pour répondre à un objectif global. Tout l’art réside dans le choix des ateliers adéquats, pour structurer un cheminement logique vers les objectifs.

Mise en oeuvre

Mission : organiser la journée de lancement de début d’année pour une quarantaine de personnes.
Objectif : ré-aligner la vision des participants sur les objectifs à moyen terme, reprendre les points durs et faire émerger les axes d’amélioration.

En d’autres termes, il faut pousser les gens à échanger. Reste à trouver une méthode pour que ces échanges soient efficaces. Nous visons une démarche d’amélioration. Il faudra faire émerger les problématiques, les étudier, puis les inscrire dans un plan d’action. Il ne suffit pas de faire une journée au vert. Encore faut-il qu’elle marque les esprits et donne naissance au mouvement d’amélioration.

J’ai donc choisi d’utiliser les “serious games”, et plus exactement de combiner les ateliers suivants : un ”Improvement Game”, en générateur d’item, un “Product box” pour se projeter dans le temps, et finalement un “Remember the future” pour créer le plan d’action.

Voici le détail de ces ateliers.

Improvement Game, le bilan sans la critique

Faire le bilan est souvent délicat :

  • On observe généralement certains blocages. Les gens n’osent pas s’exprimer.
  • On tombe aussi facilement dans le “bureau des plaintes” qui nuit à la productivité et peut créer certaines tensions (“C’est la faute à madame Michu…”)

Les serious games nous proposent pas mal d’options :
Le speed boat, les 5 pourquois, ou le perfection game ou improvement game.

J’ai choisi le dernier, pour son focus sur l’esprit positif. Il se déroule en trois phases :

  1. Donner une note sur la thématique travaillée.
  2. Donner le pourquoi de cette note en insistant sur les points que l’on a appréciés.
  3. Donner les axes d’amélioration pour atteindre la perfection.

Ce jeu est bien rodé, la difficulté était ici de le mettre en oeuvre pour 40 personnes !

La solution: un travail par groupes.

Dans chacun des groupes, nous avons instauré une phase de travail personnel, puis une mise en commun. Nous avons ensuite réalisé la consolidation en reprenant les 5 points les plus importants (positifs et négatifs) de chaque table. Lors de cette consolidation, nous avons directement regroupé les éléments proches, pour finir avec 5 catégories.
Cela nous a permis d’aboutir à une conclusion directement à la fin de l’exercice.

Les enseignements

  • L’effet de moyenne : globalement, la notation est de 7,5 sur 10. Pas mal, mais je me pose la question de faire apparaître plus les écarts entre les notes que la moyenne… A voir pour les prochaines éditions.
  • L’expression de tous les membres d’un groupe reste difficile. Sur le travail de groupe, j’ai observé que certaines personnes étaient en retrait. Le “Speed Boat” est plus participatif.
  • La majeure partie des points sont levés et échangés entre tous les participants.
  • Pour maximiser les échanges au niveau des tables, nous avons porté une attention particulière à la mixité des participants.
  • Le rendu visuel est vraiment efficace, jugez par vous même :

Nous avons ensuite lancé le Product Box :

Cet atelier a pour but de projeter l’application dans un futur proche (2018).
Le retour sur l’atelier est finalement assez mitigé, l’élan de créativité post apéro ayant légèrement changé le résultat 😉

Mais cela aura apporté un moment de décontraction qui contribuera au bon esprit d’équipe.
Au final, 3 pépites ont tout de même émergées de l’ensemble des idées, dont le secret ne sera pas dévoilé en public, mais qui, pour sûr offriront de belles opportunités business. A suivre…

L’usage d’un Prune the product tree aurait probablement permi d’innover sur des pistes plus réalistes. Cet exercice vise à déterminer la version suivante d’une application, de manière à avoir une évolution cohérente.

Retour d’expérience

  • Attention de bien cadrer l’atelier pour éviter certaines dissonances :
    • Nous faisons le packaging pour le produit que nous créons ou le packaging de notre organisation projet ?
    • A qui vendons-nous le produit ? A nos équipes ou à nos utilisateurs finaux ?
  • Il est toujours difficile de faire la transition entre le descriptif que l’on peut faire d’une boite exemple de céréales et le parallèle qui va être fait sur le produit.
  • N’hésitez pas à booster la créativité par un petit brainstorming rapide par exemple.
  • Attention à donner des exemples qui soient décorrélés, sinon vous risquez d’influencer la créativité des participants. Lors d’un précédent exercice, j’ai fait allusion à la géolocalisation dans les exemples. La majeure partie des boites en portaient la mention à l’issue de l’atelier !

Remember the future : passez à l’action !

A ce stade de la journée, les axes d’amélioration sont partagés, nous avons une première projection du produit. Il est temps de clore la journée. C’est parti pour un Remember the future dont le concept est basé sur une particularité typiquement humaine : nous avons du mal à nous projeter dans l’avenir.

En effet, le but à atteindre est bien souvent assez vague et parfois différent selon les individus. Les voies possibles sont donc diverses et pas forcément liées.

Pour y remédier, on se projette dans l’avenir, quelques jours après la réussite du projet.

Nous pouvons alors définir les critères de succès du projet. En d’autres termes… les objectifs !
Maintenant, il n’y a plus qu’à regarder derrière soi pour se “rappeler de l’avenir” et placer dans le temps les actions qui ont été mises en oeuvre pour atteindre ces objectifs.

Nous avons donc repris les sujets du matin, et nous sommes projetés 18 mois plus tard. “Nous avons résolus tous nos problèmes, voyons les actions que nous avons entreprises”:

Retour d’expérience

  • N’hésitez pas à être théâtral et à dresser une situation fictive, qui aidera l’assemblée à se projeter : “Nous somme le X Janvier 2025….”
  • Les “inputs” de travail en entrée de cet atelier étaient clairs, ce qui a facilité le travail de groupe, et la qualité de la restitution finale.
  • La motivation était vraiment palpable dans la restitution.
  • Il est important d’apporter un suivi sur les actions qui émergent de ces ateliers. Ce type d’atelier est très pratique pour lancer un mouvement auto-organisé, comme dans une démarche qualité initiée par les membres de l’équipe…

Conclusion : jouer, c’est du sérieux !

La journée a pris fin par une phrase qui résume l’essence des “serious games” : “Une journée innovante, entre moments solennels et moments de plaisir. Vous nous avez bien eu, nous nous sommes amusés mais vous nous avez bien fait bosser !”

La journée a été productive. Il reste à “essentialiser” cette feuille de route, afin de budgétiser la mise en oeuvre. Il ne faudra pas passer à côté des éléments rédhibitoires qui ont été cités.

Les ateliers ludiques sont décidément efficaces ! J’en étais déjà persuadé par mes expériences précédentes, et cette journée vient comforter ce sentiment ! L’ “improvement game” et le “remember the future” ont permis en un peu plus de 2 heures, de consolider la vision de 40 personnes sur les actions à mettre en oeuvre sur un peu plus d’un an !

Contrairement à une journée d’équipe traditionnelle, nous finissons ici sur un plan d’action partagé, pour lequel les participants sont motivés.

Je ne vois pas comment une autre technique aurait permis cela !

Ce fut magique de voir les problématiques émerger de manière collaborative, pour devenir la base des ateliers suivants.

C’est cette magie de la collaboration qui remet au centre l’importance de la communication entre les gens. Tiens cela me rappelle un certain manifeste…

Alors convaincus ? Lancez-vous !

L’Agile par la pratique: une formation ludique et … efficace

Tags

, , ,

L’agilité est souvent mise en œuvre par les équipes, avant d’être adoptée par le management. Les premiers pas peuvent être effectués sous l’impulsion de développeurs motivés, ou de chefs de projets conscients de la force des équipes auto-organisées.

Mais rendre agile une organisation nécessite, au delà du charisme des agilitateurs – et des solutions efficaces qu’ils proposent – de former les équipes, d’abord les intervenants techniques, puis les interlocuteurs métiers. La communication ouverte et l’approche transdisciplinaire de l’agilité doivent alors être mise en place dès la genèse du projet. Mais comment former à la gestion de projets informatiques des participants de cultures techniques et professionnelles différentes ?

Le constat: rien de tel qu’une approche ludique et interactive pour mobiliser les équipes, surtout si elles sont hétérogènes et ne connaissent pas encore bien les principes de Scrum.

Une réponse: une journée d’initiation à SCRUM, animée comme un projet agile. La journée commence par un état des lieux permettant d’orienter la formation selon l’expérience des participants et les besoins métiers. Elle est ponctuée d’un ‘half-daily Scrum’ qui illustre la mêlée quotidienne et se conclue par une ‘démonstration’ maison et une rétrospective en bonne et due forme.

Différents ateliers permettent aux utilisateurs de vivre la création d’une équipe agile et d’appréhender le principe d’auto-organisation. La matinée se concentre sur la découverte des principes de bases de Scrum: le sprint, le planning, la rétrospective, les itérations et l’amélioration continue. L’après-midi permet d’explorer plus en profondeur les relations entre les intervenants des projets, le rôle du Product Owner et du Scrum Master, les interactions entre développeurs et fonctionnels.

L'Agile par la pratique: the Airplane Factory

L'Agile par la pratique: the Airplane Factory

Proxiad EST propose depuis mars de cette année une session de formation conçue selon ces principes : ‘SCRUM: méthodes agiles par la pratique’. Conçue pour des groupes de 5 à 20 personnes, elle donne aux participants une vision très précise du déroulement d’un projet agile, ainsi qu’une bonne connaissance des rôles des intervenants. Elle permet, en outre, une première prise de contact avec les équipes si celles ci s’engagent dans un accompagnement agile proprement dit.

DevoxxFR 2012 : autour de java

Tags

, , , , , , , , ,

Pour faire suite à mon précédent article centré sur les tests, vous trouverez dans ce post les sessions de ce DevoxxFR qui ont retenu mon attention autour du thème java et son écosystème.

Les 3 A pour Java EE 6

Cet atelier est  animé par Alexis Hassler (@AlexisHassler), Antoine Sabot-Durand (@antoine_sd), Yann Blazart (@yblazart). Il permet d’avancer pas à pas dans la mise en œuvre des principales spécifications de Java EE 6. Par le biais d’instructions fournies sous forme d’un fichier PDF, chacun avance à son rythme et fait évoluer une application existante en y intégrant différents éléments de la spécification. Ainsi, JSF2.0, JAX-RS 1.0, CDI 1.0 mais aussi Arquillian sont abordés. Ce dernier ne fait pas partie de la spécification mais est très utile pour réaliser des tests d’intégration directement dans le conteneur.

Au final, une session “les mains dans le cambouis” intéressante, qui permet d’aborder JEE6 concrètement. Le public en sort avec un exemple complet et  fonctionnel.

Vous pouvez retrouver l’atelier à l’adresse suivante : https://github.com/antoinesd/Labs-Java-EE-6.

Developing, Deploying and Scaling in the Cloud with Play par James Ward (@_JamesWard) et Nicolas Leroux (@nicolasleroux)

Il existe des différences majeures entre Play 1 et Play 2 :

  • l’accès aux données : Ebean pour java,  Anorm pour Scala
  • les vues : par défaut les templates sont écrits en Scala ce qui permet d’avoir un typage fort dans les vues
  • les assets : en matière de CSS et Javascript, Play 2 propose de gérer nativement le code Less ou Coffescript
  • distribution des traitements avec Akka et le modèle d’Actor

Après la présentation des nouveautés, James et Nicolas déroulent une démo les mettant en œuvre.

Au final, je reste un peu sur ma faim, la démo aurait mérité d’être  plus poussée afin de mettre le framework vraiment en valeur.

Il reste qu’une vraie plongée dans Scala semble nécessaire afin de tirer parti au mieux de cette version 2 de Play.

CRaSH un shell pour étendre la plateforme Java par Julien Viet (@julienviet)

CRaSH est un shell  interactif pour la JVM, open source.

Grâce aux commandes  écrites en Groovy, Julien nous démontre qu’il est très facile d’interagir avec une JVM.  Se connecter à une JVM sur laquelle tourne un JBOSS, changer à chaud le niveau de logs, voir les pools JDBC, et  accéder aux indicateurs JMX est relativement aisé.

Ce qui fait également la puissance de CRaSH c’est la possibilité d’extension de la JVM en créant ses propres commandes.

Un outil intéressant, à avoir dans sa caisse à outils.

Changeons la conception de nos applications grâces aux services cloud par Cyrille Le Clerc (@cyrilleleclerc)

L’idée de cette session est de montrer qu’il est possible de mettre en ligne une application web en 3 mois et de l’exploiter simplement avec des Devs, pas d’Ops et surtout pas de serveurs.

Après un bref retour sur ce qu’est le Cloud, Cyril passe aux critères de sélection des différents services nécessaires, hébergement, base NoSql, stockage de fichiers, recherche Full Text, Email as a service, Captcha, monitoring. Tous ces services existent en ligne et pour environ 600€ par mois, Cyril montre qu’il est possible d’avoir une application opérationnelle et parfaitement scalable. Je retiens que pour un passage full Cloud, il y a  certains points à aborder avec attention :

  • pour la performance, la co-location de certains services est importante
  • les informations de fiabilité sont accessibles de façon transparente, chaque site propose sa page “health dashboard”
  • l’aspect juridique est important : en fonction de la localisation des services, le droit s’appliquant peut être très différent du droit français. La certification SAFEHARBOR est un gage de sécurité
  • sécurité : là il y a perte de la profondeur de sécurité d’un SI classique, tous les serveurs sont accessibles depuis le web
  • la tarification est difficile à prévoir, il faut faire attention aux offres non bornées

An overview of Guava: Google Core Libraries of Java

Session intéressante même si sur la forme elle s’apparente à un listing des fonctionnalités de la bibliothèque. Malgré tout Guava mérite vraiment qu’on y prêtre le plus grand intérêt.

Optimiser votre site web sur mobile par Romain Maton (@rmat0n)

Romain revient sur le fait qu’un site web, doit avoir sa propre version mobile. Il débute en présentant plusieurs sites non adaptés aux mobiles. Puis nous propose un certain nombre d’éléments à mettre en œuvre pour aboutir à un résultat optimal sur mobile.

Difficile de vous restituer la multitude de conseils promulgués par Romain. Dès qu’elle sera disponible, je vous invite à voir absolument cette session  sur Parleys.

Nouveau Look pour une nouvelle Vie: Spring, JQuery et HTML5 par Julien Dubois (@juliendubois)

Julien nous présente Tatami, un Twitter d’entreprise.

Il nous détaille les briques technologiques qui composent Tatami et leurs principaux intérêts. HTML5 (Gestion des formulaires, local storage, CSS3),  Jquery, Twitter Boostrap, Less CSS, Spring MVC Rest, Spring mobile, Phonegap (Apache Cordova), et NoSql /Cassandra.

Session intéressante même si le test de montée en charge face à l’application exemple de Play2  couplé à une base embarquée me semble discutable.

Bilan

Pour ma part j’ai achevé ces 3 jours à Paris avec un grand sourire, regonflé à bloc et avec déjà un œil tourné vers la session 2013.

Un grand merci à toute l’équipe DevoxxFR.

devoxxfr_3

Photo du site Devoxx France

DevoxxFR 2012 : du nouveau sur les tests

Tags

, , , , , , , , ,

Dans mon billet précédent, je relatais les sessions de ce DevoxxFR qui m’ont le plus marqué par leur originalité. Je vais maintenant revenir sur les quelques sessions qui concernaient les outils de tests.
Le dernier article de cette série traitera des sessions liées à Java et à son écosystème.

Selenium 2, Selenium Grid et TestNG par Mathilde Lemee (@MathildeLemee)
Mathilde nous présente l’intérêt de Selenium2 pour automatiser les tests IHM. Elle déconseille l’utilisation de Selenium IDE, mais encourage à écrire directement les scénarios en Java, la syntaxe étant relativement simple. Après une présentation des avantages de TestNG comparé à Junit (groupes de tests, dépendances de tests, listeners, tests paramétrés), Mathilde met le doigt sur le point noir des tests sous Selenium : la lenteur d’exécution.
Une solution pour pallier à ce problème est de mettre en place Selenium Grid. Cet outil permet de lancer les tests en parallèle, pourquoi pas sur des VM différentes, avec des OS et browser différents voir même sur le cloud avec Azamon EC2 par exemple.
Une présentation de 30 minutes rondement menée, le tiercé Selenium 2, Test NG et Selenium grid semble pertinent pour maintenir une suite de tests d’intégration opérationnelle.

Réaliser des tests de charges avec Gatling
Cette session est animée par Stéphane Landelle (@slandelle) et Romain Sertelon (@BluePyth) principaux acteurs du projet Gatling.
Gatling est un outil de tests de charge nouvelle génération qui veut rompre avec le modèle classique 1 user = 1 thread. Open source, basé sur Scala, Akka, Netty, l’outil dispose d’un DSL Scala, qui semble accessible avec un peu de pratique. Cerise sur le gâteau, les rapports générés sont visuellement plutôt sympas.
L’outil est encore jeune, mais mérite qu’on y prête attention.

FluentLenium, une autre façon de faire Selenium par Mathilde Lemee (@MathildeLemee)
FluentLenium, est un framework au dessus de Selenium. Il propose un DSL fluide qui augmente la productivité dans l’écriture de tests d’intégration basé sur Selenium. Il permet également la mise en œuvre simple du pattern Page Object Pattern gage d’une meilleure maintenabilité des suites de tests. Il s’intègre très bien avec les bibliothèques d’assertion comme JUnit assertion, Hamcrest ou encore Fest Assert.

Chouchoutez votre code javascript par Romain Linsolas (@romaintaz)
Romain nous montre que faire des tests en javascript, les automatiser et analyser les code javascript, c’est possible avec les mêmes outils que dans l’écosystème Java, à savoir Maven, Sonar, Jenkins. Sur la base du code de la librairie underscore.js, Romain met en place un certain nombre de tests grâce à la librairie orienté BDD (Behavior Driven Development) Jasmine. L’analyse de code et la couverture se font via Sonar ainsi que la librairie js-test-driver.
Encore une très bonne présentation, avec une vraie démo qui fonctionne et un environnement dans lequel le développeur Java se sent comme chez lui.

DevoxxFR 2012 : les sessions décalées

Tags

, , ,

devoxxfr_0

Les 18, 19 et 20 Avril dernier j’ai eu la chance de participer à DevoxxFR (déclinaison francophone de Devoxx).

Avec plus de 1200 inscrits, 199 intervenants et 133 sessions, c’est la conférence pour développeurs de ce début d’année.

Cette cuvée 2012 se décline sur 4 grands thèmes, Web, Mobile et le Cloud, Langages alternatifs sur la JVM, Entreprises et pratiques, Java, Java EE et Architectures.

En quelques mots, ce cru DevoxxFR 2012 fût vraiment excellent !
Si vous avez l’occasion d’assister à ce genre d’évènement, foncez sans hésitez.

A travers une série de 3 articles, je vais tenter de vous transmettre l’intérêt et le plaisir que j’ai eu à assister à cette conférence.
Pour ce premier billet, je reviendrai sur les sessions qui ont attiré mon attention par leur originalité.
Le second article sera centré sur le thème des tests.
Pour le troisième et dernier je reviendrai sur les sessions touchant à java et son écosystème.

Fier d’être développeur par Pierre Pezziardi (@ppezziardi)
Je retiens de cette keynote les points suivants (pas forcément dans l’ordre) : egoless programming manifesto; un développeur n’est pas son code et un avis critique sur son code n’est pas une critique de sa propre personne; il faut regarder au-delà de l’intérêt technique du code pour comprendre sa valeur métier et donc son intérêt pour l’entreprise; le step by step, les cycles courts et les delivery rapides débouchent souvent sur de très bons résultats.

Heaven And Hell par Ben Evans (@kittylyst) et Martijn Veburg (@karianna)
Une keynote pleine d’humour, qui propose les possibles avenirs de la plateforme java. D’abord une vision du monde idyllique dans laquelle java est le n°1 des langages, ou l’avenir est radieux. Puis passage au côté obscur, les speakers se transforment, lunettes noires, blouson de cuir, java est victime de sa complexité, les développeurs fuient pour la plateforme .Net.
L’avenir de java et de sa JVM est incertain, il est pleinement lié aux  développeurs et à leur manière de s’investir sur les nouvelles versions de la plateforme.

Portrait du développeur en the Artist par Patrick Chanezon (@chanezon)
Sur fond d’image du film the Artist, Patrick nous raconte l’histoire de Georges. Développeur depuis 3 ans, il est catapulté chef de projet.
Georges rédige des spécifications interminables, les développements s’éternisent et la complexité de l’application le dépasse complètement. Elle passe en production, ne répond pas au besoin, les utilisateurs la détestent.

Georges est promu directeur de projet. Il se met au golf, fait de l’architecture sur papier et ne code plus.
Mais Georges s’ennuie dans son boulot, il a des équipes de 30 développeurs, fait une release tous les 3 ans, ses applications sont énormes, inmaintenables et ne fonctionnent pas.
Georges s’effondre, il déprime, se sent inutile et finit par se faire virer.

Patrick nous présente alors l‘évolution du monde de l’informatique pendant que Georges jouait au golf : les mainframes, le client-server, le web, le cloud et le mobile.

Georges se ressaisit, il remet les mains dans le cambouis. Il va à une soirée du ParisJUG, il découvre Scala, Html5, NodeJS. Il retrouve l’appétit, il code chez lui, se met à l’open source et lit beaucoup. Les recruteurs se l’arrachent, il code tous les jours, fait des tests, des tests et encore des tests; il pousse du code en prod toutes les heures et son appli mobile a 10 millions d’utilisateurs. Bref Georges est heureux dans son boulot, sa carrière redécolle. Il est fier d’être développeur.
La morale de cette histoire toute en humour est que pour rester performant, il faut rester proche de la technique et toujours rester en veille face aux nouvelles technologies.

Comment tester son idée et concevoir un prototype web en un minimum de temps par Camille Roux (@camilleroux)
Je retiens cette formule choc, Une idée n’a pas de valeur (tout le monde a des idées), c’est sa réalisation, sa mise en œuvre qui a de la valeur.
Pour démarrer, Camille liste quelques petites phrases souvent prononcées à propos d’idées qui n’ont pas abouties : “j’ai ça dans les cartons”, “je finirai plus tard”, “le marché n’est pas prêt”, “je ne comprends pas pourquoi ça n’a pas marché”.
Camille déroule ensuite, sur fond de Lean Startup, les steps permettant de concrétiser une idée.
Je retiens les étapes suivantes :

  • le Lean Canvas, sorte de tableau de bord qui permet d’avoir une carte précise de l’idée à mettre en œuvre
Lean Canvas

Lean Canvas

  • Communiquer, échanger, se faire aider : ne pas hésiter à faire des interviews, un article sur un blog, contacter un expert, créer des questionnaires, une landing page, bref utiliser tout ce qui est à disposition pour avoir un maximum de retours à propos de notre idée. Ceci permettra de la valider. D’après Camille il est rare qu’une idée soit complètement mauvaise, par contre très souvent elle mérite de mûrir, d’être affinée et d’évoluer.
  • Réfléchir à la monétisation. Il est difficile de faire évoluer un service gratuit vers un service payant, Camille conseille le cas échéant de partir directement sur un service payant.
  • Le prototype est la dernière étape. Pour les aspects techniques, il faut un framework de développement rapide. Camille nous parle de ROR (Ruby on Rails), du côté de l’écosystème java nous pourrons penser à PlayFramework, Grails ou pourquoi pas Spring Roo.

Une session vraiment excellente, pleine de trucs et astuces, à revoir rapidement sur Parleys dès que disponible.

CodeStory
CodeStory c’est l’ovni de ce DevoxxFR. CodeStory c’est d’abord l’idée de David Gageot (@dgageot) et Jean-Laurent Morlhon (@morlhon) qui souhaitaient proposer à Devoxx FR une session de coding live sur 2 jours. Ils sont accompagnés de Eric (@ericlemerdy) et Sebastian (@seblm) LeMerdy, grands gagnants du concours CodeStory.

L’application développée est une sorte de timeline d’un projet. On y retrouve les faits marquants du projet, les différents commits, différents badges comme le plus gros commiter, celui qui casse le plus le build, etc. Cette application se connectera donc à GitHub, à Jenkins, et pourquoi pas à Trello pour récupérer ces métriques.

L’équipe est décomposée en 2 binômes. Le binôme Front dont l’écran est projeté pour le public, décrit son travail à voix haute et échange en live avec la salle. Le binôme Back, avance dans les développements sans perturbation extérieure. Les sessions de coding durent 55 min. 5 min de Stand up meeting (description de l’avancement du projet et de ce que chaque équipe va faire), 20 min de code, changement de binômes, puis 20 nouvelles minutes de code, enfin 10 min de questions réponses avec l’assistance.
Le nombre de bibliothèques utilisées est impressionnant :

  • Coté serveur : Lombok, Guava, Jersey, Jackson, Gson, librairie Github client
  • Browser : JQuery, Mustache, Less, Html 5
  • Infra : Github Enterprise, Jenkins, Sonar, Git, GRowl, IntelliJ Idea, Infinitest, Maven
  • Tests : Zombie.js, Mocha, Mockito, Fest Assert, Rest Assured.

Assister à CodeStory est une expérience à part, outre la découverte de ces bibliothèques, on découvre en live les bénéfices du TDD, la conception simple, le design émergent et l’intérêt du pair programming.
Vous pouvez retrouver les sources sur GitHub.

Les Cast Codeurs
Les cast coders est LE podcast java en français. Cette session était animée par Emmanuel Bernard (@emmanuelbernard), Antonio Goncalves (@agoncal), Arnaud Héritier (@aheritier), et Guillaume Laforge (@glaforge).
Après un retour sur cette session 2012 DevoxxFr, les duchess sont invitées à partager leurs retours, puis l’équipe de CodeStory. L’ambiance est difficile à retranscrire, le public est en feu, les speakers et speakeuses sont ovationnés. Vous pouvez vous plonger dans l’ambiance en retrouvant le podcast en ligne.

Pour terminer ce premier billet, je vais rapidement vous parler des BOF.
Un BOF (Bird of a Feather) est une session d’une heure, informelle et complètement interactive avec le public. Il n’y a pas de présentation au sens strict, mais plutôt des échanges continus entre intervenants et public.

BOF OSS en France usages et pratiques
La discussion démarre sur la question : L’âge moyen des acteurs de l’OSS augmente, comment convaincre les jeunes de mettre le pied à l’étrier ? Le fait est que les logiciels sont de plus en plus complexes et que le ticket d’entrée pour participer à un projet  est de plus en plus important.
S’en suit une discussion sur les licences OSS. Laquelle choisir ? Vaste sujet, chacun se retrouve sur le fait que le choix est spécifique au projet.

BOF de la communauté Software CrafmanShip Paris animé par Cyrille Martaire (@cyriux).
Cyrille revient rapidement sur l’histoire de la communauté parisienne.
S’en suit une discussion autour du sujet TDD : Comment convaincre et faire adhérer les membres d’une équipe ?
Une des réponses semble être d’apporter le TDD par petite touche et de mettre l’accent sur les pratiques de partage telles que coding dojo, randoris ou waza.
Toutes les sessions seront prochainement publiées sur Parleys, les interviews des différents intervenants sont déjà en ligne.

Photos de Salvador Diaz (@salvadordiaz) et slideshare.net.

Code retreat : de l’autre coté de la barrière !

Tags

, , ,

2011 a été une année particulière, vous avez certainement vu vos twitters s’agiter sur le tag #codeRetreat ! En apogée, le 3 décembre 2011, près de 80 villes ont contribué au Global day of Code Retreat.

En quelques mots, le code retreat a pour objectif de “lever la tête du guidon” et de poser la réflexion sur nos pratiques de codage. Le but est d’explorer des voies, des techniques, et non le livrable développé.

En complément des différents retours de la blogosphère et en prémisse du legacy code retreat du 12 mai à ProxiAD, je vous propose de découvrir l’événement, du point de vue du facilitateur. Je remercie Adrian Bolbocoa, de m’avoir offert cette possibilité !

TDD as if you meant it

Première session

La première session constitue l’échauffement. Aucune contrainte.
L’idée est de se plonger dans le problème : le Jeu de la vie (GameOfLife).

Après 45 minutes, un “delete your code now” résonne dans la salle, il est temps d’effacer son code.

Les réactions se font vives “Quoi !” “Comment ?”, “Mais on ne va jamais avancer si on efface tout à chaque fois”.
Les frustrations sont logiques, mais l’objectif n’est pas de terminer l’exercice. Il s’agit d’identifier ce qui nous a posé problème :

  • Trop court, mais pourquoi ?
  • On ne sait pas comment commencer, mais pourquoi ?
  • Je n’ai rien codé, mais pourquoi ?
  • Des difficultés avec l’IDE ? Une démarche peu efficace ? Un mauvais angle d’attaque? Le problème auquel nous nous sommes attelés était disproportionné ?

Lors de la rétrospective, le groupe est timide, la frustration est marquante.

Durant cette session nous avons remarqué que certains ne connaissent pas les techniques de test, que le code contient de la duplication, que les méthodes font plusieurs choses, et que finalement les discussions sont vives mais peu de code est écrit !

Session 2

Nous pouvons alors, soit améliorer les échanges au sein des binômes, par un pair programming game, ou introduire certaines guidelines de développement.

Nous optons pour la deuxième option avec “4 rules of design“.
1. Passes its tests
2. Minimizes duplication
3. Maximizes clarity
4. Has fewer elements

Nous aurions pu utiliser les principes SOLID que j’affectionne particulièrement, mais certains concepts impliquent une présentation plus poussée, ici nous cherchons à pratiquer.

Comme le font remarquer certains, ces éléments peuvent paraître dogmatiques, mais l’idée est de se questionner, de justifier ses choix, de prendre le sens du détail.
L’exemple typique est celui de l’interface IQuelquechose, ou des implémentations du style QuelqueChoseIMPL…

Pourquoi fait-on cela ? Est-ce que cela a un sens ?

Une autre dynamique se met en place, les gens se creusent la tête.
La session s’écoule, la rétrospective montre que certains participants lèvent le voile sur le “vrai” TDD.

Session 3

Nous observons toujours que les binômes ne “pair” pas vraiment, beaucoup de discussions, pas trop d’actions. Nous proposons alors les contraintes suivantes :

  • Ping-pong pair programming : une personne écrit un test qui échoue, l’autre le fait passer et ecrit un test qui échoue, et ainsi de suite.
  • No conditionals : ne pas utiliser de if/else
  • Silent programming : on ne doit pas parler
  • No loops : pas de boucles
  • Methods of 4 lines max : forcer à faire des méthodes qui ne font qu’une seule chose.

Les participants peuvent choisir une, plusieurs ou toutes les contraintes !
45 minutes plus tard, plusieurs des participants nous indiquent avoir apprécié le jeu de ping pong et comprendre la dynamique qui se cache derrière le TDD. C’est une première victoire, très satisfaisante !

D’autres se sont essayés au “no conditional”, et y ont réussi en remplaçant la comparaison par le dispatch [objet d’un futur article].

Il est temps de faire une pause. Les discussions animées me donne le sentiment que “la sauce a pris”.

Session 4

C’est avec le sourire que nous abordons l’après-midi. Les tests du matin étaient  plutôt lourds. Il est temps pour tout le monde d’apprendre à faire de plus petits pas : nous mettons en œuvre “Baby Steps”.
Nous nous reposons ici sur git, toutes les deux minutes, nous réinitialisons le code au dernier état du dépôt.
Si les travaux entrepris pendant n’ont pas permis d’aboutir à un test vert, il est perdu, sinon, il est commité.

45 minutes s’écoulent. Certains sont passés sur des intervalles de 5 minutes.
D’autres ont changé de stratégie et font de plus petites étapes.

Session 5

Nous pouvons maintenant attaquer les choses sérieuses, et faire l’atelier qui est généralement le plus perturbant : TDD as if you meant it !
L’idée est de focaliser sur le comportement et de s’abstraire de toute conception : L’implémentation doit se faire dans le test, toute extraction de méthode, création de classe ou autre doit se faire par refactoring.
Le plus perturbant est le démarrage : il faut trouver le “baby step” qui permet d’avancer.

Comme je l’imaginais, les participants sont face à leur première méthode de test, et il faut trouver le comportement qui ne soit ni trop simple ni trop compliqué.
Le point d’entrée de l’application d’une règle est assez simple, je guide donc certains des participants la dessus.

Voici 5 sessions écoulées et plusieurs propositions pour la dernière :
– 1 heure pour aller plus loin dans le développement et lever la frustration du “delete your code now”
– une session de 45 minutes pour introduire une 7ème session (le record est Madrid avec 9 sessions!)

L’avis général est de partir sur une session d’une heure, le sujet est libre, les personnes peuvent reprendre les contraintes de la journée.
Julien introduit Object calisthenics, et je vais prendre plaisir à coder avec lui sur cette session, sous l’œil attentif d’Adrian.

Rétrospective

Tout le monde a trouvé cette journée très riche en apprentissage, en découverte et sur le plan humain.
Beaucoup de langages (Ruby, SmallTalk, Php, Java, C#), et de pratiques différentes ont été utilisés. Ce sont autant de possibilités de découvrir, approfondir ou de prendre une bonne piqûre de rappel.

Beaucoup sont surpris de l’apport de cette journée, ou des réflexions qu’elle peut amener.
Certains comprennent la dynamique du TDD, pour d’autres la pratique paticulière « TDD as if you meant it » a livré ses secrets.
Beaucoup d’entre eux ont été perturbés, ou gardent une certaine frustration. Beaucoup sont prêts à modifier leur façon de travailler, et à mettre en œuvre ces pratiques dès le lundi suivant.
Des questions de fond sont toujours là : quand créer une classe ou non, …
La session git a convaincu, je pense que cette dernière sera une clef lors des autres code retreat ! Certains voient déjà l’intérêt d’utiliser les pomodoros dans cet esprit.

Merci Adrian et Erik pour cette trouvaille !

Retrouvez les photos ici : http://coderetreat.org/photo/photo/slideshow?albumId=6456126:Album:7620

Code Retreat Lille #2 : Retour d’expérience

Tags

, , , , ,

A l’instar d’un musicien qui doit pratiquer ses gammes entre deux concerts pour parfaire la maîtrise de son art, un développeur doit savoir “faire retraite” pour s’exercer à d’autres techniques et méthodologies que celles qu’il pratique quotidiennement.

C’est avec cette métaphore on-ne-peut-plus-compréhensible que les deux organisateurs, Jérémie Hattat et Adrian Bolboaca, nous ont présenté l’intérêt d’évènements tels que ce deuxième Code Retreat lillois, qui s’est déroulé samedi 14 janvier dans les locaux de Proxiad. Le programme de la journée s’est composé de :

  • 6 sessions de 45 minutes de programmation en binôme sur le thème du Jeu de la Vie, chacune devant nous pousser dans l’exploration par l’introduction de nouvelles contraintes,
  • Le langage d’implémentation était au choix de chaque binôme.
  • Chaque session était suivie d’une rétrospective commune, à la mode Agile, durant laquelle les participants exposaient leur approche du problème, leurs difficultés et progrès.

L’idée était bien entendu de partager les connaissances et de faire évoluer chacun, sans engager personne dans quelque compétition que ce soit.

L’intérêt de savoir implémenter le Jeu de la Vie ? Aucun.

Ce sujet était simplement l’occasion d’introduire, de pratiquer et d’expliquer les avantages du Test Driven Development (TDD) ou encore du Pair Programming ; de découvrir de nouveaux outils, tels que GIT, des trucs et astuces de développeurs ou un nouveau langage de programmation. Le but n’est pas de résoudre le problème mais bien de poser la question du cheminement ; l’important étant de progresser dans sa compréhension de ces méthodologies et de partager son expérience propre avec son binôme.

Plutôt que de vous les présenter de façon monolithique, je vais vous détailler chacune de mes sessions et l’évolution de la perception que j’en ai eu. Je ne prétends pas vous donner de réponse à toutes vos questions ni vous faire des révélations, mais simplement vous montrer la réflexion qui a été la mienne tout au long de cette journée afin de vous inciter à y participer, vous aussi.

Je préciserai simplement que c’était là mon premier Code Retreat et que je n’avais jamais pratiqué le TDD ni le Pair Programming auparavant. Je partais donc de zéro…

panoramique

1ère session : Pair-Programming … le Jeu de la Vie

Contraintes

Cette première session avait pour objectif de se familiariser avec les 4 règles principales du Jeu de la vie, mettant en scène des Cellules dans un Univers commun :

  1. Une cellule morte avec moins de trois voisins reste morte,
  2. Une cellule vivante avec moins de deux voisins meurt,
  3. Une cellule vivante avec plus de trois voisins meurt,
  4. Une cellule morte avec exactement trois voisins renaît.

4 règles basiques qui laissent cependant possibles des angles d’attaque très différents. L’idée était ainsi de les implémenter avec nos connaissances propres, sans contrainte particulière.

J’étais ici associé à un ami, d’un parcours très proche du mien. Lui non plus n’avait jamais réellement pratiqué le TDD ni le Pair Programming. Nous développions en Java, en utilisant JUnit.

Déroulement

En quelques mots échangés très rapidement en début de session, nous avons convenu d’une vision et d’une méthodologie commune :

  • Je me chargerais d’écrire le code  tandis que mon binôme se chargerait de réfléchir à l’étape suivante pour me guider dans ma réalisation. Je me chargeais donc de résoudre les problèmes techniques rencontrés sur le moment, tandis qu’il concevait la phase suivante et modélisait les règles,
  • Nous avons choisi comme approche de commencer par modéliser les Cellules et l’Univers qui les contient.

Les tests étaient en grande partie écrits avant d’implémenter le code, dans un esprit qui nous semblait proche du TDD, ce qui nous permettait de définir un contrat d’interface répondant exactement à nos besoins, sans fioriture inutile.

En 45 minutes, nous sommes arrivés à 100% de code implémenté… non fonctionnel. 2 bugs (trouvés par la suite entre deux sessions) nous ont empêché de faire le sans faute du point de vue réponse au besoin métier.

Rétrospective personnelle

Cette première session m’a permis de voir certaines choses :

  • 45 minutes pour une session, c’est court,
  • Le Pair Programming permet de confronter les idées (et donc éliminer les déchets), de définir un langage commun (permettant par exemple de mieux nommer les classes ou méthodes définies), de couvrir un périmètre fonctionnel et technique plus large car abordé de deux points de vue forcément différents. Le code s’en trouve donc plus qualitatif. En moins de 10 minutes on le comprend et, pourtant, il faut le pratiquer pour en prendre réellement conscience,
  • Sans se contraindre à des règles particulières dans l’écriture des tests, ces derniers ne couvrent pas nécessairement tout le périmètre fonctionnel et technique. Ils ont ainsi laissé échapper 2 bugs qui nous ont privé du plaisir de fournir une application en état de marche, même basique.

Rétrospective commune

Il a été très intéressant de constater les différentes approches proposées par les autres binômes. Tandis que le nôtre ne pouvait concevoir le Jeu de la Vie sans une série de bases mises en avant dans l’énoncé (comme la notion d’Univers ou de Cellules), d’autres binômes se sont orientés directement plus finement sur la notion de Cellules ou les règles régissant son cycle de vie. Adrian nous a expliqué connaître 18 approches différentes à ce problème…

Certains binômes ont passé du temps à discuter de chaque notion et de la façon de les modéliser : une Cellule peut-elle être morte ou vivante ? Ou une Cellule est-elle nécessairement vivante (une Cellule morte n’existant donc pas) ? Une Cellule est-elle une structure de données en soi ou simplement un booléen ?

Chaque vision est correcte. Aucune n’est meilleure qu’une autre. Aucun binôme n’a fourni une application totalement opérationnelle ; nous semblions être les plus avancés sur ce point.

2ème session : le TDD

Contraintes

La deuxième session avait pour objectif d’introduire les bases du TDD et de les mettre en application. Il convenait donc d’en respecter les règles de base :

  • On commence par écrire un test,
  • On ajoute les éléments qui permettent de compiler le code,
  • On vérifie que le test échoue,
  • On écrit l’implémentation qui permet de faire passer le test au vert,
  • On refactorise le code de test et/ou de production si possible.

Des éléments que j’avais déjà lus mais jamais pratiqués.

Déroulement

Pour cette session, je me suis associé à un développeur qui connaissait déjà le concept du TDD et du Pair Programming. Il m’a dès le départ proposé le principe du Ping-Pong :

  1. le premier développeur écrit le test, ajoute le code de production permettant uniquement de le compiler et vérifie qu’il ne passe pas,
  2. le second développeur implémente le code de production qui permet de le valider puis écrit à son tour un nouveau test avant de repasser le clavier au premier,
  3. Et ainsi de suite…

Chaque fois, celui qui n’a pas le clavier peut critiquer le code, signaler un oubli mais ne peut pas manipuler lui-même.

Nous étions là encore en Java et JUnit.

Rétrospective Personnelle

Il est assez déstabilisant d’avoir à côté de vous quelqu’un qui critique votre code en permanence. Non pas que ce soit frustrant ou vexant mais chacune des remarques, pertinentes, remettent en question votre façon d’aborder la problématique. Chacune d’entre elles vous oblige donc à prendre du recul en vous coupant dans votre élan mais influe directement sur la qualité du code que vous produisez. Si l’on est ouvert aux critiques, le code devient cependant rapidement plus clair et plus lisible et la perte de temps du moment est largement compensée par la suite. En vous obligeant à mieux nommer vos tests par exemple, votre binôme garantit que votre code pourra facilement être repris par un tiers.

Dans la série des petits trucs et astuces, mon binôme m’a proposé de toujours organiser mes tests avec les notions de “Given, When, Then”, en séparant chaque partie du test par un commentaire portant cette notion :

// Given
Univers univers = new Univers();
// When
univers.nextStep();
// Then
assertEquals(1, univers.getAliveCells());

La présence des commentaires délimitent clairement chaque partie du test par des informations compréhensibles de tous.

Durant cette session, nous avons de nouveau abordé la problématique du Jeu de la Vie du point de la Cellule, elle-même présente dans un Univers.

Cette session a notamment été l’occasion de découvrir l’intérêt des Code Retreat : le partage de connaissance entre les développeurs est un axe important de ce genre d’évènements. Et lorsque vous vous associez à un enseignant dans l’âme vous en ressortez nécessairement grandi. Merci Thierry (@teierii) !

Rétrospective Commune

Pas de remarque particulière.

3ème session : sans les mains !

Contraintes

La troisième session avait pour objectif de choisir nous-même des contraintes parmi :

  • Pair-Programming en Ping-Pong,
  • Pas d’instruction conditionnelle,
  • Pas de boucle,
  • Impossible de parler.

Nous avons choisi de nous tirer une balle dans le pied en choisissant les trois premières.

Déroulement

Je passerai vite sur cette session qui m’a majoritairement posé des problèmes sur la façon de structurer mon code en m’obligeant à penser différemment. Autant, se passer des boucles est relativement facile ; autant, se passer des instructions conditionnelles relève du casse-tête chinois. L’utilisation de l’opérateur ternaire a été une solution frôlant l’interdit mais finalement acceptée et utilisée ; il devient cependant très rapidement illisible. Le passage à l’héritage et à l’implémentation propre à chaque classe fille nous a semblé salvateur mais est venu trop tard dans la session pour être complètement mis en œuvre.

Rétrospective Personnelle

S’imposer des contraintes particulières sur le code est un excellent exercice pour découvrir d’autres façons d’implémenter un même comportement. Cela vous oblige clairement à avoir l’esprit ouvert aux différentes solutions et aiguise vos réflexes et connaissances de développeur en mettant en œuvre ou cherchant les patterns majeurs. Bien entendu, vous ne vous imposerez pas réellement de telles contraintes dans de véritables projets, mais acquérir ces réflexes de bonnes pratiques doit vous inciter à tendre directement vers le bon pattern, la bonne modélisation plutôt que de passer par des instructions, moins claires.

Là encore, le code en devient plus clair et plus lisible, donc plus maintenable.

Rétrospective Commune

Certains binômes ont été confrontés à des tests qu’ils ont écrits et qui, dès la première exécution, sont passés au vert sans passer par la case “échec” habituelle. Comment réagir dans ce cas ? Nos animateurs favoris répondent que si le test passe, il ne faut pas chercher à le faire échouer. Il faut bien entendu le vérifier mais un test qui passe du premier coup est généralement bon signe pour la suite.

4ème session : GIT

Contraintes

J’ai trouvé cette session un peu extraterrestre par rapport aux autres mais néanmoins particulièrement intéressante. Elle a surtout marqué un tournant dans mon approche du TDD, grâce à son objectif : se forcer à respecter des itérations extrêmement courtes (2 minutes) dans lesquelles il fallait :

  • Ecrire un test qui échoue,
  • Implémenter le code,
  • Faire passer le test,
  • Commiter le code à l’aide de GIT.

Déroulement

Je ne connaissais GIT que de nom et ne l’avais jamais manipulé. Je connaissais à peine ses grands points forts, que j’avais pu lire ici et là sur différents articles. Je me suis donc naturellement “binômé” avec un connaisseur de l’outil. Après avoir mis en place le dépôt local pour jouer le jeu des commits réguliers, nous avons pu commencer la session proprement dite.

Je me suis naturellement placé en tant que copilote et aie assisté mon binôme dans ses travaux. Impossible pour moi d’agir réellement sur le clavier, faute de connaître les commandes GIT. Parce que 2 minutes, c’est très court. Des itérations de cette durée nous montre à quel point notre connaissance des raccourcis clavier et la maîtrise de nos outils nous permet un gain de temps absolument phénoménal sur notre journée de travail.

Nous avons même “triché” en passant à des itérations de 3 minutes, qui nous ont laissé une chance d’avoir le temps de commiter (tout juste d’ailleurs).

Rétrospective Personnelle

GIT est magique. Il va falloir que je m’y intéresse sérieusement. La possibilité de switcher aussi facilement de branche dans le même répertoire m’a clairement bluffé ; de même que la simplicité de mise en œuvre de l’outil (je pense ici à l’initialisation du dépôt). Je n’ai bien entendu vu que la partie locale de l’outil, puisque nous n’avons pas partagé notre travail sur un dépôt commun, mais GIT gagne à être connu (ou, plus honnêtement, je gagnerai à connaître GIT).

Les itérations courtes ont clairement déclenché quelque chose dans mon esprit. Mon binôme n’était peut-être pas non plus étranger à l’affaire (Merci Guillaume (@guillaumewallet) pour tes explications avisées ! voir son article sur l’évènement). Impossible avec de telles itérations d’aborder les problématiques du Jeu de la Vie d’un point de vue entité métier, et donc classe. Il était absolument nécessaire de penser beaucoup plus atomique, de penser à la règle unitaire. C’est un exercice que je n’ai pas réussi,  la session étant trop courte pour que je puisse avoir le déclic et appliquer en même temps le concept. Mais les sessions suivantes, dont les contraintes s’enchaînent astucieusement pour nous mettre sur le bon chemin de la compréhension, me donneront l’occasion de me rattraper.

Rétrospective Commune

Lors de la rétrospective commune, Adrian nous a appris qu’il se forçait régulièrement à travailler par itérations d’environ 5 minutes, y compris dans son travail “réel”. Comme nous l’avions constaté, cela l’oblige à réduire son périmètre de réflexion et à se concentrer sur des éléments atomiques. Ses tests en sont plus précis, plus clair. Il committe ainsi toutes les 5 minutes. Etant donné que GIT oblige à saisir un message (tous les contrôles de sources devraient le faire par défaut), il signale qu’il est plus facile pour tous les développeurs de retrouver une modification particulière et de comprendre la raison d’un changement, plutôt que d’essayer de trouver la modification dans un lot beaucoup plus important.

Inversement, je lui demande ce qu’il en est lorsqu’il committe 100 fois par jour dans une équipe de 10 personnes. Le nombre de commits est alors conséquent et parcourir les X pages d’historiques n’est pas des plus engageant. Adrian convient que c’est un compromis à trouver,  mais m’apprend que GIT permet également de committer sur le dépôt central un ensemble de commits de son dépôt local, ce qui permet de grouper les modifications en une seule et sous un même message. Difficile de ne pas alors penser que l’on se retrouve dans un cas de commit d’un lot important de plusieurs fonctionnalités, les unes pouvant de nouveau se noyer dans les autres… Je me demande ce que cela vaut réellement en entreprise sur un projet réel…

dashboard1

5ème session : TDD “as if you meant it”

Contraintes

Cette nouvelle session avait pour objectif de continuer sur la lancée de l’écriture de tests orientés règles atomiques avec l’utilisation d’une méthodologie nommée “TDD as if you meant it” :

  1. Ecrire un seul test qui échoue,
  2. Faire passer le test en implémentant le nécessaire dans le test même,
  3. Déplacer l’implémentation de la règle dans :
    • Une nouvelle méthode,
    • Ou dans une méthode existante,
  4. Créer seulement de nouvelles méthodes dans la classe du test,
  5. Créer une nouvelle classe de production  seulement pour y placer une méthode existante provenant d’une classe de test,
  6. Faire le refactoring nécessaire,
  7. Revenir en étape (1).

Déroulement

Pour cette session, je me suis “re-binômé” avec mon ami de la première session, l’objectif étant de faire le point sur nos connaissances acquises séparément dans les sessions précédentes et d’en constater les impacts sur notre méthodologie.

D’un commun accord, nous sommes repartis sur le principe du Pair-Programming en Ping-Pong afin que nous ayons tous les deux le temps de mettre en œuvre la procédure.

Rétrospective Personnelle

J’ai toujours aimé suivre des procédures claires et nettes, quitte à en établir moi-même et à les faire appliquer à mon équipe si le contexte le permet. Cette procédure n’échappe pas à la règle. Elle est claire, précise et n’est pas soumise à l’interprétation. Le simple fait de la suivre garantit un minimum de succès. Le premier test prend nécessairement un peu de temps à écrire car il faut s’approprier la suite de règles mais celle-ci devient rapidement évidente car tout-à-fait logique.

Le déclic que j’ai eu lors de la session précédente s’est parfaitement adapté à cette méthode qui incite à tester une seule règle métier. Je me suis alors mis à voir les applications métier comme un repository de règles métier et non plus comme un package d’objets métier. Le concept d’orienté-objet, si chèrement prôné dans les différents cursus de formation, n’est plus une fin en soi mais un support permettant l’implémentation, l’organisation et la présentation de ces règles.

Seules comptent les règles en définitive.

Qu’importe réellement la notion de Client ou d’Adresse ? Ce qui compte, c’est avant tout ce qui fait la valeur ajoutée de l’application : son métier, c’est-à-dire ses règles. Bien entendu, la notion de structure est nécessaire pour véhiculer les données mais les voir comme autre chose qu’un moyen de transport revient à leur donner trop d’importance.

Cette prise de conscience m’a alors révélé tout l’intérêt de l’approche des BRMS, type Drools, que j’avais eu à manipuler de nombreux mois auparavant et dont j’étais resté totalement hermétique malgré tous mes efforts et ma prise de recul. Ces outils sont typiquement des banques de règles qui utilisent des structures pour véhiculer des données et non pas l’inverse. La logique et donc son approche sont différentes, voire déstabilisantes pour certains.

En suivant, cette méthodologie “TDD as if you meant it” au pied de la lettre, nous avons réussi à réécrire totalement différemment toutes les règles principales gérant le cycle de vie d’une Cellule dans le cadre du Jeu de la Vie… en une seule ligne !

Avec TDD "as if you meant it"

Avec TDD "as if you meant it"

En une seule ligne écrite logiquement et clairement, nous avons simulé le même comportement qu’une fonction de plus de 15 lignes obscures implémentées au cours de notre première session.

Sans TDD "as if you meant it"

Sans TDD "as if you meant it"

Le pouvoir de factorisation de cette méthode est très impressionnant ; d’autant plus que peu d’efforts sont requis pour le produire.

La seule difficulté que nous avons rencontrée a été de définir le prochain test que nous devions écrire. Je (nous ?) manque clairement d’expérience dans ce domaine pour arriver à circoncire de façon claire et nette la prochaine règle atomique à tester. Il faut pour cela pratiquer pour se déshabituer des règles de codage plus conventionnelles.

Rétrospective Commune

Pas de remarque particulière.

6ème session : a new beginning

Contraintes

As we want ! Le but ici est de faire le point ou revenir sur les différentes méthodologies de la journée qui nous ont marquées, interrogées, laissées pantois.

Déroulement

On ne change pas une équipe qui gagne. Notre binôme fétiche est reparti pour un tour afin de tenter l’implémentation complète de l’application en pur TDD, histoire de boucler la boucle…

Rétrospective Personnelle

… bon, ok. On n’a pas réussi. La fatigue aidant (la journée a duré près de 9 heures pendant lesquelles l’attention et l’apprentissage intensifs ont eu raison de nous), nous n’avons pas réussi à être suffisamment rapides pour tout implémenter. Mais la voie était la bonne…

Rétrospective Générale de la journée

Premier Code Retreat.

Je n’ai pas été déçu par la formule…

Je pensais trouver un animateur présentant les grandes lignes à l’aide d’un PowerPoint et nous laissant trouver notre chemin seuls sur notre ordinateur (un souvenir de certains cours peut-être). J’ai trouvé deux animateurs impliqués, riches en conseils, donnant les pistes pour nous permettre de cheminer nous-même à travers nos questions sans jamais donner directement les réponses. J’ai trouvé des binômes soucieux de partager, clairement habitués à l’exercice, n’hésitant pas à consacrer une partie de la session aux explications, toujours avec humilité.

La formule est tout simplement excellente. Si les participants sont toujours de cette qualité, ce genre d’évènements ne peut que contribuer à vous faire progresser et vous enrichir techniquement et humainement.

Première mise en pratique du TDD.

Comme je le partageais lors de notre rétrospective finale, j’ai pris une grande claque.

Je ne connaissais qu’une seule façon d’aborder l’implémentation, celle que l’on m’a apprise, que j’ai perfectionnée en pratiquant : on modélise les objets métiers, on refactorise pour respecter les patterns, on implémente le code de production et on vérifie que tout fonctionne en implémentant les tests.

Le TDD est clairement une approche totalement différente dont on ne peut comprendre les avantages qu’en le mettant réellement en pratique.

Il me reste cependant de nombreuses questions :

  • Nous n’avons vu que comment ajouter de nouveaux tests et du nouveau code de production. Comment doit-on procéder lorsqu’il s’agit de retirer du code ou de refondre une application existante écrite en TDD ? Y a-t-il également une méthodologie particulière à suivre ?
  • Le TDD tel que nous l’avons pratiqué part des règles métier pour ajouter au fur et à mesure les objets métier qui émergent. L’avantage est évidemment de n’avoir que ce qui est nécessaire mais, si l’on ne peut pas prévoir précisément ce dont on a besoin, comment estimer la durée d’implémentation de l’application ? Et, s’il n’est pas possible de faire d’estimation, comment faire pour gérer une équipe, estimer le budget nécessaire, les dates de livraison, … ? La réponse est-elle uniquement : le TDD ne se pratique qu’en mode Agile avec un client qui accepte ce principe de fonctionnement ? Il me manque des éléments pour répondre que seule l’expérience (la mienne ou celle des autres) peut apporter. Un avis sur la question ?
  • Quid du fonctionnement global de GIT, des repositories communs ? Il est assez facile de répondre à cela : il suffit de télécharger l’outil et de pratiquer un peu chez soi 🙂

Pour conclure, une très belle journée que ce Code Retreat. Un joli moment de partage et de découverte. Un grand merci aux organisateurs, Jérémie et Adrian, en souhaitant que ces évènements se multiplient et que la communauté lilloise se développe et s’anime d’autant plus !

Voici des photos de l’évènement :

Une journée agile à Lille

Tags

, , , ,

Agile Tour Lille 2011

Agile Tour Lille 2011

Le 10 Novembre 2010 s’est déroulé l’Agile Tour de Lille avec plus de 150 inscrits au sein d’Euratechnologies, cadre adéquat pour cette journée.

Au programme, pas moins de 3 Tracks, 16 sessions et 4 ateliers pratiques.

Les hostilités sont ouvertes par une courte intervention des organisateurs (Christophe Leroy, Julien Jakubowski, Thomas Clavier, Jérémie Hattat) précisant le déroulement de la journée. Après un rapide mot des sponsors de l’évènement : Octo, Cap Gemini, Efidev et Proxiad, s’en suit une petite nouveauté à l’Agile Tour Lille, le ch’Teaser. Chaque speaker présente sa session pendant 60 secondes afin d’allécher ses futurs auditeurs. C’est une idée très sympa,  certains Teaser sont pleins d’humour, la journée démarre donc sous les meilleurs hospices.

Et c’est parti !

Première session de la journée avec Pourquoi, où et comment les méthodes agile marchent ? par Pascal Van Cauwenberghe.

Pascal Van Cauwenberghe : Pourquoi, où et comment les méthodes agile marchent ?

Pascal Van Cauwenberghe : Pourquoi, où et comment les méthodes agile marchent ?

A travers six éléments essentiels (Théorie des contraintes, Reals options, Définir la valeur économique, Autonomie de l’équipe et du management, Excellence Technique, Systems Thinking), pascal nous guide vers la mise en place d’un environnement de travail agile / lean.

Une présentation intéressante, ponctuée d’histoires belges et donnant quelques recettes pour améliorer l’organisation et la gestion de son projet.

Seconde session de la journée, Optimisation de performances : une expérience agile (ADEO) par Nicolas Debaes

Nicolas Debaes: Optimisation de performances

Nicolas Debaes: Optimisation de performances

Après avoir décrit la mise en oeuvre de ce projet ambitieux étalé sur 4 mois  et composé d’une équipe d’experts, Nicolas nous présente les pratiques agiles qui ont permis à ce projet d’aboutir à un succès. Une présentation agréable, basée sur un sujet dédié à part entière à la performance, ce qui est peu courant.

Pour terminer cette matinée Améliorez votre Kanban ! par Jonathan Scher.

Dans cette session, à partir d’une version basique, Johnathan nous propose 10 étapes pas à pas pour étendre et améliorer notre  dashboard.

Ces différentes étapes (Aucune tâche technique, Petites et priorisées, Définition du fini fini, Bac rouge, Plus de colonnes, Plus de colonnes (encore une fois), Cumulative Flow Diagrams, Limiter l’en-cours, Plusieurs lignes et  Une ligne en Or) débouchent sur un kanban complet ou les informations pertinentes du projet sont rapidement identifiables et accessibles.

Cette session très dynamique permet d’appréhender Kanban et de repartir avec de bonnes pistes pour améliorer le dashboard de mon projet de TMA avec par exemple la ligne en or ou le bac rouge.

Midi déjà, tout le monde se retrouve dans la salle d’accueil pour échanger autour des sessions du matin en grignotant un morceau.

L’après-midi démarre comme le matin, avec les teasers des sessions à venir, là encore le choix est difficile.

Première session de l’après-midi, l’Agilité situationnelle par Claude Aubry.

Claude Aubry : Agilité situationnelle

Claude Aubry : Agilité situationnelle

Claude, au travers de la description de 4 projets nous montre que la plupart des pratiques agiles sont utiles pour les projets mais qu’elles nécessitent parfois des adaptations et que leur mise en oeuvre dépend toujours du contexte.

Session intéressante qui apporte une vision sur le fait que chaque projet a ses propres spécificités, que les pratiques agiles ne s’appliquent pas selon des règles figées dans le marbre et que tout est question de contexte.

S’en suivent 2 ateliers pratiques particulièrement intéressants :

Innovations Games® et Rétrospective par Guillaume Lours

Atelier story map, là où tout commence par Brieuc Le Marec et Olivier Pizzato

On démarre avec Innovations Games et Rétrospective.

Sur la base du livre Innovations Games de Luke HOHMANN, Guillaume nous présente ces jeux qui sont des jeux sérieux (serious games), favorisant la collaboration avec les clients, pour mieux comprendre leurs besoins. Au nombre de 13, ces jeux ont chacun un but précis: identifier les fonctionnalités les plus funs d’un produit, connaître la définition du succès de votre produit pour vos clients ou encore comprendre quand et comment votre produit est utilisé.

Guillaume nous propose ensuite de mettre en œuvre le jeu Speed Boat. Celui-ci a pour but de mettre en avant ce que les clients aiment ou n’aiment pas dans le produit. Le sujet pour ce Speed Boat est bien sûr l’Agile Tour Lille 2011. Deux équipes sont alors composées et quelques secondes plus tard, deux magnifiques bateaux émergent sur les tableaux blancs.

Première étape, recenser les aspects négatifs du produit. Ceux ci seront matérialisés par des ancres freinant le bateau. Puis identifier les points positifs matérialisés par des moteurs qui permettent au bateau d’avancer. Seconde étape, tenter de regrouper les ancres qui peuvent l’être et pour chacune d’elle définir une sévérité et une priorité pour la solutionner. A l’issue de l’exercice, les résultats sont analysés et présentés à tous.

C’est un exercice vraiment intéressant, il permet en moins d’une heure d’avoir un retour clair sur la vision que les participants ont du produit. Il permettra de déterminer et prioriser les futures actions à mettre en œuvre sur le projet.


SpeedBoat AT Lille 2011

SpeedBoat Agile Tour Lille 2011


2ème atelier de l’après-midi: Story Map, là où tout commence

La session démarre par une présentation de l’atelier et de ce qu’est une story map.

La story map d’un produit est la représentation sous forme de carte de l’ensemble des fonctionnalités du produit.

Quelques volontaires présentent une idée de produit pour lesquels une story map sera construite durant l’atelier. Après que chacun ai choisit le produit sur lequel il veut travailler, l’exercice démarre.

La création de la story map se fait par étapes. D’abord le sponsor partage sa vision du produit, puis tous les acteurs qui interagissent sur le produit sont identifiés. On passe ensuite à l’étape identification des activités en rapport avec le produit. Enfin il faut déterminer l’ensemble des cas d’utilisation du produit pour chacune des activités des acteurs, puis les prioriser (indispensable, fonctionnalité de ‘luxe’, etc …). Au fur et à mesure, les étapes s’enrichissent mutuellement.

A l’issue de l’exercice une revue complète de l’ensemble est effectuée afin de vérifier la bonne compréhension de chacun et d’identifier le chemin critique.

S’en suit un débat intéressant sur l’apport de cet atelier, la manière de le mener et qui doit y participer. Au final, cet exercice permet en très peu de temps d’avoir une idée assez précise des fonctionnalités que devra proposer le produit et de leur importance.

La fin de cet Agile Tour 2011 approche, Laurent Bossavit se charge de la keynote de clôture. Il nous emmène dans le futur tenter de découvrir l’avenir de l’agile et nous parle de la difficulté de faire de bonnes prévisions.

La journée se termine comme il se doit dans le nord autour d’une bière (ou deux) et de quelques petits fours.

Ce fut une journée bien remplie. Grâce à une organisation sans faille, une  infrastructure adaptée et des sessions et speakers des plus intéressants. L’agile tour fut pour moi une journée passionnante. Je quitte Euratechnologie enchanté par les sessions auxquelles j’ai participé, ravi d’avoir rencontré des personnes enthousiastes, pointues et motivées. Je repars en prime avec un bon lot d’idées à mettre en œuvre sur mes projets.

Un grand merci donc aux organisateurs, sponsors et speakers !

PS : Les sessions magistrales seront accessibles prochainement en vidéos, stay tuned 🙂