quel framework de BDD pour .Net et bien adapté à MVC?

Juin 19th, 2010

permettez moi tout d'abord de vous inviter à parcourir la présentation que j'ai déroulée au SigmaT 14 , qui fut un peu mon appel du 18 Juin à moi
http://www.slideshare.net/guillaumeagile/to-test-or-not-to-test

"les informaticiens parlent aux informaticiens, venez rejoindre les partisants IT libérés, venez faire du Test Comportementaliste! (BDD)"

vous pouvez trouverez moultitude de références sur le sujet en anglais , comme par exemple (et pour faire court) http://jockeholm.wordpress.com/2010/02/14/combining-tddbdd-with-ddd/

ceux qui comme moi, aiment partir de la théorie et arriver rapidement à la pratique, et qui on fait le choix de .Net, ont surement eu à se poser beaucoup de questions quant au choix de l'outil/framework de BDD/ATDD .

Si le choix semble plus évident pour la communauté Java et Ruby, qui est beaucoup plus active et unanime sur le sujet (ils ont Cucumber et RSpec, eux!), ceux qui travaillent en .Net peuvent se sentir un petit peu perdu, pour ne pas dire découragés.

Alors, voici pour se mettre rapidement et efficacement en selle, quelques liens rapides vers de bons articles en Français (et un peu en Anglais) qui explorent ces technos en détails (et avec tutoriels bien fait):

GHERKIN (sachez avant tout, que tout est centré sur ce langage, qui n'est pas un langage de développement mais un DSL prêt à l'emploi):

http://ryanlanciaux.com/ryanlanciaux/post/Gherkin-style-BDD-testing-in-NET.aspx
http://wiki.github.com/aslakhellesoy/cucumber/gherkin

MSPEC:

http://blogs.developpeur.org/tja/archive/2010/02/05/tests-suite-des-tests-unitaires-avec-mspec.aspx

NBEHAVE:

http://blogs.developpeur.org/tja/archive/2009/12/08/tests-tester-votre-site-asp-net-mvc.aspx
http://blogs.developpeur.org/tja/archive/2010/01/22/tests-nbehave-et-asp-mvc-2-suite.aspx
http://blog.developpez.com/bruno-orsier/p8428/bdd/nbehave-a-la-cucumber/

http://pebblesteps.com/post/Behavior-Driven-Development-with-NBehave.aspx

Cucumber/IronRuby:

http://blog.developpez.com/bruno-orsier/p8440/bdd/cucumber-avec-ironruby-ca-marche/#more8440

Cuke4Nuke :

http://gojko.net/2010/01/01/bdd-in-net-with-cucumber-cuke4nuke-and-teamcity/
http://stackoverflow.com/questions/2113936/cuke4nuke-or-specflow

SPECFLOW:

http://blogs.developpeur.org/tja/archive/2010/01/25/tests-ma-qu-te-bdd-continue-tests-unitaires-avec-specflow.aspx
http://www.specflow.org/specflow/technical-concepts.aspx
http://blog.stevensanderson.com/2010/03/03/behavior-driven-development-bdd-with-specflow-and-aspnet-mvc/
http://www.codeproject.com/KB/architecture/BddWithSpecFlow.aspx

 

quant à moi, je vous donnerai bientôt mon avis détaillé sur celui qui me semble être le meilleur d'entre eux...

l'Open Source rendra-t-il la planète plus verte à lui tout seul?

Avril 14th, 2010

désolé messieurs-dames, je m'inscris en faux. Le seul fait d'utiliser et d'imposer l'Open Source est selon moi tout sauf efficace pour lutter contre le gaspillage, le réchauffement climatique, la réparatition des richesses, l'amitié entre les peuples, le green washin', le social Washin'.... et tout autre concept "bankable".


Depuis plusieurs mois, il y a un effet de mode consistant à associer miraculeusement, et sans prendre la peine de réflechir, logiciels libres et écologie ou développpement durable:
pour quelques références lues récemment.

Quitte à me faire lyncher par les apôtres de ce courant (ce ne sera pas la première fois), je le clame haut et fort: l'Open Source n'est pas une cure à lui tout seul!

Pour y voir plus clair, et pour calmer ce débat, si ancien et si houleux, il n'est pas superflu de revenir à quelques définitions.

Open Source: logiciel (ou produit) dont les secrets et la méthode de fabrication (procédés, brevets, code source) sont rendus disponibles à tout un chacun et dont l'utilisation ou la modification ne demande (en théorie) aucune contrepartie financière.

L'impact environnemental désigne l'ensemble des modifications qualitatives, quantitatives et fonctionnelles de l'environnement (négatives ou positives) engendrées par un projet, un processus, un procédé, un ou des organismes et un ou des produits (de sa conception à sa "fin de vie").  d'après Wikipédia.

Impact environnemental (ou trace carbone) généré par un logiciel: tout surplus de calcul (temps CPU), d'espace de stockage (Octets en Kilo, Mega, Giga, Tera, Zeta...) et de transfert de données (flux d'Octets par unité de temps) lors de l'utilisation du dit logiciel qui aboutit à la consommation d'électricité, au réchauffement (refroidissement des machines, des data centers), à la fabrique d'équipements (réseaux, serveurs, postes, écrans) à base de composants polluants (métaux lourds, arsenic, retardateurs de flamme et autres poisons) nécessaire à sa mise en oeuvre.

Ainsi posé, il m'apparait difficile de valider que Open Source => Réduction de l'Impact Environnemental de l'Informatique.
Je m'explique. Pour moi à l'origine de toute informatique, il y a un programme, un logiciel (même dans un micro-controleur il y a un micro programme, de la plus simple machine à laver au super-calculateur) et donc du code source.
Tout le monde devrait tomber d'accord sur ce point (du moins j'espère).

Mais le fait que ce code source soit "open", c'est à dire "ouvert à quiconque" ne va pas changer beaucoup la donne écologique.
Ouvrir le code n'est en rien une garantie que l'impact du logiciel a été étudié et minimisé. En rien!

Certes le fait de distribuer ce code va permettre à une personne extérieure de vérifier si ce dernier est de qualité et si on a cherché à minimiser les ressources, les défauts, les gaspillages.

Mais à quel prix peut-on réellement et réalistement effectuer une telle vérification?

Qui d'entre vous a le temps d'aller regarder les dizaines de milliers de lignes (quand ce ne sont pas des millions) de tel ou tel logiciel (ou système d'exploitation).
Qui en a la compétence? Quel est le coût d'inspection de lignes de codes?
Combien d'heure de travail, d'heures d'utilisations d'ordinateurs et de serveurs pour déchiffrer un code qui certes est "libre" mais le plus souvent abscon quand il n'est pas, à l'extrême, bon à jeter à la poubelle.

la source de tous les maux?

Code ouvert n'a jamais été une garantie de facto de qualité et de lisibilité.

C'est là qu'il ne faut pas confondre "logiciel libre" et "liberté réelle"... le fait d'avoir accès à une chose ne veut pas dire qu'on la possède.

J'irai même plus loin en osant affirmer que posséder la source du logiciel peut dans certains cas être une formidable source de gaspillage, et donc d'élévation de l'empreinte écologique.
Se lancer dans l'exploitation de sources, passer du temps à les déchiffrer, les analyser, corriger un nombre important de bugs à postériori est du pur gaspillage de temps et d'énergie (réparer après conception et encore plus après construction coute des centaines de fois plus cher, c'est un fait maintenant admis).
Se dire que parce qu'on est en train de faire un logiciel ouvert, on peut laisser n'importe quel bug, puisque la communauté sera là pour les corriger est pour le moins hasardeux.

J'estime que la valeur et la fiabilité (logiciel durable) sont déterminées par des facteurs aussi intransigeants que la couverture de code par les tests unitaires, et qu'un code ouvert sans cela est absolument inutile et dangereux!

Ce serait comme si on vous livrait une voiture avec accès intégral au moteur, complètement ouvert, et que les centaines de pièces et micro-pièces que celui-ci renferme vous sautent au visage dès que vous ouvrez le capot alors que vous comptiez juste vérifier le niveau d'huile.
Comme si pour effectuer cette simple vérification il fallait déposer le carter et chacune des pièces pour trouver les éléments qui font jauge. Et bien sur, le tout sans manuel d'instructions, puisque l'accès au moteur est entièrement libre (vous n'avez qu'à vous débrouiller ou apprendre, ou payer les services d'un vrai expert... à chaque vérification d'huile! c'est ce que j'appelle un modèle économique bien senti).

Comme tout automobiliste moyen, je préfère un moteur bien étanche et fermé. Je n'ai pas la compétence pour démonter une bièle ou vérifier des roulements à billes (et je n'ai pas le temps de le faire, ni de l'apprendre; chacun son métier). Par contre je veux disposer d'un moyen simple et accessible (mot clef!) pour visualiser le niveau (métrique) d'huile, et d'un conduit accessible et sécurisé (ce qui s'appelle une Interface de Services ou API pour les logiciels) afin de rajouter l'huile qui manque ou de vidanger.
(pour ma part, étant plus motard qu'automobiliste, je m'en tiendrais plutôt à cette petite illustration :)


Pourquoi en serait-il autrement avec le logiciel?


Les seules personnes qui montent au créneau de l'ouverture du code sont bien souvent celles qui n'en ont jamais lu car elles n'en ont pas la compétence. Et c'est bien dommage de voir une fois de plus ceux qui prennent de grandes décisions (pour l'administration française notamment) tenir des propos aussi irresponsables.

Peut-on se satisfaire d'un logiciel sur la seule base de la disponibilité de ses sources, et d'une gratuité qui n'est ni le corolaire de l'ouverture des sources, ni garantie dans le temps?
Je n'ai jamais pu être convaincu que la qualité découlait automatiquement de l'ouverture du code, mais je reste ouverts aux arguments qui iraient dans ce sens.
En d'autres termes, on ne peut pas sérieusement réclamer la disponibilité des sources sans d'autres critères beaucoup plus précis, stricts et contraignant vis à vis des éditeurs et fournisseurs de solutions logicielles (SSII pour la plupart).

Ces autres critères sont interessants à explorer dans l'optique justement de la réduction de l'empreinte sur l'environnement.
Vous ne pouvez pas imaginer combien il est difficile d'obtenir des critères explicites reconnus par des "experts", tant le sujet est vaste, vague, animé de toutes les passions et des intentions les plus antinomiques.
Une fois de plus, Wikipedia m'a été bien utile (source: http://en.wikipedia.org/wiki/Sustainable_design )

Principes de conception durable (et application au génie logiciel)

Bien que d'un domaine d'application à l'autre, certains concepts ne puissent pas être translatés, voici quelques principe généraux applicables au logiciel:

  • Low-impact materials:
    choisir des composants et des sous-systèmes qui ont eux même mesuré la réduction de leur impact (malheureusement je ne connais aucun logiciel qui le propose à ce jour) (1)
  • Energy efficiency:: efficacité énergétique
    • efficacité en SLOC: moins de ligne de code = moins de risque de bugs mais aussi de fonctions inutilisées (moins de stockage pour ces fonctions et moins de CPU pour des calculs dont le résultat n'est pas exploité in fine). C'est aussi un facteur indiquant qu'il y a eu refactoring et que les algorithmes sont certainement optimisés (à vérifier avec ce qui suit).

    • efficacité en cycles CPU: pour chaque feature, mesurer le nombre de FLOP consommé pour une action (utiliser la base des User Story) donnée.

    • efficacité en stockage: mesure en Octects de la quantité de stockage nécessaire à une feature ou une opération.

    • efficacité de la persistence et du rappatriement de données: calculer les cycles CPU pour faire une requête, et calculer l'encombrement mémoire (ou sur les flux) des informations remontées depuis le mécanisme de stockage (objectif avoué: bannir le "select * from"). Penser aux atouts (et faiblesses) du NoSql.
    • optimisation l'encombrement sur le réseau: calcul du nombre d'informations en transit entre le client et le serveur (web ou autres) en terme de débit moyen en fonction de l'usage (une fois de plus les User Story sont un bon point d'entrée). Format condensé des données (préférez JSON à XML). Pertinence des données échangées (supprimez le superflu). Penser "Just In Time" (la bonne information au bon moment): l'utilisateur n'est pas une machine, pas la peine de lui afficher des tonnes d'informations qu'il ne lira pas.
  • Quality and durability:
    • qualité: absence de bug prouvée: mesure du taux de couverture du code par des tests unitaires qui ont échoué mais qui n'échouent plus.
    • durabilité:  présence de tests unitaires ayant un rôle évident dans la surveillance de la non-regression et couvrant l'ensemble des fonctions.
  • Design for reuse and recycling: c'est la fameuse ré-utilisabilité du logiciel, qui est trop souvent soit un voeux pieux, soit un graal jamais atteint
    • Interfaces Publiques Documentées: soit des APIs, soit des Web Services, soit une interface REST, mais toujours documentées avec des exemples concrets d'utilisation (guide sous forme de HOW-TO)
    • Ergonomie des API (ou Services): les parties d'inter-communications (interfaces) doivent être très sérieusement pensées dans un souci de non-gaspillage de ressources et de facilité d'utilisation. Pour être viables, elles doivent pouvoir être utilisées (consommées) sans dépenser de surplus d'énergie, c'est à dire sans avoir à passer 3 heures à comprendre comment ca marche, ou à devoir fournir au moment de l'appel des tonnes d'informations qui ne seront peut être même pas exploitées (penser au coût de récupération des données).
    • voir mon article sur l'érgonomie des API http://docs.google.com/Doc?id=dhp3ggmx_38f58b3d
    • commercial 'afterlife'. dans 10 ans, votre bout de logiciel devrait encore pouvoir servir à d'autres, même s'il n'a plus vocation d'être commercialisé
  • Pérénité: votre système ou sous-système doit pouvoir être adapté à tout changement de l'environnement (évolution des échelles, les mesures, conversions, valeurs fluctuantes...).
  • Sustainable Design Standards : on peut espérer (ou rêver) dans un avenir proche voir l'émergence d'un éco-label pour le développement logiciel durable. Celui-ci énoncerait des métriques précises et des niveaux de seuil en dessous desquels on peut considérer que le développeur du logiciel a fait des efforts significatifs visant à améliorer la qualité de son produit et la réduction de l'empreinte énergétique.
  • Biomimétisme: inspirez vous de ce que la nature fait quand vous devez inventer un algorythme ou un processus. Ce qui a survecu pendant des millénaires est forcément viable (principe de Darwin).
  • Service substitution:  être capable de changer le mode de consommation des services sous jacents (stockage, services bancaires, services de transaction, d'authentification, de sécurité, de cache...) et se tourner au fur et à mesure qu'ils apparaissent vers des systèmes offrant les même services mais avec une utilisation des ressources minimisée par unité de consommation (par User Story par ex.) Ceci requiert d'avoir mis en place une solide architecture de couches découplées dans le produit logiciel.
  • Renewability: Renouvelement du système: votre code devrait pouvoir se renouveler lui-même et offrir de nouveaux services plus efficaces et moins cher quand ceux-ci seront disponibles.
  • Eliminer le concept de déchet: le déchet dans le logiciel ce sont les fonctions (features) qui ne servent à rien. Et le code mort (unreachable code). Et bien sur, pas une ligne de code sans tests!
  • Recherche de l'amélioration constante par le partage de la connaissance: encourager la communication directe entre les clients (consomm'acteurs) et développeurs (producteurs) du logiciel, mais aussi entre les responsables d'équipes, de projets, d'entreprises, les DSI, permettra de lier développement durable sur le long terme , responsabilité éthique et satisfaction des clients.
  • Connaitre et comprendre les limites de son propre design (vertu de la sagesse).

(1) quant au choix des sous-systèmes sur lesquels va se reposer tout ou partie de votre solution, qu'il s'agisse de bouts de code récupérés, d'objets ré-utilisables, APIs, services tiers, Frameworks ou librairies, Open Source OU PAS!!! soyez intransigeant et évaluez les points suivants auprès de votre fournisseur:
  • niveau d'abstraction: la vision que l'on peut extraire à la lecture des contrats de service
  • style d'apprentissage: le niveau de connaissance requis et le temps d'apprentissage pour être efficace en utilisant ces services/interfaces/objets
  • étapes de travail: combien de taches de programmation sont accomplies en une étape d'appel d'opération
  • évaluation progressive: est-il possible de (mieux) comprendre comment marche le service au fur et à mesure de son utilisation.
  • portée des engagements: le nombre de décisions que le développeur doit prendre dans un scénario impliquant l'utilisation de ce service, et leur portée.
  • pénétrabilité:  comment l'exposition du service permet d'explorer, analyser et comprendre le métier sous-jacent et l'effort qu'a à faire le développeur pour récupérer les informations dont (le service) a besoin pour fonctionner correctement.
  • viscosité: les barrières rencontrées et les changements (dans votre conception initiale) que va induire l'utilisation de ce service.
  • consistance:  voir en détail l'article http://docs.google.com/Doc?id=dhp3ggmx_38f58b3d
  • expressivité du modèle: comment apparaissent les relations entre les opérations entre elles, et les services entre eux également.
  • alignement avec le domaine/métier:  évidement un aspect essentiel dans l'évaluation d'un service.
  • résilience: capacité à fonctionner en mode dégradé et à se remettre en état de fonctionnement
  • découplage (visibilité des dépendances): la nature et la complexité des systèmes externes (objets, librairies, services, framework) nécessaire au fonctionnement de ce système, et la capacité à les changer sans toucher au code source (c'est à dire  laisser le choix de la dépendance  au consommateur du système et non à l'imposer).

Qui se soucie de l'empreinte environnementale d'un logiciel?

aujourd'hui, je crois à peu près personne. Et pourtant, si on convertit (cycle CPU + espace de stockage + débit réseau) x (cout énergétique kWh) en équivalent d'arbres sacrifiés ou mètres cubes d'eau déplacés, on commencerait peut être à refléchir que le tout numérique est aussi une source de pollution non négligeable.

Mais tant que nos sociétés ne sont pas encore passées au tout numérique, voila qui ne passionnera pas les foules, ni les responsables d'un tel gachi... faut-il pour autant attendre de faire beaucoup de dégâts  avant d'agir?

 

en attendant le BDD... Tester une application Asp.net MVC en 10 minutes

Février 9th, 2010

Lien: http://bit.ly/aX5vsU

pour ceux qui veulent mettre en place des tests rapidement et efficacement sur une application Asp.Net MVC... voici une version courte de mon précédent article.

A l'essentiel cette fois ci, ou comment mettre en oeuvre une politique de tests unitaires qui marche, et qui fait des vrais tests!

 

1) choix des fra mework

2) tests des vues

3) tests des contrôleurs

4) isoler (mock) les contrôleurs de leur partie métier (domaine)

5) inversion de contrôle pour fonctionner en test et hors test sans rien toucher

le détail est à lire ici:

http://bit.ly/aX5vsU

 

 

Bien Tester une application Asp.net MVC

Janvier 21st, 2010

Lien: http://docs.google.com/View?id=dhp3ggmx_168c5md3p52

 

Bien Tester ASP.Net MVC 1.0

Genèse

ASP.Net MVC est né avec plein de bonnes résolutions, et notament celle d' enfin permettre du test unitaire sur les applications Web programmées avec le framework.Net .

Je dis "enfin" car le Test ne passionne pas les foules, et pas vraiment les développeurs, encore moins les responsables ou les clients qui voient en lui une perte de temps ou source de coûts supplémentaires!

Evidemment - et paradoxalement- nos clients (ou parfois chefs de projets) aimeraient bien voir leurs applications garanties exempte de tout défaut, et donc testées, mais bien souvent n'imaginent pas que cela est possible à faire à moindre coût et par un automate.

Comme ils croient surtout que cela coûte trop cher (ou trop de temps) ils font donc passer à la trappe cette étape, qu'ils rejettent d'ailleurs -à tort- en fin de planning alors qu'elle devrait prendre place dès le tout début du projet en se fondant dans les spécifications (pour en diluer le coût).

Pour ce qui est des technologies .Net, on ne peut pas dire que le test ait été placé au coeur de la plateforme. Il a fallu tout de même attendre la version 4 du framework pour réaliser la notion de "code contract", notion omni-présente dans des langages comme Eiffel dont s'inspire pourtant largement C#.

Pour ce qui est de la programmation Web sur la plateforme Microsoft, les WebForms (ASP.Net classique) étant intestables dans leur coeur, il fallait introduire soi-même le pattern MVC, celui par qui le test est possible, ou utiliser un framework additionnel (Monorail par exemple, donc j'avais parlé ici il y a quelques années http://www.castleproject.org/monorail/index.html )

Heureusement, et presque 10 ans après l'apparition d'ASP.Net, Microsoft rend officiel l'utilisation du pattern MVC. Il était temps! Mais que de retard accumulé par rapport aux autres plateformes!

Aidé par un puissant site de présentation et d'aide aux développeurs ( http://www.asp.net/mvc/ ), les développeurs vont enfin pouvoir sortir du modèle "dictatorial" des Webforms et retrouver des façons de programmer le web plus "dans les normes", ou du moins, plus proches des autres frameworks (JSF, RubyOnRails, PHP, etc...)... et pouvoir enfin envisager de tester facilement et sereinement!

Pourtant, trouver des bons exemples de code de tests (TDD) pour ASP.Net MVC, relève du parcours du combattant: code obsolète, différentes releases de ASP.Net MVC, examples incomplets, y compris dans la doc officielle (et quand ca compile, on peut s'estimer heureux), informations contradictoires, besoin d'utiliser à la fois des Mock-ups et de de l'injection de dépendance.... de quoi décourager le plus motivés des adeptes du TDD comme moi.

Quasiment tous les articles qui datent de 2008 sont obsolètes (par exemple http://dotnetslackers.com/articles/aspnet/ASPNETMVCFrameworkPart2.aspx ) mais ils contiennent des idées qu'il faut assimiler.

Indispensable, la classe utilitaire donnée par Scott H. mais qui compile pas :((( http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx

... que d'embuches!

Quand on sait que l'approche TDD (et BDD) [Test Driven Development et Behavior Driven Development ] est la seule qui permette de GARANTIR qu'un logiciel est conforme à ce qu'on attend de lui (via l'écriture de spécification formelles), on a besoin d'y voir clair dans les tests.

Alors voici un article en français qui explique tout, simplement (j'espère), et dont les exemples compilent!

1 - Que faut-il pour tester?

un framework de test est indispensable. Mais lequel choisir? il y en a tellement....

pour comparer d'un point de vue pratique, vous pouvez consulter cette page:

http://xunit.codeplex.com/wikipage?title=Comparisons

mais chacun a ses préférences... difficille de faire un classement objectif et trouver des critères de notations entièrement acceptés par la communauté.

Pour ma part, j'ai choisi xUnit, uniquement pour sa simplicité

http://jamesnewkirk.typepad.com/posts/2007/09/announcing-xuni.html

voici quelques unes de ses caractéristiques:

· Single Object Instance per Test Method.

· No [SetUp] or [TearDown].

· Aspect-Like Functionality.

· Reducing the Number of Custom Attributes.

· [TestFixture] was removed entirely, so tests can be anywhere.

· [Ignore] is expressed using the Skip= parameter on [Test]

· [ExpectedException] was replaced with Assert.Throws.

· [TestFixtureSetup] and [TestFixtureTearDown] are instead expressed as implementations of an interface (ITestFixture).

· Support for IDisposable was added for tests.

2 - Tester, tester.... oui mais tester quoi?


Une application, qu'elle soit Web ou pas, est un ensemble composite.

Il y a multitude de choses qui s'y passe.

Quand on n'utilise pas de pattern et qu'on ne se pré-occupe pas d'architecture logicielle, tout est mêlé dans un code "spaghetti", souvent dans peu de fichiers qui font chacun des milliers de lignes. Dans ce cas, on va avoir beaucoup de mal d'effectuer des tests clairs.

Une Séparation des Responsabilités dans le code (SoC: Separation of Concerns), une architecture N-tiers, une approche Domain Driven, un couplage lâche, une architecture bien pensée, sont évidemment les pré-requis d'un bon projet guidé par les tests (Tests Driven Development).

Le pattern MVC va beaucoup nous aider, puisqu'il sépare le code de la vue, de celui du contrôleur, et du modèle.

Tester la vue en elle même

Pour ce qui est de tester le contenu d'une page HTML, qu'une zone de texte soit bien remplie par la bonne valeur, que la bonne CSS s'applique ou que le nombre d'éléments dans une boite déroulante soit conforme à ce que l'on attend, le Unit Testing n'est pas vraiment l'outil idéal.

Quoiqu'il existe des frameworks qui ont tenté de le faire : http://nunitasp.sourceforge.net/ projet abandonné, ou http://htmlunit.sourceforge.net/ mais pas de portage .Net à ma connaissance.

Il existe malgré tout des outils de tests qui agissent directement sur l'IHM et donc dans notre cas sur le navigateur Web , avec des capacités de comprendre ce qui se passe sur la page HTML (à l’aide de notre ami JQuery) comme le très puissant Selenium IDE ( http://seleniumhq.org/ ) qui va vous générer le code NUnit de test des pages Html à intégrer dans votre solution .Net.  Malheureusement vous serez dépendant d’un serveur Web pour effectuer vos tests, et le principe d’isolation des tests unitaires n’est pas respecté.

En attendant la solution qui comble la brèche…

Tester qu'une vue s'affiche bien

C’est assez trivial mais c'est un début :

[Fact]

public void ReturnsViewResultWithDefaultViewName()

{

// Arrange

var controller = new HomeController();

// Act

var result = controller.Index();

// Assert

var viewResult = Assert.IsType<ViewResult>(result);

Assert.Empty(viewResult.ViewName);

}

Cela permet de vérifier que vous n'avez pas fait de grosses erreurs dans le montage de votre solution Asp.Net MVC. Malheureusement ca ne teste pas des erreurs éventuelles dans le fichier de vue (.aspx)

Notez au passage le tryptique classique d'une méthode de test 1)Arrange 2)Act 3)Assert.

Si votre contrôleur fait passer des bouts de données à la vue par l'intermédiaire du dictionnaire ViewData , il vous suffira de rajouter une ligne:

Assert.Equal("Welcome to ASP.NET MVC!", viewResult.ViewData["Message"]);

Toujours trivial. Et relativement peu utile.

La bonne pratique est d'utiliser une vue fortement typée, ce qui donne quelque chose comme ca dans l'entête de la déclaration de votre vue:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage<ManagePassword.Domain.OperationResult>" %>

ManagePassword.Domain est la librairie de domaine de notre application, et OperationResult est l'objet Modèle (au sens MVC) qui va transiter entre la vue et le contrôleur.

Notre test pourra déjà s'assurer que le contrôleur renvoie bien un objet de ce type là.

// ASSERT

Assert.NotNull(results);

Assert.NotNull(results.ViewData.Model);

var res = Assert.IsAssignableFrom<OperationResult>(results.ViewData.Model);

L'idée d'avoir un modèle déterminé (et donc fortement typé) afin de pouvoir passer de multiples valeurs et tester ce que le contrôleur va retourner à la vue.

Par exemple, on a souvent besoin d'une page qui fait le résumé de l'opération qui vient d'être demandé, et un modèle simple (mais récurrent) pourrait être:

public class OperationResult

{

public bool isOk;

public string errorMessage;

}

Notre test va pouvoir porter maintenant sur les membres du Model, et donc faire plus de vérifications.

// ASSERT

Assert.NotNull(results);

Assert.NotNull( results.ViewData.Model);

var res = Assert.IsAssignableFrom<OperationResult>(results.ViewData.Model);

Assert.Equal(false, res.IsOk);

Tester les redirections

Une redirection peut avoir lieu dans votre contrôleur, la tester permet de savoir par quel point ^de code le contrôleur a terminé son exécution. Pour cela le code de test ressemblera à ceci :

///ACT

var results = controler.ChangePassword(userInfo) as RedirectToRouteResult;

// ASSERT

Assert.True(controler.ViewData.ModelState.IsValid);

// permet de tester que c'est bien un RedirectToRouteResult qui a été retourné (à cause du AS plus haut)

Assert.NotNull(results);

La ligne 1) ne plantera pas au cas où le code du contrôleur ne renvoi pas un objet de redirection ( ). Par contre Assert.NotNull(results); génèrera un échec du test car en cas d’echec du cast par AS, la variable contient le pointeur vers Null.

Pour rappel, une méthode de test ne doit attendre qu’un seul comportement possible.

Si vous voulez tester le cas où le contrôleur ne fait pas d’indirection (et renvoi des valeurs via le modèle), écrivez alors une autre méthode de test pour ce cas là. Attention à ne pas mettre de logique  IF… ELSE…  dans une méthode de test. Car cela est banni.

Dans la vraie vie, le but du programme est de faire en sorte que le Contrôleur appelle un (ou plusieurs) objets du domaine avec un minimum de logique (car la logique doit être dans le domaine). Le contrôleur s’occupe de la logique nécessaire pour préparer l'affichage (et donc le Modèle pour alimenter la vue), et c'est de cela dont il va falloir maintenant s’occuper.

Tester le contrôleur tout seul

Comme je le disais plus haut, la meilleure pratique nous conseille de déporter la logique du domaine (que l'on appelle souvent Métier en France) de l'application.

Hors, dans une démarche de test, la meilleure pratique est de ne tester d’une seule chose à la fois (isolation du test).

Si nous testons le contrôleur, nous devons ne tester que les appels de code dans son corps et non pas tous les objets dont il dépend et/ou auxquels il fait appel.

Il va donc falloir « débrancher » le Contrôleur de tout ce qui pourrait parasiter le test.

Comment faire sans écrire du code compliqué, et surtout sans toucher au code du contrôleur qui doit être transparent au test ? On ne doit pas changer le code de ce qui doit être testé pour le rendre testable ! Sinon le test est biaisé.

Les 2 choses typiques à débrancher sont : le ou les objets de domaine (ou système d’accès aux données), et le contexte sous-jacent au contrôleur (routage, requête http, contexte session, etc.).

Pour ce dernier, ASP.Net MVC est assez bien fait et les dépendances en place n’empêchent pas les tests de fonctionner en isolation, c'est-à-dire sans la présence d’un serveur HTTP.

Ceci dit, si on a besoin de tester le comportement d’un contrôleur en fonction de ce qui peut se passer au niveau Requête HTTP par exemple, on a la possibilité de fournir un faux contexte HTTP.

Vous trouverez de quoi réaliser ceci avec une classe d’aide aux tests, que vous devrez intégrer dans le projet de test : MvcMockHelpers

Vous en trouvez le code ici : http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx

Elle vous propose (entre autres) un FakeHttpContext que vous brancherez à votre contrôleur avec une méthode d’extension, comme celle ci :

controler.SetFakeControllerContext();

Cette classe repose sur un  framework de Mock-up. Le code donné fonctionne avec différentes librairies : RhinoMocks, TypeMock ou Moq.

Personnellement j’ai choisi Moq, car c’est le plus « fluent » au niveau API, sans être abscon, et celui qui a la syntaxe la plus claire pour spécifier le comportement des bouchons, mais nous allons le voir plus loin.

Le seul (petit) problème c’est que cela peut ne pas compiler. Il vous faudra chercher un certain moment sur le net avant de trouver ce « hack » :

http://stackoverflow.com/questions/205644/error-when-using-extension-methods-in-c

et qui vous conseille d’ajouter ces quelques lignes de code au fichier dans lequel vous aurez mis le MvcMockHelpers:

namespace System.Runtime.CompilerServices

{

/// <summary>/// to avoid the following error: Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor'

/// </summary>

public class ExtensionAttribute : Attribute { }

}

Les méthodes d’extension SetHttpMethodResult et SetupRequestUrl vous seront bien utiles pour tester le comportement de votre contrôleur quand l’invocation se fait par une méthode HTTP GET ou HTTP POST, ou si son code vérifie l’URL demandée.

Bouchons à la rescousse

Mais une bonne partie du comportement d'un contrôleur repose sur l'appel à (et sur les réponses fournies par) un ou plusieurs objets de domaine.

Personnellement je mets toute la logique de mon application dans ces objets et je ne fais pas d'appel aux données directement. Pour ceux qui font le contraire,  la logique de tests est de toute façon la même. Pour que le test puisse tourner indépendamment (sur un serveur de Build ou dans Gallio Icarus par exemple), il ne faut pas de liaison à une base de données ou à tout autre système externe.

C'est aussi pour cela que passer par des objets de domaine, même s'ils ne font que du CRUD, va simplifier le code dans le contrôleur et donc faciliter les tests.

L'avantage majeure résidant dans ces objets de domaine, puisque c'est nous qui les écrivons "à la main", c'est d'avoir une interface que les bouchons vont exploiter.

Je ne vous fais pas l'affront d'expliquer pourquoi une interface est bonne pour votre architecture.

Tout ce qui est à l'extérieur de notre  contrôleur à tester devrait avoir une interface. C'est le cas par exemple d'un Web Service. Quand vous allez vous brancher à une Web Reference, Visual Studio va avant tout construire une Interface (au sens C#) et vous allez pouvoir travailler avec celle-ci.

De toutes façons, il est aisé d’admettre (ou de constater) que tous les frameworks de bouchonnage (mockup) vont exiger une interface afin de pouvoir travailler, donc vous n'avez pas le choix.

Partons du cas où nous avons été de bons élèves et où nous disposons d'une IquelqueChose pour nos objets de domaine (Si ce n'est pas le cas, un petit coup de refactoring et en 3 secondes nous auront ce précieux fichier).

Armé de cette précieuse Interface, donc, vous la passerez en carburant au constructeur du Mock. Avec Moq, cela ressemble à ceci :

//Arrange

// create the mock

var mockRepository = new Mock<IDomainManagingPasswords>();

L’idée est ensuite de faire passer au contrôleur, un objet factice fabriqué par le mockRepository, qui va répondre à l’interface voulue.

Donc vous aurez à modifier le code du contrôleur pour qu'il travaille non plus avec une instance interne du (ou des) objet de domaine, mais avec une référence sur l'Interface, et fourni à l'extérieur du contrôler.  C’est la seule chose que vous devez modifier dans votre contrôleur pour le rendre testable, mais à bien y réfléchir, c’est plus une façon de programmer qu’une contrainte donnée par la démarche de test. Je m’en expliquerai dans un prochain article sur la qualité du code et les enjeux du test dans l’optique de la programmabilité et de la maintenabilité du code.

Cette différente façon de faire consiste à très fortement découpler les objets entre eux. A bien y réfléchir, un objet (ici le contrôleur) a toujours besoin d’un (ou plusieurs) autre objet pour réaliser le comportement attendu. Ne serait-ce que parce que nous avons à notre disposition foultitude d’objets prêt à être réutilisés.

Pour ce faire, nous avions souvent l’habitude d’instancier ces objets tiers, au moment où nous en avions besoin. Parfois, au mieux, nous procédions à leur instanciation/initialisation dans le constructeur de l’objet qui en fait usage.

Ce n’est pas une bonne pratique, car cela ne laisse aucun contrôle sur ces objets (comment ils doivent être initialisés, etc). Il est donc plus profitable (et pas que pour des besoins de tests) de passer des pointeurs sur ces objets au moins au constructeur de celui qui en fait usage, et voir même à chaque méthode dans certains cas.

Pour notre contrôleur cela donne ceci :

private readonly IDomainManagingPasswords _domainObject;

/// <summary>

/// constructeur avec parametre pour accepter le Mocking...

/// </summary>

/// <param name="domainObj">The domain object.</param>

public ManageController(IDomainManagingPasswords domainObj)

{

_domainObject = domainObj;

}

Ensuite à l’intérieur des méthodes du contrôleur, on utilise librement la variable _domainObject comme si de rien n’était.

Cette variable sera occupée par l’objet bouchon lors du test, et cela nous permettra d’ordonner au bouchon d’avoir un comportement A ou B, selon les besoins du test.

Les possibilités donc de « jouer » avec le test sont maintenant très nombreuses.

Par contre, il faut que le contrôleur continue de fonctionner dans son environnement initial, à savoir lorsque le site Web fonctionne dans IIS ou Cassini (ou Apache). Et dans ce cas, le framework Asp.Net MVC s’occupe d’initialiser les contrôleurs, et pour cela il appelle le constructeur sans paramètre de chacun ; ce qui est bien normal, car il n’est pas capable de décider quelle instance d’objet tiers lui passer.

Et évidement, dans ce contexte, on ne travaille plus avec les bouchons mais avec les implémentations « qui marchent » !

Alors comment faire ?

Inversons le contrôle

Il faudrait avoir un mécanisme qui de manière transparente à tout mécanisme (je pense en particulier au mécanisme d’initialisation de Asp.Net MVC, puisse instancier lui-même les objets « qui marchent » et les donner à ceux qui s’en serve.

Dans notre cas, il s’agit de faire passer des objets de domaine correctement instanciés et initialisés, aux constructeurs des contrôleurs lorsque ceux-ci sont mis en route par l’infrastructure de Asp.Net MVC, sur laquelle bien sur nous ne pouvons pas opérer de modification de comportement, puisque le code ne nous appartient pas et qu’il est déjà compilé.

C’est là où l’Inversion Of Control (IoC, tellement plus chic) entre en scène et trouve une de ses nombreuses utilités.

L’idée initiale de l’AOP (qui a inspiré l’Injection de Dépendance) était de permettre au développeur de supprimer la plomberie dans son code, c'est-à-dire sortir toutes les lignes de code qui n’avaient pas vraiment attrait à son algorithme mais qui étaient nécessaires ; sans quoi, justement, les objets dont il dépendait (accès aux données ou à une information tierce) ne pouvaient pas opérer comme il le souhaitait.

Dans le cas du test d’un projet Asp.Net MVC avec de l’injection de dépendance, vous trouverez foison d’exemples et de frameworks.

Quelques points d’entrées :

http://www.mikesdotnetting.com/Article/117/Dependency-Injection-and-Inversion-of-Control-with-ASP.NET-MVC

http://www.rickardnilsson.net/post/2009/12/25/Dependency-injection-in-ASPNET-MVC-with-Unity-IoC-Container.aspx

http://scottfindlater.blogspot.com/2009/11/tdd-mvc-12-inversion-of-control-ioc.html

http://codeclimber.net.nz/archive/2009/02/05/how-to-use-ninject-with-asp.net-mvc.aspx

Mais nous voulons rester pragmatiques, et le problème qui nous intéresse ici est « comment faire en sorte que le contrôleur obtienne un objet de domaine correctement instancié et initialisé quand le projet tourne en mode non-test, c'est-à-dire avec un constructeur sans paramètre ? ».

Mon critère est assez simple : j’ai retenu la solution qui m’oblige à écrire le moins de code possible, qui soit la moins intrusive dans le code existant, et qui m’épargne des lignes de configuration XML qu’on ne sait jamais comment écrire correctement (et auxquelles ont préfère une API fluente, qui permette à l’Intellisense de nous guider intuitivement dans l’usage des objets exposés).

StructureMap est l’un d’entre eux.

Nous avons écrit plus haut un contrôleur MVC doté d’un constructeur avec paramètre qui permet de faire passer une instance d’un objet de domaine.

Hors la fabrique de contrôleurs que Asp.Net MVC utilise en interne ne sait instancier les contrôleurs qu’en utilisant un constructeur sans paramètre. Il faut donc fournir une autre fabrique plus souple.

Heureusement que Scott et son équipe ont tout prévu, et que nous pouvons surcharger la fabrique de contrôleurs par défaut (DefaultControllerFactory) en préparent une autre comme ceci :

using System;

using System.Web.Mvc;

using StructureMap;

namespace yourProject

{

public class DependencyControllerFactory : DefaultControllerFactory

{

protected override IController GetControllerInstance(Type controllerType)

{

return ObjectFactory.GetInstance(controllerType) as Controller;

}

}

}

L’ObjectFactory permettra à StructureMap de résoudre les dépendances et trouver la bonne implémentation concrète de tous ce qui présente une interface remplaçable à la volée par un objet concret.

Ce nouveau Controllerfactory sera enregistré dans la logique Asp.Net MVC en ajoutant une petite ligne dans Global.asax.cs, dans Application_Start() plus précisément :

ControllerBuilder.Current.SetControllerFactory(new DependencyControllerFactory());


Et   juste ensuite (toujours dans Application_Start) nous préciserons à  StructureMap quel mapping opérer entre les interfaces et les implémentations concrètes, comme ici :

ObjectFactory.Initialize(registry => registry

.ForRequestedType<IDomainManagingPasswords>() .TheDefaultIsConcreteType<DomainManagingPasswords>());

Et voila!

C’est assez simple, notez juste que dans cet exemple, mon classe d’implémentation concrète DomainManagingPasswords disposerait d’un constructeur sans paramètre. Pour les cas plus complexes, lire la documentation ici : http://codebetter.com/blogs/jeremy.miller/archive/2008/08/20/smartinstance-in-structuremap-2-5.aspx

Il y a des frameworks IoC qui sont plus explicites encore, et qui vous laissent choisir quelle implémentation viendra s’injecter selon telle ou telle condition.

Cela peut être aussi en intéressant à utiliser si vous voulez par exemple, changer un fournisseur de données par un autre, à la volée dans votre programme.

http://www.iridescence.no/post/Inversion-of-Control-ASPNET-MVC-and-Unit-Testing.aspx

Mais y-a-t-il plus simple ?

Sortir les patterns qui vous font passer pour le roi de la programmation est parfois superflu.

Le crédo est d’être économe, de n’utiliser que ce dont on a besoin. Pourquoi lancer toute la machine d’un IoC, sinon à passer pour un érudit ?

Dans notre cas, nous avions simplement besoin de fournir à la factory par défaut de construction des Contrôleur Asp.Net MVC, un constructeur sans paramètre (tout en gardant celui avec paramètre qui sert aux tests).

Il suffisait d’écrire ce constructeur, et c’est lui qui se chargeait d’instancier l’objet de domaine concret répondant à l’interface IDomainManagingPasswords :

public ManageController()

{

_domainObject = new DomainManagingPasswords();

}

Un bien pour un mal. En faisant cela nous économisons toute la coûteuse introspection qu’opère un Injecteur de Dépendances, mais nous introduisons avant compilation du couplage très fort entre nos classes…

Retour au test, comment pousser le bouchon plus loin ?

Maintenant que nous savons comment faire pour préparer notre objet testé (le contrôleur) pour pouvoir fonctionner de manière identique dans un cas de test ou dans un cas de non-test, voyons comment spécifier le comportement des bouchons pendant le test.

C’est la que notre ami Moq refait surface, et nous permet de piloter le comportement de l’objet « bouchon ».

// create the mock

var mockRepository = new Mock<IDomainManagingPasswords>();

Je veux que lorsque la méthode X mon contrôleur fera appel à la méthode FindUserInAdam de l’objet de domaine qu’elle emploie, et quelque soit la valeur des paramètres, il me retourne une valeur de mon cru, rien de plus simple :

mockRepository.Setup(cr => cr.FindUserInAdam (It.IsAny<string>()))

.Returns(new resultOfSearchingUser

{

errorMessage = "test error",

codeResult = codeResult.NotFound

});

Ce qui se lit (donc se programme) aisément :

Permet de poster les choses.  La lambda expression permet d’exprimer ce qui se passera en cas d’appel à la méthode voulue. Les arguments sont gérés aussi par Moq. It est un objet pratique qui permet de dire « Ceci » est une valeur « peu importe » de type string : It.IsAny<string>().
Ou d’autres formules (une regex par exemple).
Lexpression qui s’en suit dit quoi faire quand la méthode sera réellement invoquée. Ici c’est un retour (Returns) d’une valeur assemblée de toute pièce pour les besoins du test (new resultOfSearchingUser).

N’oubliez pas que les Mocks sont des objets creux, ils répondent à une interface mais ne font rien. Donc à vous de programmer leur comportement.

On pourrait vouloir tester comment le contrôleur réagit si l’objet Bouchon de domaine renvoit une exception. Là aussi, c’est assez simple à exprimer :

mockRepository.Setup(cr => cr.FindUserInAdam (It.IsAny<string>()))

.Throws(new System.OverflowException("test error"));

Pour terminer, on n’oubliera pas de donner en carburant cet objet bouchon au contrôleur avant de lancer (ACT) l’opération à tester:

//bind the mocked object to the controller

var controler = new ManageController(mockRepository.Object);

///ACT

var results = controler.DoFindUser() as ViewResult;


A partir de là, vous avez toutes les billes en main pour tester tout ce que vous pouvez imaginer.
C’est d’ailleurs cette trop grand liberté qui peut être désarmante, et on cherche une méthode pour savoir quoi écrire comme cas de test. La réponse est 2 paragraphes plus loin.

Tester le Modèle

le "Modèle" en tant que structure de données que l'on passe du contrôleur à la vue ne se teste pas en lui-même. Par contre c'est le "fournisseur du modèle" c'est à dire l'objet que vous devez invoquer (et que nous avons substitué par un Mock) qui doit être testé pour lui-même.

A ce moment là c'est un projet de test autour des classes de domaine (classes métier pour ceux qui préfèrent ce terme) aux quelles il faut ajouter une batterie de Tests Unitaires "classiques" pour vérifier leur comportement.

Tout ce que je viens de dire sur les contrôleurs s’applique évidement aux classes de domaines. Elles doivent elles-aussi être fournie avec un jeu de test « en isolation complète ».

3 - Plaidoyer pour une approche Comportementaliste (BDD)

Si vous êtes en mal d’inspiration pour écrire vos tests, voici une idée qui pourra faire son chemin…

Le Behavior Driven Development (ou développement conduit par le comportement et donc les spécifications) devrait être LA façon de programmer universelle.

Affirmer aujourd'hui que la programmation d'un logiciel ne peut se faire qu'en fonction des spécifications passe pour une vérité des plus banales.

Or, jusque là, personne ne s'était occupé de rendre vérifiable, "prouvable" une telle démarche. Le développeur écrivait donc son programme, bon an, mal an. Et vérifiait une fois déployé (en général lors de la préparation de la recette ou de lors de la recette elle même) si le logiciel produit était bien conforme aux spécifications.

Entre écriture des spécifications (en majorité sous forme littéraire) et code (forme "machine", c'est à dire langage de développement) il y a un certain écart, pour ne pas dire un gouffre.

Ce que propose l'approche BDD c'est d'éliminer purement et simplement tout écart.

Et d'écrire les spécifications de manière formelle (donc dans une langue compréhensible par l'ordinateur) et reliée au langage du développement.

Ainsi un automate (un framework de tests unitaires est préposé à cela) peut relier la vérification des spécifications ainsi décrites au code réellement produit.

Le tout, de manière systématique, automatique, constante et répétée (dans le cadre d'une usine logicielle bien construite).

Ce ne sont pas les ressources qui manquent sur le net pour vous expliquer que faire du BDD c'est bon pour vous, essayez par exemple http://behaviour-driven.org/

Ou lisez Dan North, qui est celui qui a posé l'article fondateur : http://dannorth.net/introducing-bdd

Pour ma part, je vous proposerai bientôt un article entièrement consacré au sujet, autour d'une exemple concret bien entendu.

Le BDD est présenté par beaucoup d'éminent spécialiste comme l'aboutissement des méthodes SCRUM et XP

http://www.code-magazine.com/Article.aspx?quickid=0805061

Cette approche est également la plus fidèle à la notion d'Agilité, puisqu'elle permet d'exploiter à 100% les efforts faits en matière de spécification par UserStories et Scenarios.

Mais si elle est légion en Ruby et Python, si on la trouve beaucoup en Java, il faut dire que .Net est à la traine. Et c'est quelque peu frustrant voir même insultant (n'avons nous pas le droit de faire de meilleurs logiciels?)

Cela me rend plutôt inquiet, .Net est-il une plateforme laissée aux seuls Geeks et bricoleur de l'informatique? ou aux sociétés de service pressées de faire du chiffre et ne mettant pas vraiment l'accent sur la qualité logicielle?

Toujours est-il qu'il faut se lever tôt pour trouver un framework prêt à l'emploi, qui fonctionne (sic), et simple à prendre en main (re-sic) pour la plateforme .Net

Beaucoup de projets sont abandonnés en phase initiale (BDD Extensions project on Google Code.)

J'ai essayé de tester tout ce qui était compilable et seul NBehave semble tenir ses promesses; mais comme vous pouvez le voir dans cet article, l'écriture reste peu lisible hélas http://pebblesteps.com/post/Behavior-Driven-Development-with-NBehave.aspx

les BDD extensions de xUnit semblait offrir une forme plus sympathique à lire, mais bon.

Il y avait des initiatives très prometteuses comme  MisBehave, basé sur M et Oslo... mais là encore aucun engouement, ni de la part de la communauté ou des têtes pensantes chez Microsoft (d'ailleurs, que devient M à part un textual DSL pour de la modélisation de données).

Il faudra attendre que la communauté .Net se (re)mobilise et trouve enfin de l'intérêt à faire du BDD pour voir naître un framework nous donnant vraiment envie de faire du comportementalisme et que cette pratique n'apparaisse plus comme une perte de temps, alors que justement c'est le contraire qui devrait en résulter.

4 - D’autres exemples ?

Un projet complet TDD avec MVC plus NHibernate est à découvrir (avec des pages Wiki complètes) sur http://sharparchitecture.net/

Allez voir aussi sur http://scottfindlater.blogspot.com/2009/10/tdd-mvc-adventures.html

Enjoy!


 

pour les brèves, préférez Twitter

Janvier 21st, 2010

Lien: https://twitter.com/guillaume_agile

finalement, Tweeter s'avère parfait pour les reflexions instantannées, je vous invite donc à me suivre aussi là bas

https://twitter.com/guillaume_agile

 

et ici, toujours des articles de fond et/ou pratiques ; comme le prochain sur le Test avec Asp.Net MVC

de la réalisation à la production

Décembre 7th, 2009

je m'amuse souvent (et pas forcement innocement)  à faire le parralèle entre mon métier actuel de "faiseur de logiciel" et mon passé d'étudiant en cinéma et audio-visuel  (passé trop court, mais les contraintes matérielles de ce bas monde et quelques autres paramètres en ont décidé autrement).

Déjà, j'ai beaucoup de mal à répondre à la question "quel est ton métier?"... j'avoue que je déteste répondre "ingénieur informaticien" ou autres "ingénieur en développement informatique" car cela met une trop grande distance entre mon interlocuteur et moi.
Et puis le pauvre bougre n'en est pas moins renseigné sur la nature même de mon travail. J'obtiens au mieux l'étiquette de "Geek" au pire celle de l'ingénieur intello qui a fait de longues études, ou carrément la moquerie traditionnelle relayée par la fameuse video Youtube que je pense tout le monde connait ici (au cas où: http://www.youtube.com/watch?v=ZdEcyk5G80s ).
Et si la question qui s'en suit est: "tu travailles pour Microsoft?" alors j'ai vraiment tout faux.
C'est pour cela que je contourne un peu la question, et je change ma version....  "je fabrique du logiciel", et déjà cela attire un peu plus la curiosité de mon interlocuteur. "tu fais des sites Web " me demande-t-on parfois, et évidement cela me fait plaisir, car je peux me lancer dans l'explication qu'il n'y a plus de frontière entre logiciel et sites Web.
"fabriquer" est pourtant un terme vague et je lui préfère celui de "réaliser" qui me met en position de réalisateur. On comprend assez bien toute la portée du mot "réalisateur", qui parfois renvoie à "créateur".
Mais créateur a cette notion un peu supérieure de "création", qui pourrait faire paraitre quelque peu présomptueux, bien que j'aime assez souligner que nous faisons un métier qui n'est pas dépourvu de dimension "créative".
Réalisateur, c'est pourtant un terme qui fait de suite penser au monde du cinéma et de l'audiovisuel. Et je m'y retrouve assez bien finalement. Un réalisateur est amené à réaliser différents projets, du film de commande à l'oeuvre plus personnelle, du film publicitaire au long métrage blockbuster, en passant par le film d'entreprise... ou de mariage ;)
Un bon réalisateur de films est celui qui a appris tous les métiers intermédiaires: cadreur, monteur, preneur de son, mixeur, directeur d'acteur, constructeur de décors, inventeur d'effets spéciaux, scénariste. Il peut d'ailleurs sur certains projets cumuler certains (voir la totalité) de ces rôles.
Il est en de même pour le logiciel: codeur, testeur, analyste, architecte, documenteur (documentaliste?)...
Le réalisateur peut travailler seul sur des petits projets ou , et surtout, en équipe dès que le projet le demande.
Il devient donc un pilote d'hommes. Le terme chef de projet n'est pourtant pas très communément admis dans le monde audiovisuel (en France du moins).
D'ailleurs ce rôle ressemblerait plus à celui du producteur: l'homme qui orchestre le projet de film, qui met les hommes aux services des hommes et du projet.
Et qui assume tout ou partie de la responsabilité financière aussi.
Mais vous aurez tous remarqué que dans toute production audiovisuelle (cinema et tv), il n'y a jamais un seul producteur. Il se fait entourer d'une palanquée de producteurs exécutifs, associés, délégues, généraux, sous producteurs, etc... Ce sont des équipes entières de production qui s'occupent d'un projet.
Là dessus, nous, pauvres faiseurs de logiciels, avons peut être quelques leçons à prendre...
Intéressant de voir divers points de vue sur le métier de producteur: http://www.youtube.com/watch?v=r2v2dht1teI
très étonnant comment le dernier lien va parler à tous ceux qui se sont frottés au rôle de chef de projet informatique, mais cela va vraiment au delà (et c'est surement plus intéressant en cela)
Et il apparait qu'une bonne traduction du stakeholder des méthodes agiles, serait le producteur.
Le Producteur représente le Produit (même racine), et derrière le produit viennent ceux qui vont l'utiliser. Le producteur comme ambassadeur à la fois d'un besoin exprimé mais aussi d'une émergence, d'envies implicites, de besoins sous-jacents. Il va jauger du marché, des attentes, des potentialités.
Idéalement son rôle ne s'arrêterait pas à la sortie du produit mais va aussi essayer ensuite de vendre le produit et de le faire se diffuser, d'aider ceux qui vont l'utiliser à vraiment le posséder, à s'investir dans le logiciel livré (accompagnement au changement).
Bref un rôle d'accompagnement indispensable et qui ne peut retomber sur les épaules d'une seule personne mais sur une équipe.
Et un tandem: le réalisateur et le producteur devraient être les 2 piliers d'un projet logiciel comme ils le sont depuis de nombreuses décennies dans le monde audio-visuel, qui possède lui aussi cette dualité "industrie-artisanat";
2 monde professionnels qui se rejoignent sur bien des points...

 

parlons du futur un peu....

Novembre 20th, 2009

Comme ils nous cassent tous les oreilles avec ChromeOS (ok, j'aime Android et j'assume), n’oublions pas que MS va aller beaucoup plus loin qu’un simple Linux revampé et des WebApps (même si c’est l’avenir) tournant sur un omni-navigateur (Chrome+Gears)

 

Un article de référence pour soutenir mes propos:

http://www.sdtimes.com/MICROSOFT_S_PLANS_FOR_POST_WINDOWS_OS_REVEALED/About_CLOUDCOMPUTING_and_MOBILEDEVELOPMENT_and_NET_and_SOASAAS_and_SOFTWAREDEVELOPMENT_and_WINDOWS_and_MICROSOFT/32627

Peut être vous saviez déjà que ca s’appelle Midori, mais le modèle de programmation va changer :

 

The Midori programming model will tackle state management, which Microsoft admits in its documentation is a challenge in Windows, by migrating APIs, applications and developers to a constrained model.

Là où ca devient palpitant (pour les développeurs):

Other objectives are eliminating dynamic loading and in-process extensions; developing a failure model based on reliable transactions, so the system understands exactly which processes are impacted by a cascading failure and how to restart the computation; and having a standard way of dealing with latency, asynchronous behavior and cancellation, throughout the stack.

Un OS intelligent qui se protégé tout seul des plantages et qui arrête de faire confiance aux programmes qu’il execute ? comme par hasard, c’est aussi l’idée de Google dans ChromeOS

 

Mais, plus de protection, et donc plus de contrôle = moins de souplesse

restricting dynamism at the OS level will not impact dynamism at the programming level.”
ouf, on est sauvés!

 

Et OSLO pourrait revennir sur le devant de la scène :)

 

In a possible link to Microsoft’s Oslo composite application initiative, the programming model will have a dependence on metadata, with the aim of allowing the system to more reliably manage applications.


the proposed OS would have a non-blocking object-oriented framework API. This would have strong notions of immutability—in the sense of objects that cannot be modified once created—and strive to foster application correctness through deep verifiability by using .NET programming languages.

Un OS orienté objet et transactions? On en rêvait….

Mais la concurrence est là:

“A lot of these problems are being solved, at least partially, by the ideas of store-and-forward and message synchronization,” Hammond noted. “Google Gears, Adobe AIR, even the mobile OSes with things like SMS can handle occasional connectivity. Why shouldn’t this be built into core OS communication protocols, especially if they are asynchronous by default?” he asked.

Qui sera le vainqueur des OS de demain ? non pas de savoir quel éditeur car il s’agit d’une guerre commerciale… mais quelle technique ?

Y-a-t-il un futur pour la recherche sur les OS tels que nous les connaissons aujourd’hui, et donc pour les suites de Windows… (ou MacOs)

Ou bien l’OS va-t-il devenir le grand perdant de cette bataille, et toutes les nouveautés ne seront-elles pas reportées sur les omni-navigateurs (ou plateforme applicatives virtualisées comme pourra le devenir Air ou même Eclipse), sur les interpréteurs et sur les petits moteurs de synchronisations comme Gears. Mais qui laisseront l’OS à une place dérisoire, et qui n’intéressera plus aucun développeur…

A lire : Une très intéressante présentation des principes de Singularity (mais vieille de 2006 !) :

http://research.microsoft.com/en-us/um/redmond/events/fs2006/presentations/23_Hunt_071706.ppt

http://research.microsoft.com/en-us/projects/singularity/

 

la guerre continue: http://blogs.zdnet.com/microsoft/?p=4650&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+zdnet/microsoft+(ZDNet+All+About+Microsoft)&utm_content=Google+Reader

mais Microsoft fait toujours office de suiveur... dommage

 

Agile Development From A Developers Perspective

October 14th, 2009

je ne saurais trop vous recommander de jouer cette brillante (et agile) présentation, pour vous développeurs, pour un chef de projet, pour un architecte...

Tout est excellement condensé. Le MUST de l'application des bonnes pratiques de conduite d'un projet de développement logiciel, et de méthode de réalisation (TDD, intégration continue, code quality metrics,  acceptance tests, etc...)

http://www.slideshare.net/rbanks54/agile-development-from-a-developers-perspective

 

faites le savoir!

Agile Tour 2009: c'est parti! ... et aussi à Toulouse

October 8th, 2009

pour tous ceux impliqués de près ou de loin dans l'adoption de démarches Agiles, et surtout pour ceux qui se demandent quel est cet oiseau bizarre, et qui voudraient bien en savoir plus, il n'y a qu'un rendez vous:

c'est l'Agile Tour 2009 partout en France!

et en particulier à Toulouse où pas moins de 20 sessions vous attendent:  retours d'expériences, conférences, ateliers, présentation d'outils, débats!

les échanges seront riches et nombreux.

Une journée que vous ne serez pas près d'oublier ...

le programme et les inscriptions Toulousaines se font ici: http://www.agiletour.org/fr/at2009_toulouse_programmation.html

http://www.agiletour.org/fr/at2009_toulouse_inscription.html

affichage agile tour toulouse

appels aux orateurs

September 4th, 2009

l'Agile Tour 2009 se dessine et nous recherchons des orateurs sur le sujet

Je fait partie de l'équipe d'organisation de Toulouse et c'est aux sudistes que je m'adresse en particulier.

L'édition de cette année est orientée sur les retours d'expériences, n'hésitez donc pas à venir partager les votres!

Tous les détails pour s'inscrire (en orateur ou auditeur) sur le site http://www.agiletour.org/

Ou si vous cherchez à mettre au point un sujet à plusieurs, n'hésitez pas à me contacter.

 

Bonne rentrée agile à tous.

les conseils beauté de vos présentations (slides, keynotes, prez)

Août 21st, 2009

Pour finir vos devoirs de vacances, je vous propose des petits idées pour améliorer les présentations PPT que vous êtes parfois amenés à faire.

Les règles d’une présentation PPT réussie :

Le texte à l’écran ne doit JAMAIS être le texte récité par le présentateur.
Le slide est un support à la narration, il doit présenter des éléments visuels qui NE SONT LA QUE POUR soutenir ce que dit le présentateur.
Il ne faut pas endormir l’auditoire.
DONC
• Des textes très courts et écrits gros
• Des belles images qui marquent ! (ne pas hésiter à aller sur Flickr pour prendre des jolis clichés, ils sont souvent en Creative Common Licence, par ex http://www.flickr.com/photos/lucas3d/3794517546/ )
• Il vaut mieux 100 slides avec 3 mots dans chaque, que 3 slides avec 100 mots.
• Utiliser une charte graphique
• Utiliser un police agréable à lire en gros
• Utiliser HABILEMENT les couleurs pour mettre en évidence un mot en particulier dans une slide, tout en gardant une charte de couleurs cohérente et sobre
• Une SEULE phrase et un SEUL concept par slide
• Un concept compliqué s’explique sur PLUSIEURS slides
• Pas d’animation dans les slides
• Si vous voulez faire apparaitre ou disparaitre des éléments, dupliquez le slide autant de fois que nécessaire pour faire l’effet
• Votre présentation doit faire entre 60 et 100 slides, en passant au max 10 à 20 secondes par slide

Une excellente prez sur le TDD
http://www.slideshare.net/bencarey/beyond-tdd

ma préférée (graphiquement) sur les CSS
http://www.slideshare.net/stubbornella/object-oriented-css

une très bonne sur l’agilité
http://www.slideshare.net/eig/agile-software-development

plus de texte, mais quand meme des bonnes idées gfx
http://www.slideshare.net/jurgenappelo/what-else-can-agile-learn-from-complexity
un rapide tour de méthodes agiles avec des images qui parlent
http://www.slideshare.net/Siddhi/introduction-to-agile-methods

le bout du tunnel?

Juin 11th, 2009

enfin, on sort des ténèbres... après presque 10 ans de règne sans partager sur l'accès aux données depuis la création du Framework .Net, les DataSets rendent les armes.

C'est une vision personnelle, mais je ne peux me rappeler que mes soirées de debuggage intenses avec les DataSet... absence de typage, requêtes SQL construites sur des concaténations de chaînes de caractère... en tout cas au début, on était obligé de commencer comme ca.

Même s'ils ont mûri, les DataSets sont synonymes de lignes et lignes de codes de plomberie techniques, lourdes, fastidieuses, inutiles... et à mon sens une vision tordue de l'accès aux données.
Tout cela m'avait vite poussé à regarder NHibernate et ses confrères. Vive le Mapping Objet Relationnel!

Pour moi Linq et surtout Ado.Net Entity Framework allait enterrer définitivement les odieux DataSets... il n'en a rien été.

Et cette nouvelle m'apparaît comme une sortie du tunnel: "here are no plans to add DataSet into future releases of Silverlight"
Un signe? Un espoir?
Une promesse d'une aube nouvelle???? ;)

Si une technologie qui a le vent en poupe ne soutient plus cet ancêtre, peut être est-ce l'annonce du début de la fin?
Allez, il faut croire au progrès.

http://blogs.msdn.com/adonet/archive/2009/05/26/dataset-and-silverlight.aspx
http://www.sheysrebellion.net/blog/2008/07/31/datasets-are-evil/
http://jelle.druyts.net/PermaLink.aspx?guid=61676665-06a7-443a-9462-71dae713539e (DataSets Are Not Evil)

une excellent présentation des méthodes agiles

Juin 4th, 2009

http://www.slideshare.net/mcottmeyer/adopting-agile-1521562

exactement le genre de présentation que je fais
rapide, concis, une idée par slide, des idées claires & simples
des diapositives compréhensibles par tous et d'elles-même!

a MUST HAVE and a MUST FOLLOW

Une journée extra-ordinaire

Janvier 29th, 2009

Pour changer de .Net, un petit billet d'humeur sur... le travail.

Voila donc cette grande journée de grève avec une paralysie quasi-totale annoncée.
Et qu'est ce que je remarque ce matin au boulot: 2 fois moins de mes collègues sont venus travailler, les autres sont restés travailler chez eux.
C'est un des avantages à bosser dans les domaines de l'IT ou du service. Nous n'avons pas *vraiment* besoin de nous déplacer sur notre lieux de travail tous les jours, dans l'absolu.

Résultat de cette journée: l'ambiance était particulièrement décontractée voire joviale. Travaillant dans un OpenSpace, voila que -tout d'un coup- une quiétude et un calme nécessaire à la concentration régnaient autour de nous. Le travail allait en être plus efficace.

Les gens étant restés, pour bon nombre, chez eux, la circulation fut plus fluide que d'habitude (source Europe 1) et la qualité de l'air était bonne ( http://www.airparif.asso.fr ).
L'analyse de la courbe de cumul de bouchon en IdF fait ressortir une étrangeté ( http://www.sytadin.fr/ ): l'intensité des bouchons était exactement égale à la courbe des moyennes (donc aucun effet de sur-bouchon) mais elle était décalée dans le temps; c'est à dire que les bouchons se sont produits beaucoup plus tôt dans la matinée puis résorbés, pour avoir retrouvé à 9h30 une valeur quasi nulle... du jamais vu pour Paris et sa banlieue!

75% des métros ont fonctionné mais comme il y avait beaucoup moins de monde, les voyageurs étaient détendus.

Et de réfléchir, en ces temps de crise, à la nécessité de repenser nos modes de travail. Avons nous besoin de dépenser autant de CO2 pour transporter autant de monde à des distances parfois incroyables (plus de 3h de transport par journée pour certains). Et tous en même temps (ne pouvons nous pas imaginer des horaires mieux adaptés?).

Selon le WWF, 50% des émissions de CO2 des entreprises sont liées aux déplacements professionnels : voyages d’affaires, trajets domicile-bureau, etc. L’ONG vient donc de lancer le challenge One in five pour pousser les entreprises à réduire leurs déplacements professionnels de 20% d’ici 5 ans. (source: http://www.greenit.fr/article/acteurs/50-des-emissions-de-co2-liees-aux-voyages-daffaires )

En bon provincial (et Occitan de surcroît) je suis convaincu qu'il y a trop de monde en Ile de France, et que concentrer 1/5eme de la population sur 1,7% de la surface du territoire est une aberration environnementale (et idéologique).

Les instances territoriales font toutes les études qui démontrent que les trajets domicile-travail coûtent trop cher en CO2 ( http://www.hauts-de-seine.equipement.gouv.fr/IMG/pdf/p6_pda_covoiturage_vf_cle636a11.pdf ).
Le gouvernement et la CEE s'y mettent aussi ( http://www.bougezautrement.gouv.fr/ ).

Je saluerai donc toutes les initiatives qui vont dans le sens du télétravail et de la dématérialisation, tel que http://www.cyberworkers.com/
et de suivre les actualités de sites "IT durable" tels que http://www.greenit.fr/

Il est temps de vivre au 21e siècle et de laisser loin derrière nous la révolution industrielle. L'ère a changé!

la Modélisation Métier est elle soluble dans le CRUD (et inversement)?

Janvier 28th, 2009

http://docs.google.com/Doc?id=dhp3ggmx_115g524prcq

je vais lever une veille taupe, peut être un débat sans fin, mais il me parait important d'essayer de remettre les cartes sur table.

Plus les années avancent, et plus je me questionne sur où vont les technologies et les éditeurs ou les projets Open Source?

Et je me demande si on ne frôle parfois pas la schizophrénie...
Par exemple chez Microsoft, on nous dit : "CRUD, Only When You Can Afford It" ( http://msdn.microsoft.com/en-us/library/ms978509.aspx )
et après on met en avant ASP.NET Dynamic Data, qui permet de faire des applications 100% orientées CRUD.

Au début était l'informatique, les carte perforées, puis les disques durs. Et tout cela stockait des données, des données, des données.
Puis vint Merise en grand éclaireur de la pensée informatique industrielle (pendant que les scientifiques n'en avaient cure, et persistait dans une voie fonctionnelle).

Ce que faisaient alors les logiciels se résumait en 4 verbes: Créer, Lire, Modifier, Effacer des données (Create Read Update Delete, CRUD en anglais).

Et après de nombreux logiciels produits sur ce modèle, on s'est rendu compte que:
1) cela ne faisait que produire des logiciels d'informaticiens, c'est à dire pas du tout "User Friendly";
2) la complexité de la réalité dépasse le stade de ces 4 opérations basiques.

On a commencé à réfléchir du point de vue de l'utilisateur. On s'est aperçu qu'il avait un besoin de logiciel dans le but de l'assister dans l'exécution de son métier (et accessoirement que l'utilisateur était livré avec des yeux).

On a donc sorti une artillerie lourde pour décrire - MODELISER - les processus métier, issus du besoin réel de l'utilisateur, représentés bien souvent par des Scénarios Utilisateurs (merci UML).

Des paradigmes tels que le "Model Driven Design" ou le "Domain Driven Design" sont venus consolider cette nouvelle façon de faire du logiciel.

Pourtant le CRUD n'avait pas pour autant disparu...

On a l'habitude de dire qu'il ne faut pas exposer les données directement au dessus d'une couche métier, tels que ce que l'on peut trouver exposé par un Web Service, et pourtant nombre d'applications le font.
et Microsoft qui va droit dedans avec SdS et ASP.NET Dynamic Data.

"Data-driven application" redevient un mot que l'on peut prononcer sans honte.

Microsoft n'est pas le seul, avec la lame de fond qu'est REST, tout est orienté ressource, donc données, et les opérations permises sont encore au nombre de... 4!
Question légitime: comment exprimer du métier avec ce genre d'outils?

Comment faire dans cet incessant aller-retour entre une paroisse et une autre? Est-ce un éternel recommencement? (et piétinement?)

la suite sur http://docs.google.com/Doc?id=dhp3ggmx_115g524prcq