fvrier 2010Monthly :

Vin, fromages et initiation au poker estimatif avec jean-rené et le PMI de Lévis-Québec

Jean-René Rousseau animera la session le mercredi 10 mars de 17h à 19h à l’Auberge Saint-Antoine à Québec.

Saisissez l’opportunité de connaître les méthodologies Agile sous un angle bien pratique et concret avec une méthode émergente : le poker estimatif.

Lors d’un vin et fromage organisé par le PMI de Lévis-Québec, Jean-René vous initiera à cette méthode et vous aurez l’occasion d’en faire l’essai durant l’atelier d’une durée de deux heures.

Attention, le nombre de places est limité, faites-vite votre inscription.

Prix : 75$ pour les membres PMI Lévis-Québec, 90$ pour les non-membres

Inscrivez-vous ici!

 

L’activité donne droit à 2 PDUs.

FizzBuzz à la façon LINQ

ModèleDernièrement mes collègues et moi exécutions le Kata FizzBuzz dans le cadre de notre Dojo pratiques d’ingénierie. L’objectif était de pratiquer le développement piloté par les tests. Je dois avouer que ce fut fort amusant et la solution à laquelle nous sommes arrivés est tout à fait adéquate et présente un modèle objet élégant qui résoud le problème.

La séquence FizzBuzz est générée par la méthode CountTo de la classe FizzBuzz. Cette dernière utilise un ensemble de règles qui vérifient si elles s’appliquent et transforment, le cas échéant, l’entier question soit en “Fizz”, “Buzz” ou “FizzBuzzz”.

class FizzBuzz
{
private readonly IRule[] _rules = new IRule[] {
new FizzBuzzRule(),
new BuzzRule(),
new FizzRule()
};

private readonly IRule _defaultRule = new NumberRule();

public string[] CountTo(int upperBound)
{
var sequence = new List();

foreach (var n in NumbersUpTo(upperBound))
{
sequence.Add(Interpret(n));
}

return RespondWith(sequence);
}

private static IEnumerable NumbersUpTo(int n)
{
for ( int i = 1; i <= n; i++)
{
yield return i;
}
}

private string Interpret(int n)
{
foreach (var rule in _rules)
{
if (rule.Applies(n)) return rule.Apply(n);
}
return _defaultRule.Apply(n);
}

private string[] RespondWith(List result)
{
return result.ToArray();
}
}

La classe FizzRule est un exemple d’implémentation d’une rèlge.

class FizzRule : IRule
{
public bool Applies(int number)
{
return ShouldSayFizz(number);
}

private static bool ShouldSayFizz(int n)
{
return IsDivisibleByThree(n) || ContainsThree(n);
}

private static bool IsDivisibleByThree(int number)
{
return number % 3 == 0;
}

private static bool ContainsThree(int n)
{
return n.ToString().Contains(“3″);
}

public string Apply(int number)
{
return SayFizz();
}

private static string SayFizz()
{
return Fizz;
}

private const string Fizz = “fizz”;

}

Plus tard, je me suis demandé de quoi aurait l’air la solution si j’utilisais les fonctionnalités du langage C# 3.0 telles que LINQ, les expressions lambda et les méthodes d’extension. Avec notre batterie de tests comme garde-fou je me suis lancé dans une session de refactorisation au bout de laquelle je suis arrivé à la solution que je présente plus loin.

Les premières pistes que je choisis d’explorer sont les méthodes que Resharper suggère de changer en méthodes statiques. En fait, les méthodes statiques me font toujours penser à des méthodes utilitaires qui en général sont très réutilisables. C’est le cas par exemple des méthodes IsDivisibleByThree et ContainsThree de la classe FizzRule plus haut. Je les rassemble donc dans la classe IntExtensions après avoir introduit un peu de généricité pour qu’elles soient utilisables également dans la classe BuzzRule.

public static class IntExtensions
{
public static bool Contains(this int n, int number)
{
return n.ToString().Contains(number.ToString());
}

public static bool IsDivisibleBy(this int number, int dividend)
{
return number % dividend == 0;
}
}

Avec ces modifications, la méthode ShouldSayFizz se lit comme suit:

private static bool ShouldSayFizz(int n)
{
return n.IsDivisibleBy(3) || n.Contains(3);
}

Je suis content car la lisibilité du code n’en souffre pas. Je m’attaque de la même façon à la méthode NumbersUpTo de la classe FizzBuzz. J’en fais une méthode d’extension que je rajoute à la classe IntExtensions. Je prends le soin de renommer la méthode FirstNumbers pour une meilleure lisibilité du code client qui se lira

foreach(int number in n.FirstNumbers()) { … }

Cela me rappelle mon cours d’analyse et la série des n premiers nombres entiers… En fouillant un peu dans MSDN, je retrouve comment générer une suite d’entiers grâce à la classe Ennumerable et je modifie mon implémentation en conséquence. J’obtiens le résultat suivant

public static class IntExtensions
{
public static IEnumerable FirstNumbers(this int n)
{
return Enumerable.Range(1, n);
}

public static bool Contains(this int n, int number)
{
return n.ToString().Contains(number.ToString());
}

public static bool IsDivisibleBy(this int number, int dividend)
{
return number % dividend == 0;
}
}

Avec ces méthodes utilitaires hors de la classe FizzRule, la responsabilité de celle-ci devient plus évidente et je la simplifie pour arriver au résultat suivant

class FizzRule : IRule
{
public const string Fizz = "fizz";
private const int Three = 3;

public bool AppliesTo(int number)
{
return number.IsDivisibleBy(Three) || number.Contains(Three);
}

public string Apply(int number)
{
return Fizz;
}
}

Une bonne chose de faite! Je tourne mon attention vers la classe FizzBuzz. Même si j’ai sorti la génération des nombres entiers hors de cette classe, elle a encore trop de responsabilités: maintenir la liste des règles FizzBuzz, appliquer les règles qui conviennent, formater le résultat. C’est une violation évidente du principe de responsabilité unique (Single Responsibility Principle) de l’oncle Bob. Je décide donc séparer tout ce qui touche à la transformation FizzBuzz dans une classe à part. Les règles et tranformations FizzBuzz sont maintenant rendues dans la classe FizzzBuzzExtensions. J’ai changé l’implémentation pour utiliser LINQ étant donné que le résultat est plus compacte et tout de même très lisible.

static class FizzBuzzExtensions
{
internal static IEnumerable AsFizzBuzzSequence (this IEnumerable sequence)
{
return sequence.Select(numeral => Transform(numeral));
}

private static string Transform(int n)
{
return FirstRuleThatApliesTo(n).Apply(n);
}

private static IRule FirstRuleThatApliesTo(int n)
{
return Rules.First(r => r.AppliesTo(n));
}

private static readonly IRule[] Rules = new IRule[] {
new FizzBuzzRule(),
new BuzzRule(),
new FizzRule(),
new NumberRule()
};
}

L’astuce d’encapsuler cette fonctionnalité en arrière d’une méthode d’extension facilite grandement la lecture de la classe FizzBuzz qui devient

class FizzBuzz
{
public string[] CountTo(int n)
{
return RespondWith(n.FirstNumbers().AsFizzBuzzSequence());
}

internal static string[] RespondWith(IEnumerable result)
{
return result.ToArray();
}
}

Séparer ainsi les responsabilités dans différentes classes a grandement augmenté la clareté du design. De plus l’utilisation de LINQ et des méthodes d’extension fait en sorte que le code est très compacte quoique très expressif. À vous d’en jugez. Voyez-vous d’autres pistes d’améliorations ?

Le Sunset Graph comme vecteur de communication

Lorsque nous parlons Scrum, nous insistons sur la visibilité, l’engagement, les points d’inspection, l’adaption… ajoutons à cela quelques règles simples, 3 rôles, 5 artefacts, quelques incréments et du bon sens à volonté… et voilà une recette simple et gagnante pour une équipe agile!

Cependant, surtout dans les grandes organisations qui font le choix de l’agilité, notre équipe Scrum se retrouve bien souvent scrutée par les stakeholders, qui déplorent parfois leur manque de visibilité sur l’avancement global du projet. Certes, le Release Burndown, couplé le cas échéant au graphique de Vélocité, adresse ce besoin, mais il a une lacune majeure : il ne permet pas de rendre visible l’atteinte du périmètre minimum, ni de ce fait le levier que l’on a sur la portée.

Mon collègue Mathieu et moi-même avons envisagé un autre graphique, baptisé « Sunset Graph » (en hommage à son visuel si… jaune), dans le but d’optimiser notre communication sur l’avancement et sur les prévisions.

Ses caractéristiques? Il s’agit d’un burn-up mettant en valeur :

  • Le périmètre du backlog, catégorisé en obligatoire/important/optionnel
  • l’avancement réel catégorisé en obligatoire/important/optionnel
  • l’avancement prévisionnel compte tenu de l’auto-évaluation de l’équipe
  • la vélocité réelle de l’équipe
  • les fluctuations du backlog

Par exemple : Nous sommes au sprint 0 d’un projet, et le PO a catégorisé ses stories. L’équipe fait une macro-estimation de la totalité du carnet de commande par un atelier type wall session, puis nous alimentons le graphique avec les valeurs estimées. Par rapport à l’engagement de l’équipe pour le sprint 1, nous avons le point de départ des prévisions pessimiste et optimiste. L’équipe fait ensuite des hypothèses sur sa courbe d’avancement pire et meilleure (en fonction de sa courbe d’apprentissage pressentie par exemple).

burnup1

Dans l’exemple du graphique ci-dessus, on constate que selon les hypothèses, à la fin du sprint 8, on pense avoir atteint l’optionnel dans le meilleur des cas, et le milieu de l’important dans le cas pessimiste. Les courbes prévisionnelles divergent logiquement (plus on s’éloigne, moins on est précis).

Suite au sprint 0, au fil des sprints, on met à jour les données après chaque planification.

Par exemple, dans le graphique ci-dessous, au bout de 3 sprints (donc 3 sprints de données réelles), on constate que :

  • le périmètre du backlog a évolué
  • les évaluations des cas pessimiste et optimiste tendent à converger car l’équipe affine ses estimations
  • la pente du réalisé nous montre la vélocité de l’équipe qui va en s’améliorant
  • dans ce cas, suite à la révision du backlog et aux réalisations meilleures que prévues initialement, l’équipe pourrait couvrir dans tous les cas l’obligatoire et l’important du backlog.

burnup2

Ainsi, ce graphique, associé au travail annexe de catégorisation du backlog et de macro estimation de ce dernier, permet :

  • à l’équipe, en sprint 0, de prendre conscience de l’ampleur du backlog et des objectifs
  • à l’équipe, en réalisation, de vérifier sa vélocité, la justesse des estimations, et de mieux s’évaluer
  • au PO, en tout temps, de savoir ce à quoi il peut s’attendre, et si besoin d’ajuster ses priorités et/ou de jouer sur ses leviers Calendrier/Budget/Portée
  • de rendre visible l’avancement du projet (atteinte du périmètre minimum), mais aussi les potentiels dysfonctionnements (ex : fluctuation forte du backlog, vélocité dégradée, …)

Tout cela favorisant la communication… CQFD!

Atelier de démarrage de projet animé par Mathieu Boisvert le 17 février à Agile Québec

Atelier de démarrage de  projet : rédaction du carnet de produit et planification d’un système cohérent

Événement gratuit organisé par Agile Québec le 17 février 2010 à 18h à l’Université Laval

Contrairement à ce que la littérature Agile laisse entendre, un logiciel a souvent besoin de préparation pour commencer son développement. Cette préparation ne doit pas tomber dans le piège de l’analyse exhaustive. On veut limiter l’effort à aligner une équipe sur la vision du produit et à réunir des spécifications “juste-suffisantes” pour permettre à cette équipe d’entreprendre la réalisation.

Mais par quoi commencer? Comment éviter de se perdre dans la constitution d’un carnet de produit et d’une planification qui ne formeront jamais un système cohérent?

Dans le cadre de la présentation et à travers un atelier, Mathieu Boisvert vous propose un cadre de démarrage de projets de développement logiciel:

  • Quels sont les pré-requis à réunir?
  • Qui devrait être impliqué?
  • Comment identifier le système minimal et cohérent?

Tous les détails et inscriptions à cette adresse : http://www.agilequebec.ca/event.php?id=7

Data Context Interaction (DCI) in Java

DCI is an emerging user interaction pattern that has many benefits over traditional MVC. This video by Rickard Oberg shows how to implement such a pattern in plain Java as well as with Qi4J, an emerging composite-oriented programming framework. Focusing on interactions and context helps create atomic objects directly mapped to user actions. This greatly helps testing and system evolution. Potential good practice for our agile projects? Are these approaches are also emerging in other technologies? Ruby? .Net? Scala?

Autorité, pragmatisme et auto-désorganisation

Le titre original de l’article d’InfoQ est “Agile – A Way of Life and Pragmatic Use of Authority“. Le mot autorité m’a interpellé et ce pour plusieurs raisons :

  • En tant que Scrum Master comment guider mon équipe à partir d’une position dépourvue d’autorité ?
  • Que devient un Project Manager dans un mode Agile? Qu’arrive-t-il à son autorité?
  • En tant que coach, si j’applique le Leadership de situation et je suis directif. Je nuis à l’équipe?
  • En tant que leader à Pyxis, comment communiquer une vision, prendre des décisions difficiles, faire des choix sans autorité?

Dernièrement plusieurs discussions entre collègues et amis avaient comme sujet principal l’autorité. Même que pour rigoler on a appelé une communauté des services “Le BOSS

J’ai donc plongé dans l’article.

Premier point intéressant l’article fait suite à un article sur les chargés de projet justement. Autorité et gestion de projet c’est toujours assez controversé… ici même à Pyxis.

L’auteur tente de défendre sa position face à l’autorité

“Although in that article, I used the term ‘authority’ scarcely but some of the readers expressed reservation about ‘authority’”

Je me retrouve dans sa vision de l’autorité. J’aime penser que le problème avec l’autorité est l’usage qu’on en fait et non l’autorité elle-même. Je crois que de l’éliminer complètement peut causer un drôle d’effet bord :  l’auto-désorganisation

“There are certain decisions in life if they go wrong, we can always recover and get 2nd chance to make amendments. But there are certain decisions, where life does not give 2nd chance. If they go wrong, it may irreversibly alter course of your life, your business, your project, your relation with the customer and so on. It is these things where we should fall back on expert judgment and more experienced people. And those seasoned experts may have to use authority in certain situations if their loved ones are doing a blunder in ignorance. This is my idea of pragmatic authority.

you cannot inspire every person and make every person truly self-organizing. If this is true, what will you do to those persons who are off track, not Agile by nature which means self-disorganized?[...]One of the best and historical ways to handle these off track people is to control the incompetency of these people using authority but using it professionally.”

L’auteur fait plusieurs analogies avec la vie courante pour renforcer son point. Certains exemples sont plus faibles que d’autre, mais au final:

“It may sound a little strange that I am comparing acts of public life against backdrop of Agile in IT. Actually I am comparing humans with humans. Agile is an excellent way of software development but in my opinion, it is not a magic pill with divine powers that will transform people into a perfect human being the moment they enter into the office.”

en résumé…

“In my opinion, the problem is misusing the authority and using it unnecessarily. It should be used to protect the business, protect the customer, protect the projects which indirectly would protect and help people only. Agile is not only a set of rules but it is much bigger. It requires paradigm shift in the mindset and attitude the way we work. And it cannot be adopted completely simply by couple of days of classroom training. It requires a minimum basic level of maturity, ability to change and evolve, self-motivation, honest intentions to excel as a team and constant mentoring.

Freedom has same attribute as authority. If people misuse freedom, it is equally terrible.”

Rhino Mock / MSTest : Isolation

 

Dans ce post, j’aimerais vous présenter diverses méthodes permettant d’effectuer des tests de comportements sur vos composants. On ne teste pas le contexte, les données retournées mais bien le comportement de la routine avec l’appelant et les dépendances.

Contexte

On souhaite tester une méthode d’un dépôt(notion de repository en DDD). La routine en question est un service permettant d’envoyer des entités (Demande) à un service Web pour centraliser ces demandes. Les différentes actions effectuées sont les suivantes :

L’appelant appelle la méthode EnvoyerTout prenant en paramètre une liste de Demande.

Le dépôt reçoit la liste et vérifie les informations de synchronisation dans une base de données locale.

Le dépôt envoie la liste des demandes et les informations de synchronisation au service.

Le service répond et fournit des informations permettant d’enregistrer en local que les demandes ont déjà été envoyé au serveur.

Afin de limiter le trafic réseau, on souhaite vérifier que les demandes réellement envoyées au serveur n’avait jamais été envoyées. Cette information est disponible dans la base de données de locale.

On souhaite isoler le comportement de cette routine car nous détectons rapidement les différentes dépendances :

Un service Web qui doit répondre aux différentes requêtes du proxy.

Une base de données contenant des informations de synchronisation.

Une utilisation d’une dépôt permettant de récupérer les informations de l’utilisateur.

Explication du test

Voici donc le test en question :

 1: [TestMethod]
 2:         public void EnvoyerToutNAjouteQueLesDemandesJamaisSynchronisees()
 3:         {
 4:             utilisateurDepot = mockRepository.Stub<IUtilisateurDepot>();
 5:             demandeDeControleService = mockRepository.StrictMock<DemandeDeControleService>();
 6:             demandeDeControleServeurDepot = mockRepository.Stub<DemandeDeControleServeurDepot>(demandeDeControleService, utilisateurDepot);
 7:             Expect.Call(demandeDeControleServeurDepot.GetReplicaId()).Return(Guid.NewGuid());
 8:             demandeDeControleServeurDepot.MettreAJourTousLesWatermark(null, 0);
 9:             LastCall.IgnoreArguments();
 10: 
 11:             Expect.Call(demandeDeControleService.EnvoyerTout(null)).IgnoreArguments().Return(0).Repeat.Once();
 12:             mockRepository.ReplayAll();
 13: 
 14:             demandeDeControleServeurDepot.EnvoyerTout(CreerUneListeDeDemandes(5, 2));
 15: 
 16:             ServiceDomain.DemandeDeControle[] demandeDeControleEnvoyees =
 17:                 (ServiceDomain.DemandeDeControle[])demandeDeControleService.GetArgumentsForCallsMadeOn(x => x.EnvoyerTout(null)).First().First();
 18:             Assert.AreEqual(2, demandeDeControleEnvoyees.Length);
 19:         }

Pour décrire ce test commençons par le commencement d’un test à savoir son assertion :

Ligne 18 :  Assert.AreEqual(2, demandeDeControleEnvoyees.Length); On vérifie ici que le nombre de demandes envoyés au serveur est bien égale à 2.

On pourrait donc traduire cette assertion de la sorte : Si l’application fournit une liste de 5 demandes au dépôt mais que seuls 2 demandes de cette liste doivent être envoyées au serveur, vérifie que le dépôt n’a envoyé que ces 2 éléments au service.

Pourquoi?

Ligne 14 : demandeDeControleServeurDepot.EnvoyerTout(CreerUneListeDeDemandes(5, 2)); C’est la routine que nous souhaitons tester. Dans le test, le paramètre (la liste de demandes suceptibles d’être envoyées) est fourni par une méthode du test CreerUneListeDeDemandes(5, 2) prenant en paramètre le nombre total de demande à créer et le nombre de demandes à synchroniser (et qui doivent donc réellement être envoyées au serveur).

Et la rapport avec l’assertion?

Ligne 16 et 17 : On récupère le premier paramètre du premier appel (il n’y en a qu’un) de l’exécution de la méthode EnvoyerTout d’un mock (demandeDeControleService) .C’est le cœur même du test et l’objet de l’assertion. Ces paramètres proviennet directement du mock, le service n’est jamais instancié.

Et comment c’est possible?

De la ligne 4 à la ligne 9 : on prépare l’exécution du test en isolant, à l’aide de diverses techniques et fonctionnalités de RhinoMock, les dépendances détectées.

Ligne 4 : on crée un stub du dépot utilisateur, aucun comportement ou données ne nous sont nécessaires. Nous avons juste besoin d’une instance de ce dépot pour l’instanciation ligne 6. Le fait de le “stuber” permet de ne pas exécuter le code de ce dépôt.

Ligne 5 : On crée un mock strict. Toutes les fonctionnalités du service seront recrées et tous les appels vers le service seront redirigés vers ce mock.

Ligne 6 à 12 : Création du mock partiel du composant testé. Toutes les routines réclamant un contexte (ligne 7 et 8, la récupération des informations de synchronisation nécessite une base de données locale) sont redirigés vers le mock. On peut configurer le résultat de l’exécution de la méthode du mock (ligne6 : demandeDeControleServeurDepot.GetReplicaId()).Return(Guid.NewGuid()) ) ou l’on peut déclarer d’ignorer l’appel et les paramètres (ligne 7).

Sur ce mock partiel, on appelle la méthode testée (ligne 11).

Tous les comportement d’isolation ne seront disponibles qu’après la ligne 12. Celle-ci permet d’informer RhinoMock des différentes instructions d’isolation.

Conclusion

Pas de base de données à construire et de données à générer. Pas de service sur un serveur de test. Mais le comportement attendu est vérifié et le sera même en cas de changement de source de données, de modification du contrat de service…

Cool non?

 

 

Green is good!

Éric Laramée, a colleague at Pyxis the other day was recalling the Greed is good scene from the movie Wall Street

The point is, ladies and gentleman, that greed, for lack of a better word, is good. Greed is right, greed works. Greed clarifies, cuts through, and captures the essence of the evolutionary spirit. Greed, in all of its forms; greed for life, for money, for love, knowledge has marked the upward surge of mankind. And greed, you mark my words, will not only save Teldar Paper, but that other malfunctioning corporation called the USA.

Thank you very much.

We the started to play with that quote and here is the result:

The point is, ladies and gentleman, that green, for lack of a better word, is good. Green is right, green works. Green clarifies, cuts through, and captures the essence of the evolutionary design. Green, in all of its forms; green for life, for money, for love, knowledge has marked the upward surge of mankind. And green, you mark my words, will not only save your project, but that malfunctioning industry called IT.

Thank you very much.

We had a good laugh and thought it was very cool!

Put your specifications in the freezer

Some developers are asking me : How do I tag my specification when I do a release or close a development branch while GreenPepper does not provide full SCM capabilities in the wiki.

I explained in Why we did not implement a full SCM for specifications why we did not think it was a good idea to implement full SCM capabilities in the wiki.

To achieve the need stated above, we have implemented in all our build system integrations (Maven, MSBuild and Nant) a feature called freeze, what this does is simply going to the wiki server to get the specifications and store them locally. See the documentation to learn what you need to do in your build script.

You simply commit those files and tag them with your source files. Couldn’t be simpler!

Life is Green!

You can even come back months after the release and execute the specifications locally from your IDE or from the command line.

Life is Greener!