Accueil > Journal, TDD > Refactoring de tests

Refactoring de tests

Salut 🙂

Je faisais remarquer aux participants d’une PSD le mois dernier que l’on passe énormément plus de temps à lire du code qu’à en écrire. C’est pour cette raison, entre autres, que je leur conseillais d’investir dans la lisibilité du code. Une façon de faire ça qui fonctionne bien pour moi c’est d’écrire l’intention du test en langage naturel, puis de m’arranger pour faire compiler et passer ce que je viens d’écrire.

Un exemple ? Allez, un exemple… 😉

Considérez le test suivant. Sans doute vous trouverez que j’exagère de montrer autant de choses qu’il ne faut pas faire, mais c’est pour l’exemple.

Le défaut de ce test qui m’intéresse aujourd’hui c’est que beaucoup de gens vont le lire plusieurs fois pour bien comprendre son intention. Si j’essaye de me concentrer sur l’intention du test, en tentant d’activer mon meilleur anglais, cela me donne envie d’écrire les choses plutôt comme ci-dessous.

A partir de là, je dis souvent aux participants « il ne vous reste plus qu’à placer les parenthèses et les points où cela vous arrange pour faire compiler tout ça ». Il y a bien sûr plusieurs façons de le faire et je ne vais pas m’étendre sur ce point. Juste mentionner que pour ma part j’aime bien le pattern builder et, en Java, les imports statiques. Cela peut par exemple donner le résultat ci-dessous.

C’est plus clair non ?

Publicités
Catégories :Journal, TDD Étiquettes :
  1. 13 octobre 2011 à 10 h 22 min

    + 1

    Je te suis Eric. Lors d’un dojo de quelques séances de 2h sur un même exercice, ceci a été une révélation. Nous passions au début, la moitié du temps à nous réapproprier le code. Tout ça car nous avions des nommages dans un langage non naturel.

    Un bon nommage vaut mieux qu’un long commentaire. Peut importe la longueur des noms de fonctions.

    🙂
    Luc

  2. 13 octobre 2011 à 11 h 41 min

    +1

    Les builders, les imports statique et les « fluent interfaces » font désormais partis de mon coffre à outil. Super découverte, difficile de s’en passer 🙂

    Une remarque suivit d’une question.

    Pour les besoin de la cause, la méthode a() est très sympa. Par contre, avec le temps elle risque de rentrer en conflit avec d’autres builders. Peut-être que quelque chose comme aProduct().withPrice(10) serait suffisant, surtout que le nom du produit ne semble pas pertinent dans ce test puisqu’on ne le réutilise jamais.

    Pour ce qui est du shouldHave…(), vous avez mis l’assertion directement dans la classe du builder ou vous en avez fait une sous classe ? Je me pose la question car je trouve très utile les builder maintenant non seulement pour mon code de tests mais pour mon code de production.

    Lâche pas, ce type de blog est vraiment intéressant 🙂
    Nick.

    • @EricMinio
      13 octobre 2011 à 15 h 54 min

      Evidemment cela se discute mais j’aime utiliser des données réalistes dans mes tests plutôt que des formulations génériques. Cela m’a aidé plus d’une fois à conserver l’attention d’un binôme orienté affaire.

      Moi aussi j’aime utiliser les builders dans le code de production. L’assertion n’est pas dans le builder mais dans un OrderAssertionHelper.

  3. 13 octobre 2011 à 15 h 52 min

    J’adore!

    Quand organises-tu un dojo avec comme but d’explorer et de partager sur les builders?
    Je vois déjà un randori très intéressant!

    françois

  4. 14 octobre 2011 à 8 h 14 min

    Vraiment sympa.

    Dans le genre builders j’ai joué un peu avec http://code.google.com/p/make-it-easy/ qui résout le problème de boiler plate code dans les builders ainsi que le problème signalé par Nicolas.

    Par contre je l’ai trouvé un poil dur à appréhender donc j’ai pas continué la fréquentation. D’autres avis sur le sujet?

  5. 16 octobre 2011 à 20 h 50 min

    J’ai pas mal travaillé avec ce pattern et chaque fois je me suis trouvé à écrire beaucoup de code sans trop grande valeur ajoutée. Étant un tantinet paresseux, j’ai réfléchis à une solution pour éviter d’avoir à écrire tout ce code, surtout pour les cas simples où les builders ne créent que de simples beans. En effet, dans la plupart de ces cas, les builders sont pratiquement une duplication des setters du bean en lui-même.

    Ton blog post m’a donc convaincu à aller de l’avant avec une idée qui me trottait depuis peu. J’ai donc profité de ce week-end maussade et pluvieux pour pondre quelque chose:
    https://github.com/davidmarquis/fluent-interface-proxy

    Dites-moi ce que vous en pensez! J’écrirai un post plus complet sur mon blog à propos de cet outil qui, je crois, peut faire sauver pas mal de temps à nous chers développeurs paresseux. 🙂

  6. 17 octobre 2011 à 10 h 06 min

    Histoire de compléter un peu le tooling :

    Il y a aussi cette solution basé sur annotations
    https://github.com/mkarneim/pojobuilder

    Et un plugin Eclipse
    http://code.google.com/p/fluent-builders-generator-eclipse-plugin/

  7. 10 novembre 2011 à 19 h 16 min

    Au dela du tooling, ca dépend du « setup » du test et de l’api que tu te propose de créer

    // Arrange
    o = new Order()
    .add(new Product(« foo », 41))
    .add(new Product(« bar », 1);
    // Assert
    assertThat(o.price(), equals(42));

    et du langage

    price_is_sum_of_quantity_per_price_for_items_in_basket_test_() ->
    [
    ?_assertEqual(
    42,
    basket:price([{« foo », 1, 41}, {« foo », 1, 1}])
    )
    %% , …
    ].

    :), Thierry

  1. 24 mars 2013 à 11 h 53 min

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :