Bienvenue sur Développement Agile

Référence sur le développement logiciel Agile. Nous traitons de conception, de programmation, de pratiques de génie logiciel, d'essais et d'autres sujets connexes.

Une firme de service-conseils TI pas comme les autres

Publié par Louis-Philippe Carignan le mercredi 22 mai 2013 à 10:00

En avril 2012, Infoq.com a publié la liste des 20 personnes les plus influentes en Agilité. En 20ième position, on retrouve Henrick Kniberg, un suédois dont la biographie mérite d’être lue avant de continuer à lire ce billet. Il est aussi co-propriétaire de Crisp, une petite firme de consultants en technologie de l’information en Suède.

En mai 2010, Henrik a publié un billet à propos de Crisp où il raconte comment ils ont découvert leur identité. Pendant des années, il trouvait que leurs rencontres de compagnie biannuelles ne donnaient pas les résultats escomptés. 

"Every conference we would spend lots of effort around a big conference room table attempting to define these things, but the only results would be a bunch of wiki pages (our intranet) with lots of different options and ideas. No clear decisions."

Une année, Henrik a donc emprunté une approche différente pour identifier leur vision. Il a fait les étapes suivantes:

  • Découvrir leur vision et la mettre en mots.
  • Rendre la vision physique.
  • Dessiner avec des crayons de plomb puisque la vision n’est jamais finale.
  • Limiter l’espace pour se forcer à choisir les bons mots.
  • L’afficher partout.
  • Obtenir l’approbation de tous.

Comparativement à d’autres organisations qui font un exercice similaire, le résultat de cette expérience a fait son bout de chemin au travers le temps. Une fois leur identité découverte avec cette vision en dessins, des éléments intéressants en ont découlé. Voici ce qu’Henrik raconte sur son blogue

Indice du bonheur – version Crisp

Maintenant outillé avec leur vision sous forme de dessins, Crisp a mis sur pied l’indice du bonheur, une simple feuille de calcul sur Google Spreadsheet qui mesure, de 1 à 5, le niveau de bonheur de chaque personne à chaque mois.

On y trace un graphique mensuel où on fait la moyenne de cet indice. Si le graphique montre une courbe négative, les gens deviennent alors concernés et travaillent ensemble pour résoudre ce qui irritent leurs collègues.

 

Voici le constat d’Henrik par rapport à cette mesure :

"Crisp Happiness Index is more important than any financial metric, not only because it visualizes the aspect that matters most to us, but also because it is a leading indicator, which makes us agile. Most financial metrics are trailing indicators, making it hard to react to change in time."

Leur indice du bonheur est un bon indicateur puisqu’il donne un aperçu de ce qui va se produire dans la compagnie. En étant heureux chez Crisp, les employés rendront heureux leurs clients. Henrik fait le constat que les indicateurs financiers sont en arrière (lagging) puisqu’ils donnent une lecture après qu’une prestation de service ait été faite chez un client.

La valeur des actions chez Crisp

Leur indice du bonheur a permis une autre prise de conscience aux employés de Crisp:

"As a result of understanding our own values better, we’ve dramatically changed our partnership contract between Crisp stock owners. We’ve literally made our own stock worthless (at least from a pure monetary perspective)"

Vous avez bien lu. Leurs actions ne valent plus rien sur le plan monétaire. Ils ne veulent pas être une firme pour enrichir les actionnaires. Ils veulent être une maison pour les consultants en technologie de l’information.

Il est d’ailleurs dommage qu’il n’explique pas en détails ce volet. Je serais curieux de connaître comment Crisp gère sa comptabilité, paie ses impôts ou si un partage de revenus annuel est fait.

Et leur plan pour gérer la croissance

En continuant la lecture de l’article, on apprend que pour eux, la croissance de l’entreprise n’est tout simplement pas un paramètre qu’ils désirent contrôler. Puisqu’ils s’identifient comme étant une maison pour consultants en TI, c’est plutôt leur indice du bonheur qui indiquer si leur croissance actuelle est plaisante (ou non). J'ai entendu plusieurs fois des gestionnaires expliqués comment la croissance était importante pour aller chercher de nouvelles opportunités d'affaires. Crisp a une vision tout à fait différente de la croissance. Elle n'est pas liée aux opportunités d'affaires mais à l'indice du bonheur de ses employés.   

En conclusion

Je vous invite à consulter les deux dessins qu’Henrik présente au début de son article. Il a traduit les mots en anglais pour faciliter notre compréhension. Le premier montre la maison des consultants avec les valeurs importantes à leurs yeux. Mais c’est le dessin à la deuxième page qui est plus révélateur à mon avis. L’image « What do we do with money? » est particulièrement intéressante ainsi que la mesure du bonheur à la gauche de la feuille. Si les employés sont heureux, leurs clients le seront tout autant.

Comme le dit si bien les Poppendieck dans leur troisième excellent livre « Leading Lean Software Development » à la page 198 à propos des entreprises dans l'économie du savoir :

"In knowledge work, success comes entirely from people and the system within which they work. Results are not the point. Developing the people and the system so that together they are capable of achieving successful results is the point."

La géolocalisation sur mobile avec HTML 5

Publié par Vincent Crépin le mercredi 8 mai 2013 à 20:43

Une des nouvelles fonctionnalités intéressantes que HTML 5 fournit  est la capacité de géo-localiser l’utilisateur peu importe la plateforme sur laquelle l’application s’exécute. Par exemple, dans un navigateur standard, l’adresse IP sera utilisée (ce qui est souvent très imprécis) mais sur un téléphone intelligent, le GPS sera utilisé s’il est disponible et activé. Cela se fait de façon transparente. Dans cet article, je m’attarderai à la géo-localisation sur les plateformes mobiles qui utilisent le GPS.

HTML 5 fournit deux fonctionnalités de géo-localisation : soit obtenir la position actuelle ou effectuer un suivi de la position dans le cas où la personne se déplace (watch). Dans les 2 cas, les données retournées sont sous la forme d’une position qui comprend les coordonnées géo-spatiales (longitude et latitude), la vitesse de déplacement, l’altitude et une précision de la position obtenue en mètres. Les exemples de code suivants illustrent la simplicité de cet API :

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition);
    } 
    else {
        x.innerHTML="Geolocation is not supported by this browser.";
    }
}

function showPosition(position) {
    x.innerHTML="Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude;
}

function geWatchLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.watchPosition(showWatchPosition);
    } else {
        x.innerHTML="Geolocation is not supported by this browser.";
    }
}
function showWatchPosition(position) {
    x.innerHTML="Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude;  
}

La première function (getLocation) invoque l’API asynchrone de géolocalisation (tout est asynchrone ou presque en Javascript…) et appelle notre function callback (showPosition) lorsqu’un résultat est disponible. Dans celle-ci, on affiche simplement les coordonnées obtenues (longitude et latitude dans un DIV. La deuxième fonction (watchLocation) se comporte de la même façon mais cela déclenche un traitement qui retourne une nouvelle position à environ toutes les secondes.  Le callback (showWatchPosition) est donc appelé à chaque fois.

Il est donc très facile avec ces données de tracer un parcours sur une carte en utilisant l’API de Google Maps qui ne nécessite aucune installation, seulement l’ajout d’une référence javascript:

<script type="text/javascript" 
src="https://maps.googleapis.com/maps/api/js?v=3&&libraries=geometry&sensor=true"> </script>

Une des applications que j’ai développées comportait justement ce besoin de suivre la route de l’utilisateur en temps réel et de la représenter sur une carte. Une première implémentation simple plaçait les points sur la carte et les reliait à l’aide d’une polyline (ligne droite entre deux points) ce qui est facilement supporté par Google Maps.

L’exemple de code suivant tiré de la documentation de Google démontre comment tracer une ligne sur la carte. Dans cet exemple, on construit un plan de vol fictif que l’on affiche sur une carte.

function initialize() {
  var myLatLng = new google.maps.LatLng(0, -180);
  var mapOptions = {
    zoom: 3,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };
  var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
  var flightPlanCoordinates = [
    new google.maps.LatLng(37.772323, -122.214897),
    new google.maps.LatLng(21.291982, -157.821856),
    new google.maps.LatLng(-18.142599, 178.431),
    new google.maps.LatLng(-27.46758, 153.027892)
  ];
  var flightPath = new google.maps.Polyline({
    path: flightPlanCoordinates,
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 2
  });
  flightPath.setMap(map);
}

On voit que pour tracer le parcours, il faut fournir une série de coordonnées géospatiales et construire une polyline avec ces coordonnées. On indique ensuite sur quelle carte (map) la ligne doit être tracée et cela se fait automatiquement comme la figure ci-dessous le démontre.

Cette implémentation de base comporte plusieurs problèmes. Ils concernent tous la précision de la route obtenue. Un des buts importants de cette fonctionnalité dans mon application est de calculer la distance parcourue. En utilisant des lignes droites entre les points, le nombre de points requis est très grand pour tenir compte des changements de direction. De plus, la précision des points obtenus par le GPS est très variable ce qui donne parfois des distances complètement erronées. J’ai donc dû utiliser des stratégies de filtration des points pour obtenir des données plus précises.

La première modification que j’ai apportée est de rejeter les points GPS qui comportent une précision trop faible (exemple : plus de 30 mètres). Cela a aidé un peu mais une bonne précision ne garantit pas la précision réelle du point parce que la précision obtenue du GPS peut être imprécise elle aussi!!!

La deuxième modification que j’ai apportée est d’utiliser le service de directions de Google (Direction Service). Celui-ci permet de tracer une route entre deux points en utilisant une carte routière et aussi d’obtenir la distance entre ces points. C’est déjà une amélioration considérable puisque les points utilisés par l’API se trouvent nécessairement sur une route. Donc en fournissant mes points GPS, le service de directions essaiera de trouver une route entre ces deux points même si les points ne sont pas exactement sur la route en question. Mon application en étant une de suivi routier, cela convient parfaitement. L’exemple de code suivant tiré de la documentation de Google illustre l’utilisation de cet API :

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  var chicago = new google.maps.LatLng(41.850033, -87.6500523);
  var mapOptions = {
    zoom:7,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: chicago
  }
  map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
  directionsDisplay.setMap(map);
}

function calcRoute() {
  var start = document.getElementById("start").value;
  var end = document.getElementById("end").value;
  var request = {
    origin:start,
    destination:end,
    travelMode: google.maps.TravelMode.DRIVING
  };
  directionsService.route(request, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(result);
    }
  });
}

En gros, on invoque cet API en lui spécifiant 2 points et il nous retourne une route qui tient compte des routes terrestres véritables pour aller du départ à la fin. L’objet directionsDisplay permet de tracer automatiquement cette route sur une carte sans avoir à traiter les points intermédiaires. Mais il est aussi possible de tracer nous même les points si on veut appliquer des traitements particuliers.

Mais cela ne s’est pas avéré suffisant pour répondre à mes besoins. Il peut en effet arriver que des points erronés se trouvent sur une route secondaire et le service de directions essaiera de trouver une route qui tient compte de cette route secondaire même si on ne l’a pas visitée réellement. Cela se produit surtout dans les quartiers résidentiels où les routes sont très rapprochées. J’ai donc dû ajouter un troisième correctif important. J’ai créé un algorithme de filtration assez simple : pour chaque point qui est fourni par le GPS, je calcule la distance linéaire et la distance obtenue du service de direction de Google et j’utilise la vitesse moyenne des 2 derniers points ainsi que le temps écoulé entre les deux. Je compare ces valeurs et si la valeur linéaire calculée est beaucoup plus grande que la valeur obtenue en tenant compte de la vitesse moyenne, je rejette simplement ce point. Cette stratégie a complètement éliminé les points qui se situent sur les routes secondaires puisque le temps requis pour parcourir cette distance serait beaucoup trop grand par rapport au temps réel.

Me restait un cas à régler. Si on fait du surplace pendant un certain temps (arrêt à une lumière par exemple), et que pendant ce temps on obtient un point sur une route secondaire, le temps écoulé pourrait permettre d’avoir parcouru cette fausse distance. J’ai donc finalement rejeté tous les points GPS pour lesquels la vitesse est très basse (ex : moins de 0,5 mètres par seconde).

En conservant tous les points retenus dans une base de données (voir le billet précédent sur ce sujet), il est possible de consulter les routes parcourues comme l’illustre la figure suivante :

 Geolocalisation-mobile-exemple

En conclusion, les outils de géo-localisation disponibles sur les plateformes mobiles avec HTML 5 sont très puissants mais il est nécessaire d’appliquer une certaine intelligence au traitement pour obtenir des données précises. Et cette expérimentation m’a amené à supposer que les compagnies telles que TomTom ou Garmin ont accès à des données satellites de grande qualité ou possèdent des algorithmes très élaborés.

Tester unitairement mon code Javascript? Oui c'est possible!

Publié par Vincent Crépin le jeudi 25 avril 2013 à 07:16

Dans mon billet précédent j'ai révélé quelques aspects importants mais souvent méconnus de Javascript. J'ai également présenté des façons de se prémunir contre certains comportements du langage qui peuvent parfois nous jouer de vilains tours. Aujourd'hui, je vous propose d'aborder l’importante question des tests.

Les applications html5 ont en commun de proposer un modèle d'interaction très riche avec l'utilisateur. Pour y arriver, on n'a généralement pas d'autre choix que d'amener sur le poste client beaucoup de logique d'affichage en utiliant Javascript. Et qui dit logique dit risque de mauvais comportement. Sans une stratégie de vérification adéquate il devient malheureusement trop facile d'introduire par inadvertance une problématique dans la couche de présentation et de rendre une fonctionnalité inutilisable.

Habituellement, les tests au niveau des interfaces utilisateurs sont surtout des tests d’acceptation. Cependant, il peut être complexe et coûteux de tenter de couvrir tout le code Javascript à l'aide de ce type d'essais. Aussi, comme développeur, il est toujours intéressant d'avoir une rétroaction rapide en cas de problème, chose qui est souvent plus difficle avec des tests d'acceptation.

Personnellement, j’ai utilisé un framework de tests appelé QUnit (dans la famille JQuery) qui permet de rouler des tests complets des fonctionnalités disponibles dans les pages. Ce qui est très intéressant avec cet outil est la possibilité de manipuler le DOM et d'appeler toute fonction Javascript disponible dans le contexte. Cela permet à un développeur d'appeler de façon unitaire chacune des fonctions qu'il implémente.

L’installation et l’utilisation de QUnit sont extrêmement simples, comme l’illustre le code suivant tiré du site de QUnit:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>QUnit Example</title>
  <link rel="stylesheet" href="/resources/qunit.css">
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>
  <script src="/resources/qunit.js"></script>
  <script src="/resources/tests.js"></script>
</body>
</html>

Voici le contenu de tests.js :

test( "simple test", function() {
      var value = "bonjour";
      equal( value, "bonjour", "Nous attendons la valeur bonjour" );
      });

Pour exécuter les tests, il s’agit simplement d’ouvrir le fichier html dans un navigateur et on obtient un résultat semblable à ce qui suit :

QUnit-basic-sample

Une fois que vous aurez procédé à quelques expérimentation avec QUnit, vous serez en mesure d'apprécier la capacité de celui-ci à garantir la coformité de la couche de logique de présentation de vos applications html5. L'outil supporte l'exécution des fonctions Javascript tout en permettant d'accéder et d'altérer le DOM, ce qui vous permet de simuler des cas assez complexes d'interaction. Avec un tel outil, il devient alors plus facile d'attraper les problématiques sans avoir à tester manuellement l'interaction avec votre application, surtout dans les cas limites (ceux que l'on oublie trop souvent de tester manuellement).

Un des principaux désavantage de ce type d'outil est que, par défaut, ces tests s’exécutent dans le navigateur et nécessitent donc certains ajustements pour être roulés dans un environnement d’intégration continue, mais c’est tout-à-fait faisable. Entre autres, PhantomJS permet de rouler les tests avec un navigateur headless. Un prochain bille fera état de la façon d'utiliser PhantomJS.

Références utiles

Voici quelques liens qui, je l'espère, vous permettront d'approfondir le sujet et de profiter vous aussi des bénéfices des tests unitaires avec Javascript.

La communication non-violente

Publié par Louis-Philippe Carignan le mercredi 24 avril 2013 à 15:50

Voici moi il y a quelques années: 

« Si tu n’écris pas tes tests avant ton code de production, ton code est à chier. »

J’entendais aussi cela des fois dans les équipes de développement sur lesquels j’étais assigné : 

« Tom est un mauvais programmeur » ou « Heille man, c’est à chier ce que tu fais »

Belle façon de communiquer non? Avec les années, cette façon de communiquer m’a mené plus d’une fois directement dans un mur. On m’a reproché à plusieurs reprises mon manque de tact et pour faire l’effort nécessaire afin de corriger ce défaut, j’ai découvert entre autre la communication non-violente

J’ai donc commencé à creuser le sujet pour apprendre à mieux communiquer sans blesser les autres. J’assistais aussi dernièrement à une réunion où les participants avaient reçu une formation sur ce sujet. Je pouvais voir que c’était difficile pour eux puisque c'était contre nature mais le message était mieux communiqué (à mon avis).  

En quelques lignes, la communication non-violente se décompose en trois parties :

  • Observations : Ce que j’observe ne contribue pas à mon bien-être.
  • Émotions : Comment je me sens face à ce que j’observe?
  • Besoins : Qu’est-ce que j’ai besoin pour me sentir mieux comme personne

Tout comme le fameux gabarit de la user story, on peut aussi se faire un gabarit pour la communication non-violente : 

« Quand je <observation>, je me sens <émotion> puisque j’ai <besoin>. ».

Une fois que ces trois étapes sont formulées en une phrase, on fait une requête à la personne et non une demande. Selon la communication non-violente, une demande est plutôt un ordre tandis qu’une requête peut-être refusée par l’autre. Je concède qu’en français, la nuance entre « demande » et « requête » n’est pas aussi claire qu’en anglais, langue dans laquelle la communication non-violente a été élaborée.

Remarquer aussi le « je » qui prédomine le gabarit ci-haut. La communication non-violente met l’accent sur le « je » puisqu’on y communique nos émotions, chose qui nous appartient. Je vous invite d’ailleurs à relire les exemples au début du billet. Le « tu » est présent tandis que le « je » est absent.

Après avoir pris connaissance de ce processus pour communiquer non-violemment, voici comment je réécrirais les phrases au début de mon billet.

  • Avant : Si tu n’écris pas tes tests avant ton code de production, ton code est à chier.
  • Après :
    • Approche #1 : J’ai peur pour la qualité de ton code si tu n’écris pas tes tests.
    • Approche #2 : Quand je ne vois pas de tests unitaires couvrir du code de production, j’éprouve un certain inconfort puisque je désire livrer de la qualité à mon client.
  • Avant : Tom est un mauvais programmeur.
  • Après
    • Approche #1 : Tom a livré 5 bogues dans l’itération.
    • Approche #2 : Quand je vois plusieurs bogues à la fin de l’itération, j’éprouve une certaine culpabilité envers le livrable puisque j’aime être fier de la qualité dans la livraison à la fin de l’itération.

En somme, je vous invite à vous documenter sur le sujet si vous désirez améliorer votre savoir-être. En technologie de l'information, on nous demande souvent d'améliorer notre savoir-faire mais pour communiquer ce savoir-faire à nos collègues, je pense qu'il faut aussi un savoir-être pour bien travailler en équipe. 

Mots-Clés :

Ma présentation au colloque TI 2013 - Mauricie et Centre-du-Québec

Publié par Louis-Philippe Carignan le mardi 23 avril 2013 à 11:20

J'aimerais remercier le comité organisateur du Colloque TI 2013 - Mauricie et Centre-du-Québec pour m'avoir donné l'opportunité de parler d'Agilité lors de leur évènement. C'était très apprécié d'échanger avec les gens dans la salle et j'espère que vous avez l'impression d'avoir fait un bon choix de conférence.

J'inclus dans ce billet ma présentation. Pour ceux et celles qui aimeraient télécharger la présentation, vous pouvez le faire directement en utilisant les boutons au bas la présentation.

 

Mots-Clés :

Archive