Votre organisation survivra-t’elle à l’auto-destruction des modèles d’affaires?

« Start up, Scale up, Screw up » n’est pas le titre du nouveau film de Quentin Tarantino mais celui du nouveau livre de Jurgen Appelo (sortie prévue pour avril 2019). Le dernier mot de ce titre est évocateur. Oui, trouver un modèle d’affaires qui fonctionne durablement n’est pas chose aisée. Je suis convaincu que vous ne voulez pas que votre entreprise finisse comme 90% des start-ups: en échec (source tirée du site internet Wydden.com).

Pourquoi un taux d’échec si important ? Pourquoi est-il si difficile de trouver un modèle d’affaires durable?

Lire la suite

Retour sur Learn To Craft : l’après-midi du Software Craftsmanship

Le mardi 20 octobre s’est déroulé l’événement LearnToCraft : l’après midi du développeur craftsman.

Planning de la journée

 

Le mouvement Software Craftsmanship

Au cours de cette session, l’animateur, Jean-Laurent de Morlhon, a retranscrit les grandes lignes du mouvement Software Craftsmanship.
Il a pour cela mis en avant les grandes idées du mouvement en s’axant tout particulièrement sur la pratique

Lire la suite

Comment débuter dans l’accessibilité numérique ?

Etant sourde, je suis passionnée par l’accessibilité numérique et en tant que développeuse, je débute dans ce domaine. Pour mon projet personnel, j’ai pensé à l’accessibilité.

Qu’est ce que l’accessibilité numérique ?
Un site internet accessible permet de garantir que son contenu est utilisable par n’importe qui, quelle que soit sa situation, son handicap (visuel, auditif, moteur…) et le matériel (ordinateur, navigateur Internet, logiciels spécialisés) utilisé pour y accéder.

Mais comment débuter ?  

Pour débuter, j’ai décidé d’utiliser l’outil Tota11y, découvert sur Twitter, un outil de visualisation des pages web accessibles. Cet outil permet de vérifier les erreurs de développement commises qui empêchent l’accessibilité de vos pages.

Comme page de garde, j’utilise Bootstrap et son template pour les blogs. Je vais me servir comme exemple pour l’article qui mettra bien en évidence les erreurs. Mine de rien, la page, que j’ai créée, a l’air super sympa et sans défaut. Mais méfiez-vous aux apparences. Il y a des choses auxquelles on ne pense pas et, du coup, cela ne facilite pas du tout l’accessibilité de votre page !

access1

Comme vous pourrez le voir, l’outil Tota11y est très facile à installer et à utiliser. Voici les explications.

Lire la suite

[Agile France] La naissance d’un Ordre des Développeurs ?

odd1

Les 18 et 19 juin derniers s’est déroulée Agile France. Au milieu des conférences, nous avons pu entre autres en suivre deux particulières :

L’Ordre des Développeurs par Jean-Baptiste Dusseaut

Le Réveil du Développeur  par Ly-Jia Goldstein

Leurs points communs ? Chacun a lancé l’idée de cadrer le métier de développeur (d’une manière assez large).

« With great power comes great responsibilities »

Et c’est un peu notre cas. Nous créons les sites, les applications que le reste du monde utilise tous les jours. Nous avons le devoir de bien faire notre travail.

Si la notion d' »Ordre » peut-être intimidante, paraître trop stricte, il est nécessaire de définir des engagements aussi bien du développeur seul (qualité, responsabilité, …) comme de la communauté (conseil, formations, …).

Si vous voulez en savoir un peu plus, vous pouvez rejoindre le GitHub de l’Ordre de Développeur ici : http://github.com/ordre-des-developpeurs

[BDD] Introduction au Behavior Driven Development

Introduction à la BDD

J’ai récemment pu expérimenter au cours d’une mission auprès d’un client la méthodologie BDD, autrement dit « Behaviour Driven Developement » (développement dirigé par le comportement). J’ai trouvé cela fort intéressant, du coup je me suis intéressé au sujet. 

Ce post aura pour objectif de revenir sur la notion de BDD, d’en présenter les principales grandes lignes ainsi que de suivre la méthodologie à travers un exemple.

BDD

Le processus BDD met en avant le langage naturel et les interactions dans le processus de développement logiciel. Les développeurs utilisant le BDD utilisent leur langue maternelle […] pour décrire l’objectif et le bénéfice de leur code. Cela permet aux développeurs de se concentrer sur les raisons pour lesquelles le code doit être créé […]. 
Définition Wikipédia de BDD

La notion de BDD fut introduite par Dan North, en réponse aux nombreuses critiques formulées à l’encontre du TDD (développement dirigé par les tests), en particulier concernant les difficultés de compréhension entre le programmeur et le chargé fonctionnel.

En effet au cours de projets en TDD, il m’est souvent arrivé de me demander par quel test je devais commencer, ce que je devais tester et à contrario ce que je ne devais pas tester, et surtout comment je devais tester. La méthodologie BDD est censée apporter des solutions à ces interrogations. 

Ses principes sont évoqués ci-dessous :

  • Définir les comportements de l’application avec des notations compréhensibles par tous : chargés fonctionnels et développeurs.
  • Chaque morceau de code est implémenté pour satisfaire un comportement de l’application, ceci afin de développer uniquement ce qui est utile à l’application.
  • Les exigences définissent les tests et le comportement de l’application. Elles sont définies à travers un canevas « Etant donné que … Lorsque … Alors ».

Ne vous y trompez pas, BDD ne réinvente pas le TDD, il s’appuie dessus et y ajoute des notions permettant une meilleure compréhension et définissant un fil conducteur pour le développeur.

Concrètement, qu’est-ce que cela donne ?

Imaginons le cas d’une application embarquée dans un automate pour la vente de billet de train. Je veux pouvoir définir la possibilité d’acheter des billets pour Londres.

Le chargé fonctionnel définit les comportements attendus ainsi :

Exigence 1 : 

Etant donné qu’il reste de la place dans le train pour Londres
Et ma carte bancaire est valide
Et j’ai suffisamment d’argent sur mon compte
Lorsque je valide l’achat d’un billet pour Londres avec ma carte bancaire
Alors je reçois une confirmation de la transaction
Et j’obtiens 1 billet pour Londres
Et j’obtiens le reçu de ma carte bancaire
Et mon compte est débité du montant du billet

Exigence 2 :

Etant donné qu’il reste de la place dans le train pour Londres
Et le montant du billet est de 40€
Et j’ai un billet de 100€
Lorsque je veux acheter 1 billet pour Londres avec mon billet
Alors je reçois une confirmation de la transaction
Et je reçois 1 billet pour Londres
Et j’obtiens un remboursement d’une valeur de 60€

Exigence 3 :

Etant donné qu’il reste de la place dans le train pour Londres
Et ma carte bancaire est valide
Et je n’ai pas suffisamment d’argent sur mon compte
Lorsque je valide l’achat d’un billet pour Londres avec ma carte bancaire
Alors je reçois un message m’indiquant que la transaction a échoué

Exigence 4 :

Etant donné qu’il reste de la place dans le train pour Londres
Et le montant du billet est de 40€
Et j’ai un billet de 20€
Lorsque je veux acheter 1 billet pour Londres avec mon billet
Alors je reçois un message m’invitant à compléter le reste de la somme ou à annuler la transaction

La question que le développeur se pose est « par où commencer » ? 

La méthodologie BDD préconise de prioriser en choisissant le comportement le plus important.
Ici, dans le cas de l’automate, j’ai pris l’option de l’opération la plus fréquente; soit le paiement par carte. Je ne retiendrai donc que les exigences 1 et 3.
De manière générale, la décision est prise en concertation avec le chargé fonctionnel. Le choix se porte le plus souvent sur la valeur business la plus importante. La question simple à se poser, est : Quelle est la fonctionnalité la plus importante qui manque actuellement à mon application ?. Bien entendu cela dépend du contexte du projet, dans le cas de mon automate, la fonctionnalité la plus importante est le paiement par carte de par sa fréquence.

L’exigence est alors traduite au travers d’un test d’intégration par le développeur. Un test qui échoue, bien entendu (principe même du TDD). 

 

Le nom du test doit être compréhensible par tous, on construit alors son nom par une phrase décrivant le comportement du test tel « Acheter un billet pour Londres avec ma carte bancaire et avec assez d’argent sur mon compte ». La phrase doit couvrir l’intégralité du comportement. 

Chaque étape du scénario devra être implémentée par la suite par le développeur. Les étapes « Etant donné que » (ou « Given ») permettent de définir le contexte initial du test, l’étape « Lorsque » (ou « When ») indique le déclencheur du comportement et les étapes « Alors » (ou « Then ») sont chargées de vérifier si l’application a bien répondu au déclencheur. 

 

J’utilise l’outil SpecFlow, disponible dans les packages nugget, qui fournit une interface pour suivre la méthodologie BDD à partir de Visual Studio. Il fournit également le squelette de la méthode de test (voir ci-dessus) que le développeur devra implémenter. Remarquez le nom des méthodes qui reprenne l’intitulé des étapes. 

Je ne vais délibérément pas détailler l’utilisation de SpecFlow, ce n’est pas le sujet, cela se fera peut-être dans un autre post.

A ce moment, l’application ne possède pas encore d’entité Banque pour indiquer qu’une carte bancaire est valide, confirmer une transaction, ou bien d’entité Gare pour permettre l’achat d’un billet. On utilise alors des bouchons (ou mocksvoir le post suivant pour plus d’information) afin de combler l’absence de ces entités. 

Le test d’intégration est toujours en échec. 

Je cherche à faire passer mon test d’intégration, pour cela je mets en place des tests unitaires propres à mon entité Banque. Ces entités prendront la responsabilité d’un comportement.
La convention veut que l’on place le mot préfix « doit » (should en anglais) devant le nom des méthodes de test. On pourrait ainsi lire un test par « Mon entité Banque doit valider ma carte bancaire » pour la méthode « DoitValiderMaCarteBancaire » de ma classe « BanqueTest ». Cette convention a un objectif: celui d’inciter le développeur à ne pas se disperser. Il doit en effet constamment se poser la question: est-ce que ce test s’applique à cette entité ?

Je dois à présent créer mon entité Banque afin que mon test unitaire passe également. Je le développe avec dans l’esprit l’idée de faire toujours au plus simple (principe YAGNI). Si mon entité Banque doit accéder à une couche de donnée « BanqueDAL », je mets en place des tests unitaires pour ma couche d’accès aux données, je créé ensuite l’entité « BanqueDAL » afin de satisfaire aux tests.

Une fois mes tests unitaire passés, j’effectue une refactorisation de mon code si besoin, et je lance mon test d’intégration. Celui-ci ne passe pas; chose normale vu que je n’ai pas non plus mon entité Gare. 

J’itère ainsi à créer mes tests unitaire d’entité jusqu’à ce que mon test d’intégration passe

Lorsque mon test d’intégration passe, je lance tous mes tests, et j’observe ou non des erreurs.

Si j’en obtiens, il y a trois possibilités :

  • J’ai introduit un bug, donc je le corrige
  • Le comportement attendu est toujours pertinent, mais s’est déplacé ailleurs. Je déplace le test et je le modifie éventuellement
  • Le comportement n’est plus correct, donc je supprime le test

Dans le cas où je n’ai pas de régression, j’itère sur un nouveau comportement, et donc un nouveau test d’intégration. Par exemple celui de l’exigence 3.

Le cycle se poursuit jusqu’à couvrir tous les comportements de l’application. 

Pour en savoir plus :

http://dannorth.net/introducing-bdd 

http://referentiel.institut-agile.fr/bdd.html

http://www.specflow.org

http://fr.wikipedia.org/wiki/Behavior_Driven_Development

http://blog.stevensanderson.com/2010/03/03/behavior-driven-development-bdd-with-specflow-and-aspnet-mvc/ 

[SQL Server] Changer de manière permanente le premier jour de la semaine pour un utilisateur

Problématique

Nous avons eu une problématique avec la langue de SQL Server, et plus particulièrement des effets de la langue sur le 1er jour de la semaine.

En effet, dans le cadre d’une requête en utilisant Entity Framework, nous faisions du regroupement par semaine. La plupart des SQL Server de développement sont installés en Français, mais pas le mien, en Anglais. Du coup lorsque j’exécutais la requête, je n’avais pas le même résultat qu’eux (le premier jour de la semaine étant le dimanche et pas le lundi comme eux, la requête me retournait la semaine regroupée à partir du dimanche).

Ce qui faisait planter au passage les tests chez moi, ce qui n’est pas très pratique…

Solution

Il existe toujours la possibilité d’exécuter des commandes T-SQL comme :

SET DATEFIRST 1

ou

SET LANGUAGE FRENCH

L’inconvénient de ces commandes est qu’elles ne fonctionnent que pour la session actuelle. J’ai essayé de le mettre dans le constructeur de notre DbContext, mais sans succès (les tests s’exécutant en parallèle, il n’a pas l’air d’avoir trop apprécié).

J’en suis venu à modifier le langage de mon utilisateur dans SQL Server. Pour le faire, deux options :

  • Via SQL Server Management Studio :
Security / Logins / clic droit sur le login utilisé par entity framework / Properties
Et dans la page de propriétés, changer la propriété « Default language » (dernière option de la page principale)
  • Via une requête T-SQL :
ALTER LOGIN sa WITH DEFAULT_LANGUAGE = french

Source :
http://www.experts-exchange.com/Database/MS-SQL-Server/Q_24751670.html

Dummy, Fake, Stub, Mock et Spy, les tests unitaires avec l’aide de Moq.

J’ai travaillé dans plusieurs sociétés et encore plus d’équipes différentes. Souvent, on m’a parlé de tests unitaires, que c’était important pour la stabilité et la robustesse de la solution.
Je me suis rendu compte qu’il s’agissait d’un abus de langage : la plupart du temps, j’étais devant des tests d’intégration. Cette erreur avait très souvent la même explication : les équipes n’avaient pas correctement isolé leur code.

L’isoler veut dire permettre à son applicatif de s’affranchir de ses dépendances externes (sa base de données par exemple).
Je vais ici tenter d’expliquer les différentes techniques permettant de couper ou simuler ces dépendances.

Les personnes qui pourraient être intéressées par cet article sont principalement (mais pas seulement) : 

  • Les développeurs débutants dans les tests unitaires.
  • Ceux ayant déjà survolé le sujet voulant approfondir leurs connaissance et compréhension.

Je risque pour les second d’enfoncer quelques portes ouvertes. Mais il est toujours bon de rappeler les bases.

Que sont les doublures de test ?

Durant le développement de mon application, j’aurai sûrement à implémenter à un moment donné des tests unitaires.
Chaque test doit être atomique et ne tester que son état. Pas celui d’autres méthodes ou objets. Je ne dois, par exemple, jamais atteindre la base de données ou le système de fichier. Je passerai alors dans l’univers des tests d’intégration.
Du coup, je dois faire croire à mon code soit que j’appelle bien la méthode qu’il m’a demandé d’utiliser soit que l’objet dont il peut avoir besoin existe.
Cet ensemble de subterfuges s’appellent des doublures de test. Ceux-ci sont identifiés et nommés comme suit : Dummy, Fake, Stub, Mock, Spy.
Leurs implémentations peuvent aller du trivial au casse-tête si je n’utilise pas d’outil spécifique existant.
C’est pourquoi j’utiliserai la bibliothèque Moq pour illustrer mes exemples.
A noter que si en général, l’utilité des doublures de test est avéré pendant les tests unitaires; je peux dans certains cas précis utiliser leur principe ailleurs dans mon projet.

Définitions et implémentations

Dummy

Il s’agit de faire croire à ma destination que l’objet existe. Celui-ci ne fera rien, il ne contiendra rien non plus. Mais il existera aux yeux de mon code testé.
Exemple : Admettons que nous ayons une classe que nous appellerons MasterClass. Son constructeur unique prend en paramètre une implémentation d’une interface lui servant de DAL.
Nous avons un test à faire : qu’un GUID soit bien généré suite à l’appel du constructeur. Ce test n’a pas besoin de mon appel à la DAL.
Alors soit, je peux passer null au constructeur :

[code language= »csharp »]
[TestMethod]
public void MasterClass_Contient_Guid()
{
var master = new MasterClass(null);
Assert.IsNotNull(master.Guid);
}
[/code]

Si d’aventure mon constructeur appelle ma DAL directement, mon test ne passera jamais (le constructeur renverra invariablement une NullReferenceException).
Je peux me servir de Moq afin de faire croire à mon constructeur que si, je lui ai bien donné une instance de l’interface :

[code language= »csharp »]
[TestMethod]
public void MasterClass_Contient_Guid()
{
// Initialisation des variables utilisant Moq
var repo = new Mock<IDataRepository>();

IDataRepository dummyRepo = repo.Object;

// On appelle le constructeur avec le dummy
var master = new MasterClass(dummyRepo);

// Enfin, on effectue une assertion qui n’a pas besoin
// d’utiliser IDataRepository.
Assert.IsNotNull(master.Guid);
}
[/code]

Attention : avec Moq, l’appel à une méthode d’un Dummy renverra toujours null. Gare à vos validations !

Fake

Un Fake est une implémentation simplifiée d’un comportement attendu. Ici, on ne fait pas croire à notre code quelque chose; on l’a implémenté explicitement. Il sera juste simplifié et ne fera appel à aucune dépendance.
Je n’ai pas besoin de Moq pour cette doublure de test. Je dois créer une classe qui me servira uniquement pour mes tests.

[code language= »csharp »]
public class FakeDataAccessLayer : IDataRepository
{
private int nbInstances;
public FakeDataAccessLayer(int nbInstances)
{
this.nbInstances = nbInstances;
}

List<SlaveClass> IDataRepository.GetSlaves()
{
var output = new List<BusinessLayer.SlaveClass>();

for(int i = 0; i < this.nbInstances; i++)
output.Add(new SlaveClass() { Id = i, Name = i.ToString() });

return output;
}

int IDataRepository.Save(MasterClass masterClass)
{
throw new NotImplementedException();
}

int IDataRepository.Save(SlaveClass slaveClass)
{
throw new NotImplementedException();
}
}
[/code]

Bien évidemment, je n’implémente que ce dont j’ai besoin. Si mon Fake ne teste jamais les méthodes de sauvegarde, il est même préférable de laisser un renvoi d’exception. Ça me rappellera que ce n’est pas normal de passer par cette méthode.
J’utiliserai le Fake de cette manière dans les tests unitaires :

[code language= »csharp »]
[TestMethod]
public void MasterClass_NbSlaves_Retourne_Liste_Count()
{
int nbInstances = 3;
var fakeRepo = new FakeDataAccessLayer(nbInstances);

var master = new MasterClass(fakeRepo);

Assert.AreEqual(nbInstances, master.NbSlaves);
}
[/code]

Le Fake peut également être très utile en dehors des tests unitaires :
Vous commencez un nouveau développement. Vous n’avez aucune information concernant le mode de stockage de vos données.
Cela peut être voulu (Clean Architecture) ou pas (on vous lance sur le développement alors que tout le monde n’est pas encore d’accord sur ce point, au moins).
En utilisant un Fake, vous vous affranchissez des accès extérieurs. Vous pouvez commencer à coder sans attendre de décision supplémentaire. Il ne vous restera enfin qu’à changer l’implémentation à passer à votre appli / site.

Stub

Je reprends le principe du Fake, mais je vais être plus fainéant. Il n’y aura aucune implémentation explicite, Moq me sera utile dans ce cas. Je ne présenterai que ce dont j’ai besoin.

[code language= »csharp »]
[TestMethod]
public void MasterClass_Save_Met_A_Jour_Id()
{
// Initialisation des variables utilisant Moq
var repo = new Mock<IDataRepository>();

repo.Setup(m => m.Save(It.IsAny<MasterClass>())).Returns(5);

IDataRepository stubRepo = repo.Object;

// On appelle le constructeur avec le stub
var master = new MasterClass(stubRepo);

master.Save();

Assert.AreEqual(5, master.Id);
}
[/code]

La méthodeSetup(Expression<Action<T>>) de Moq me permet de créer une implémentation de la méthode Save(MasterClass) de IDataRepository.
Dans ce cas précis, je demande à Moq :

« Lorsque tu recevras un appel à la méthode Save(MasterClass). Quelle que soit la valeur du paramètre masterClass (It.IsAny<MasterClass>()), renvoie toujours la valeur 5. »

Rappel : Je ne veux pas tester le retour de la fonction Save(MasterClass) de IDataRepository, je veux m’assurer que la méthode Save(MasterClass) de MasterClass utilise bien le retour de cette première.

Mock

Il est parfois compliqué d’aller vérifier le comportement d’une méthode. Notamment lorsque celle-ci va manipuler d’autres objets ou bien appeler leurs méthodes.

On parle également de « behaviour verification« , expression un peu plus facile à comprendre.

J’utiliserai le Mock le plus souvent pour vérifier une propagation.

Ce qu’il faut garder à l’esprit lorsque l’on parle de Mock, c’est que je vérifie des états et des valeurs que je maîtrise et connais. Si je n’en ai pas le pouvoir (ou si ça n’est pas mon problème), alors je parlerai de Spy.
Admettons qu’au moment de la sauvegarde, si une exception est levée, je dois l’enregistrer dans un fichier quelconque. Celui-ci contiendra la valeur du message de l’exception.

[code language= »csharp »]
[TestMethod]
public void MasterClass_Save_Enregistre_Message_Exception()
{
// Initialisation des variables utilisant Moq
var repo = new Mock<IDataRepository>();
var fileLogger = new Mock<IFileAccess>();

repo.Setup(r => r.Save(It.IsAny<MasterClass>())).Throws(new Exception("TestException"));

var master = new MasterClass(repo.Object);
master.SetFileLogger(fileLogger.Object);

master.Save();

fileLogger.Verify(f => f.LogMessage("TestException"));
}
[/code]

J’utilise encore la méthode Setup(Expression<Action<T>>) de Moq. Ici, je lui demande de me renvoyer invariablement une exception. Exception dont je connais le message, puisque c’est moi qui le passe.
Arrive la fonction Verify(Expression<Action<T>>, Times). Dans ce cas, je demande à Moq de vérifier que j’ai bien appelé la méthode LogMessage(string) avec le paramètre d’entré égal à « TestException ».
Dans ce cas, je peux avoir appelé la méthode LogMessage(string) n fois pendant mon traitement. La seule chose qui m’intéresse, c’est de savoir si au moins une fois, mon paramètre était « TestException ».

Spy

Le Spy est un dérivé du Mock. Cependant, si dans ce dernier, je vérifiais les paramètres, ici, je m’assure uniquement que je suis passé (ou non) par un chemin ou une méthode.
Reprenons le test précédent et tournons le en Spy :

[code language= »csharp »]
[TestMethod]
public void MasterClass_Save_Enregistre_Message_Exception_Spy()
{
// Initialisation des variables utilisant Moq
var repo = new Mock<IDataRepository>();
var fileLogger = new Mock<IFileAccess>();

repo.Setup(r => r.Save(It.IsAny<MasterClass>())).Throws(new Exception());

var master = new MasterClass(repo.Object);
master.SetFileLogger(fileLogger.Object);

master.Save();

fileLogger.Verify(f => f.LogMessage(It.IsAny<string>()), Times.AtLeastOnce());
}
[/code]

Le code du test est quasiment le même.
Les seules différences sont que l’exception ne contient plus de message explicite et que Verify(Expression<Action<T>>, Times) ne s’intéresse plus à la valeur du paramètre passé à LogMessage(string).La raison est que dans le Spy, les valeurs passées ne m’intéressent pas. Soit parce que je ne les maîtrise pas soit parce qu’elles ne sont pas au cœur de ma problématique.
J’ai également rajouté Times.AtLeastOnce(), de manière assez évidente, vous aurez compris que je veux vérifier que j’ai appelé « au moins une fois » la méthode. Je peux bien évidemment demander un nombre fixe de fois.

Quelle est la différence fondamentale avec Mock ? Rien ne m’assure que dans le Spy, j’ai bien appelé LogMessage(string) depuis l’endroit du code que je veux valider.

En plus clair : prenons ma méthode Save(MasterClass). Admettons que j’appelle LogMessage(string) autrepart ;pour logger les valeurs de mes paramètres envoyés à IDataRepository par exemple. Et que, par contre, je n’appelle pas ou plus cette méthode lorsqu’une exception est levée… Alors Spy considèrera mon test unitaire en « Réussite » : j’ai correctement appelé LogMessage(string) au moins une fois. A l’inverse, Mock le marquera en « Échec » car je n’ai pas validé la valeur du paramètre passé.
J’espère vous avoir suffisamment présenté les différences, points communs et subtilités des doublures de test. Le sujet est assez complexe. De plus, je me suis rendu compte pendant cette rédaction que je confondais certains d’entre eux. Si j’ai pu éclairer certains d’entre vous, ce serait une excellente chose.
Sources :
Mocks Aren’t Stubs (Martin Fowler)