L'année 2014 a été longue et difficile. Les vacances de Noël ont failli être du même ordre :

  • Un dimanche à chercher un médecin de garde, pour une bronchite traitée qui a dégénéré.
  • Une soirée aux urgences pédiatriques pour mon fils avec ses 39.7°C, une nuit à l'hopital, pour pneumopathie.
  • Une rechute pour mon père, avec infection pulmonaire, un traitement assez lourd.
  • La moitié de la famille touchée par une gastro... qui finalement a été "légère" avec à peine une journée chacun de "moins bien"

Avec tout ce qui s'est passé, j'apprécie d'autant plus les petits bonheurs de la vie :

  • Toute la famille a pu passer le réveillon du 25 ensemble, et tous les enfants se sont éclatés. Mon fils a adoré distribuer les paquets à tout le monde.
  • Mon père va mieux, et devrait enfin rentrer à la maison dans les prochaines semaines. Depuis le printemps, ca commençait à faire long.
  • La neige, qui est bien tombée juste après Noël, pour la faire découvrir aux petits. Mais sans gêner la circulation pour autant.
  • La première bêtise de mon fils (un premier janvier). Sur le coup, je n'étais pas content. Mais maintenant, ça fera un chouette souvenir. Nous aider au restaurant et faire tomber une assiette pleine...
  • Mon fils se met à vouloir manger comme les grands. Il passe donc de "je ne mange que les plats pour bébés", sans vouloir gouter aux plats préparés avec amour par sa mère à "je ne veux manger que comme mes parents".
  • Mon fils qui accepte enfin de varier les gouts de ses yaourts.
  • Mon fils qui a fait des progrès énormes dans l'apprentissage du langage. On devine les phrases, on comprend de plus en plus de mots, et il se met à répéter tout ce qu'on dit.
  • Mon fils qui semble bien comprendre qu'il y aura bientôt un bébé de plus dans la maison.
  • La grossesse de ma femme, qui avance doucement et surement.
  • Mon travail, où j'ai assez de temps pour pouvoir effectuer des modifications importantes qui me tiennent à coeur. Et où l'équipe travaille "enfin" en harmonie.

Les petits plaisirs de la vie font mon bonheur. N'oubliez jamais vos petits plaisirs.

Quand on travaille sur des gros projets, on a tendance à rajouter beaucoup de fonctions, de code, partout, à tout bout de champ. Il faut savoir prendre du recul, pour simplifier le code, et faire des choses simples et efficaces.

Dans le cadre de mon travail, l'équipe test a pas mal changé cet été, avec 2 nouveaux arrivants. Ca tombe bien, on a aussi récupéré des nouveaux projets à tester. C'est en les formant à nos méthodes, notre code, que j'ai repéré des améliorations à faire, et qu'ils ont fait des suggestions intéressantes.

Avec leur arrivée, une partie de ma charge de travail a pu diminuer un peu, me permettant de réflechir, de me poser des questions, de chercher des idées "innovantes" pour résoudre des problèmes mis de côté par manque de temps depuis des semaines (voire plus).

Mise en place en 3 clics

Bon, j'éxagère, il faut plus que 3 clics. L'utilisation d'un Gemfile et de la gem bundler permet de simplifier l'ensemble de la procédure.

Pour préparer un nouveau poste (suite à une embauche, une réinstallation, ou un nouveau serveur, il faut alors installer ruby, la gem bundler, récupérer le dépôt du code, puis lancer juste la commande bundle install. Et le tour est joué.

Pour aller plus loin : mise en place sur tous les serveurs de tests d'une routine vérifiant que la liste est à jour et conforme à ce qu'on attend, avec un

bundle update
gem cleanup

L'information, le nerf de la guerre

Plongés dans les tests, nous disposions de plusieurs documentations, avec des buts plus ou moins précis. Localisées à plusieurs endroits. Du coup, petit ménage d'été, pour les regrouper, classer, mettre à jour. Au final, on a gardé plusieurs documents, pour plusieurs rôles différents :

  • Documentation du code : présente depuis le début, avec génération automatique par la gem ruby rdoc et un petit script ruby (basé sur des expressions régulières) pour lister les step_definitons. Basée évidemment sur les commentaires dans le code, qui sont eux mêmes le premier niveau d'explication.
  • Documentation sur comment coder : quelques documents précis sur comment installer l'environnement, les conventions de codage, ou des points précis et complexe des tests.
  • Documentation sur les produits : nous testons une demie douzaine de projets, plus ou moins liés les uns avec les autres. Pour pouvoir teter efficacement, il vaut mieux savoir comment le projet fonctionne, et dans l'idéal, connaître également les bugs les plus courants sur le projet.

Codes complexes et compliqués

Aujourd'hui, l'ensemble de nos codes testant les projets de la société représenter environ 11 000 lignes de codes (essentiellement en ruby, cucumber, shell)

Il y a 10 jours, j'ai regardé pour la première fois depuis des mois les résultats de flog sur le projet. Pour résumer, flog analyse le code source, compte combien de fois on effectue chaque "action", et s'ensuit une note de complexité pour chaque méthode, et pour l'ensemble.

Comme on peut classer, on voit immédiatement les fonctions les plus compliquées. Reste à savoir si la complexité est normale ou non. Après avoir lu pas mal d'articles sur le sujet, et testé moi même sur notre code, j'estime qu'une fonction avec un score supérieur à 50 doit être analysée, et éventuellement, modifiée.

Quelques chiffres

J'ai profité d'un "temps calme" au bureau pour bosser sur le sujet.

Avant :

  7128.5: flog total
    15.6: flog/method average

   793.5: main#none
   236.1: main#launch_browser
   197.0: main#get_job_results
   138.0: Then#/^HTML (contain|don't contain) (.*)$/
   136.7: Then#/^I don't see errors$/
   134.8: FormatPage#format_is_present
   131.1: main#compare_stats
    90.7: Then#/^I click on the insocial expand$/
    81.4: main#stats_of_day

Après :

 6166.2: flog total
    13.8: flog/method average

   827.4: main#none
   197.0: main#get_job_results
   168.0: main#launch_browser
   134.8: FormatPage#format_is_present
    90.7: Then#/^I click on the insocial expand$/
    90.3: main#compare_stats
    77.0: main#stats_of_day

On note plusieurs choses :

  • La note globale a chuté (-14%).
  • Cela fait mathématiquement baissé la moyenne par méthode.
  • Certaines méthodes "complexes" ont bien baissé.
  • D'autres ont augmenté : avec les pull request de mes collègues, rien d'aberrant. La note a donc baissé alors que dans le même temps, plus de 1 500 lignes de code ont été ajoutées / modifiées.
  • Certaines méthodes, complexes, ont une note qui correspond à leur difficulté de compréhension.

Qu'est ce que j'ai changé ?

Rien de transcendant :

  • Du code dupliqué a été "mis en commun" pour faciliter la maintenance.
  • Des optimisations faciles : par exemple, dans une méthode utilisant beaucoup de données, j'ai remplacé l'utilisation d'un tableau par une copie du contenu d'une données. Passer de my_array['result']['report']['url'] à my_url quand c'est utilisé 7-8 fois, ça améliore la complexité et aussi la lisibilité et la maintenabilité.
  • Des méthodes ont été découpées pour clarifier ce que le code faisait.

Et c'est conventionnel tout ça ?

En parralèle, j'ai mis à jour la gem rubocop. Cette gem permet de vérifier que toutes les conventions sont respectées. La liste des choses vérifiées s'est beaucoup étoffée depuis la dernière fois que j'avais mis à jour la gemme (de 0.18.1 à 0.27.1), et j'ai passé quelques heures à modifier notre code pour qu'il passe les nouvelles règles.

Sur le projet, nous avons désactivé 27 règles parmi les centaines présentes. Par exemple, nous désactivons la limite sur le calcul de complexité cyclomatique puisque nous utilisons flog.

Rubocop nous a aussi aidé sur la complexité : une nouvelle règle a fait remonté quelques variables non utilisés. Les supprimer à fait baisser les notes de flog.

Pour l'automatisation, un git-hooks lance un script shell :

  • vérifiant le résultat de rubocop,
  • vérifiant qu'il ne reste pas de trace d'un conflit dans les fichiers,
  • vérifiant que tous les fichiers yaml sont syntaxiement juste (find . -name *.yml -exec yaml-lint {} \; pour les analyser, avec la gem yaml-lint)

KISS, et après

Le principe KISS (pour Keep it simple and stupid) est une façon de travailler qui incite à rester simple pour être efficace. Certains points cités plus hauts ne sont pas triviaux à mettre en place, mais permettent sur le long terme à limiter les risques, à garder facilement du code propre, compréhensible, et simple.

Ma todolist pour la suite ?

  • Traquer le code dupliqué (j'en ai déjà repéré quelques morceaux, dont le nettoyage n'était pas possible dans le temps que j'avais),
  • Supprimer le code mort et non utilisé.
  • Continuer à documenter, ranger, classer.
  • Refactoriser ce qui peut l'être et dont le code n'est pas amené à disparaître dans les prochains mois.

Il y a des années qui sont très bonnes, pleines de bonnes choses. Pour moi, la référence, c'était 2009 : je me suis marié, nous avons acheté notre appartement, changé de voiture, ma femme a trouvé un travail.

Il y a des années, où c'est moins bon, mais qui ne sont pas mauvaises.

Et après, il y a des années où la poisse s'acharne. Pour moi, cette année noire, c'est 2014. Pour résumer, sur les 250 jours de l'année déjà passés, ma famille a compté pas loin de 300 jours d'hospitalisation. A tout ceci s'ajoute le fait que j'habite loin de mes familles, et que la communication n'est pas toujours simple.

  • Janvier 2014 : Décès de ma belle-mère. Même si elle n'était pas en super santé, cela a surpris tout le monde. Ma femme était effondrée. (Et j'étais pas beaucoup mieux)
  • Janvier 2014 : Mon père subit des examens pour un problème cardiaque. Avec stents. Posés avec complications.
  • Février 2014 : Ma filleule entre en urgence à l'hôpital, et est placée en coma artificiel le temps de faire les examens, pour éviter qu'elle souffre. Une petite fille de 5 mois passe donc 15 jours dans le coma.
  • Mars 2014 : Fin du coma, difficile et longue adaptation. Elle est clairement traumatisée, elle a peur des gens habillés en gris, etc...
  • Mars 2014 : Au boulot, j'ai l'impression que rien ne va. Je mets ça sur le compte de mes ennuis familiaux.
  • Avril 2014 : Mon père gagne un double pontage, en "urgence", avec plus d'un mois d'avance sur la date prévue.
  • Avril 2014 : Je continue de cloisonner entre boulot et perso, mettant tout mon stress sur le compte du personnel.
  • Avril 2014 : Mon père gagne un nouveau pontage.
  • Avril 2014 : J'explique la situation à mes chefs, qui commençaient à se demander pourquoi j'étais aussi sur les nerfs. On réalise que l'effectif du pole qualité n'est pas suffisant. Contre mon avis, on privilégie des solutions pratiques plutôt qu'une embauche.
  • Avril 2014 : On ajoute une chirurgie exploratoire abdominale sur mon père.
  • Mai 2014 : Amputation de la jambe pour mon père.
  • Mai 2014 : Sudweb me donne une bouffée d'air.
  • Juin 2014 : Je revois mon père pour la première fois de l'année. Il est dans un tel état que j'ai l'impression de lui dire adieu.
  • Juillet 2014 : Lors d'une sortie entre collègues organisée par ma société, blessure de mon binôme. Je suis donc seul là où on ne suffisait pas à deux.
  • Juillet 2014 : Nouvel opération de mon père, pour "fignoler" l'amputation.
  • Juillet 2014 : On fait passer des entretiens pour embaucher du monde au pole qualité.
  • Aout 2014 : Au boulot, on me propose une mutation. De Toulouse à Montpellier. (5 personnes à Toulouse, 40 à Montpellier)
  • Aout 2014 : Vacances. Repos, pas d'internet (ou si peu). Je me repose, j'oublie tout.
  • Aout 2014 : Ma femme est très fatiguée, malade.
  • Aout 2014 : J'apprends qu'une de mes tantes va mieux : elle a eu un AVC avec complications, alors qu'elle avait déjà une santé fragile.
  • Aout 2014 : Premier jour de boulot, lorsque je prends ma voiture, quelqu'un a laissé un mot pour s'excuser pour la bosse. Ma portière s'est faite enfoncer durant la nuit.
  • Aout 2014 : Deuxième semaine de reprise : chute de mon fils de sa hauteur à plat dos, on fini aux urgences. Il ne pose plus son pied par terre, et ne peut donc plus marcher. Ils nous font surveiller les symptômes d'un traumatisme crânien.
  • Aout 2014 : Mon fils ne marche toujours pas 2 jours après, passage chez le médecin. Qui nous dit de patienter, puis de passer une échographie du genou.
  • Aout 2014 : Ma meilleure amie passe aux urgences suite à un problème de santé pendant ses vacances.
  • Aout 2014 : Avec l'arrivée d'un nouveau testeur qui code des tests auto, je ressens d'autant plus le manque de code pour moi. En regardant en arrière, j'ai du coder en tout et pour tout 15 jours depuis janvier. (Le reste, c'est du test à la main, dont 75% au moins peut être automatisé)
  • Aout 2014 : Ma meilleure amie retourne à l'hôpital pour quelques jours après son retour de vacances.
  • Septembre 2014 : Échographie négative pour le genou de mon fils, retour aux urgences. Cette fois, on est fixé (10 jours après) : il ne pose pas le pied par terre parce qu'il a une fracture du tibia (Fracture en cheveu, compliquée à voir sur une radio). C'est parti pour un plâtre pendant 3 semaines.
  • Septembre 2014 : Ma femme est toujours malade, mais on est maintenant sûrs : on va être parents une deuxième fois.

Quand je racontais un point particulier à quelqu'un, on me disait toujours "Courage, ça va passer". Quand je vois la liste, je comprends mieux pourquoi, deux semaines après mon retour de vacances, j'ai l'impression de passer à côté de ma vie depuis quelques mois.

  • J'ai un travail, où je devrais faire mon métier. Pourtant, j'ai l'impression de ne pas faire mon métier.
  • J'ai une famille, que je ne vois pas aussi souvent que je voudrais.
  • J'ai un fils, et j'ai l'impression de ne pas le voir grandir.
  • J'ai une vie, mais je ne sais pas où elle me mène.