Reconversion pour coder : pertinence, moyens, débouchés…

Répondre
Partager Rechercher
C'est du c++ mais le principe derrière doit être valable pour la plupart des langages... enfin ça va dépendre surtout des compilos/interpréteurs et des architectures processeur, bref y'a des fous qui expliquent ça très bien dans le spoiler
@Zangdar : Moué c'est gentil encore comme code, les variables semblent encore décemment nommées. Un poil de formatage et ça doit commencer à devenir lisible.

"Les maths ne servent à rien pour coder" -> ça va énormément dépendre du secteur/type de logiciel. Un minimum de bagage(~les maths de lycée en S) ne fait pas de mal pour le quotidien.
Citation :
Publié par Zangdar MortPartout
Ce genre de choses par exemple, avec aucun commentaire (et je dis ça en étant anti-commentaires)
L'architecte qui fonde un projet,
le développeur principal qui jouera le rôle d'encadrant des arrivants,
sont anti-commentaires. Ils disent : "Un code bien fait se comprend tout seul."

Trois ans plus tard, l'architecte est bien sûr sur un autre projet, et le développeur principal aussi.
Le code est bien ou mal écrit, selon les endroits et qui l'a codé, qui est là ou plus là.
Pour appréhender le logiciel, il observer jusqu'à 250 000 lignes et les interpréter de tête comme si l'on était un compilateur ou un processeur.

Ça marche. Mais avec plusieurs défauts :
1) En cas de coup dur qui affecte une zone d'envergure de 30 000 instructions, ce sont ces 30 000 instructions qu'il faut lire et interpréter sans se tromper jusqu'à trouver la ou les causes de l'incident.
Bien sûr, le développeur principal ou l'architecte auraient dit "Mais c'est facile si tu connais le langage !", sauf que tu es de plus en plus fatigué à la recherche des bugs et que ton acuité diminue. Le risque d'erreurs d'interprétation s'accroît.

2) La maintenance évolutive se fait à vitesse réduite. Il faut trouver où agir en décodant le code.

3) Un nouvel arrivant doit demander.
demander comment ça marche.
et trouver quelqu'un qui a le temps de lui répondre parce que c'est plus long à expliquer s'il n'y a aucun support pour aider.

4) Un analyste fonctionnel vient s'assoir à côté de soi. Il ne comprend pas comment quelque-chose fonctionne.
Il voit un fatras de lignes et de fonctions. Il n'est pas serein.


Situation opposée (celle que je promeus) :

1) Tout le code est documenté. Les classes, les méthodes ont bien sûr une documentation au dessus d'elles,
mais aussi chaque bloc d'instructions impératives, chaque if et chaque for ou while.

2) Les commentaires ne paraphrasent pas les instructions qui vont s'exécuter. Soient elles les résument en quelques mots, soit (c'est le mieux) elles disent dans quel but, du point de vue du demandeur du programme, elles ont été faites.

/* Je récupère la liste des articles en promotion. */
....
/* Je parcours tous ceux qui sont sur les présentoirs depuis plus de deux mois. */
...
/* Cet article a t-il une étiquette de promotion valide ? */
...
/* Si ce n'est pas le cas, il est retiré et reclassé dans les articles à ré-etiquetter. */
..

Derrière ces commentaires, tu peux imaginer les for, les if, les while. Imaginer des appels à du SQL ou du Mongo, n'importe quoi que tu voudras. L'important, c'est que l'on comprenne pourquoi on est là et ce qu'on fait.
Derrière, que ce soit du Java, du C++, du PHP ou du Python, c'est presque pas important.

3) Un incident grave ? Une recherche par simple mot-clef suffit parfois à trouver les endroits où recherher prioritairement les bugs. Et les commentaires, dans une situation d'urgence, apportent dans tous les cas un grand soutien, car ils servent de fils directeurs, d'index permettant de s'affranchir de lire immédiatement des monceaux de codes avant d'avoir atteint les endroits où il est probable que les défauts se trouvent. Ce sont des panneaux indicateurs.

4) La maintenance évolutive est plus facile, parce qu'il est plus facile de se diriger dans l'existant.

5) Un nouvel arrivant interroge beaucoup moins : de nombreuses choses lui sont déjà expliquées.
Et il se rend respecté.

6) L'analyste fonctionnel assis à côté de soi, lit :

/* Si ce n'est pas le cas, il est retiré et reclassé dans les articles à ré-etiquetter. */

"Ah non, non, non.", dit-il. "T'embêtes pas ! Tu les mets avec une étiquette à -20% c'est tout !"

Et tout le monde a gagné du temps. Lui voit le code avec confiance, bien qu'il ne connaisse pas le langage utilisé. Il sait que c'est écrit dedans, ce que ça fait.


Moyennant quoi :
a) Un code non commenté est considéré en la plupart des endroit où je passe, comme soit :
- Un code de test
- Soit celui d'une personne débutante qui ne comprend pas encore bien ce qu'elle fait, parce qu'elle ne sait pas l'expliquer.
- Comme celui d'un prestataire qui essaie d'en garder la maintenance le plus longtemps possible. Si c'est pas commenté, c'est pas facile à comprendre, alors on me le laisse, puisque moi je sais le lire !

b) Si un code source qui n'est pas commenté provoque un bug, et qu'il semble pas très beau par ailleurs dans son écriture, il est détruit sans autre forme de procès. Son auteur, ne respectant personne puisque ne le documentant pas, ne reçoit pas plus d'égards pour son travail en retour.

c) De plus en plus d'outils à base de Git ont une étape de Merge Request où le code est mis en quarantaine pour l'examen de réviseurs plus ou moins tatillons.
En de plus en plus d'endroits, pas de commentaires = Merge request refusée. Et c'est légitime.

Le code n'appartient pas au développeur dans une entreprise.
Il est collectif et doit être expliqué à l'attention de tous ceux qui viendront agir dessus demain ou plus tard.

Ne pas commenter est vu en bien des endroits comme une forme d'impolitesse.

Dernière modification par Caniveau Royal ; 28/04/2017 à 19h28.
Je ne souhaite pas partir un débat ici sur les commentaires, mais les exemples que tu donnes (/* Je récupère la liste des articles en promotion */) sont tout ce que je combat journalièrement dans le code. D'ailleurs ça porte un nom: Du Mumbling.

C'est inutile, lourd, et s'il faut fouiller dans 30.000 lignes d'instruction, il y a un problème d'architecture.

Au lieu de mettre un commentaire qui ne sera ni maintenu, ni mis à jour, il suffit d'extraire une fonction getOnRebateArticlesList() du code existant.

Ma philosophie du commentaire est décrite dans le livre suivant:

http://www.goodreads.com/book/show/3735293-clean-code

Pour faire très court :

- Why: OK, rarement nécessaire: "Je fais cette boucle de cette façon là pour telle et telle raisons que tu ne pourras pas deviner avec le code". Exemple:

Code:
    /* The unchecked conversion and suppress warning are valid for the following reasons:
     * - The cast is actually type safe
     * - Restrictions on java Enums in 1.65 prevents us to find another solution that would not implicate duplicated code
     */    
    @SuppressWarnings("unchecked")
    public static <E extends Enum<E> & IDisplayableEnum> E[] getDisplayablesValues(Class<E> iClass, E[] iValues)
- How: JAMAIS. Ces commentaires cachent du mauvais code, si je dois prendre le temps d'écrire un tel commentaire, je le prends pour ré-écrire le morceau de code de façon claire.

Les commentaires de type HOW finissent toujours par mentir et ne plus refléter ce que fait réellement le code. Quand c'est couplé à du code pourri, on en arrive à se demander si c'est le commentaire qui ment, ou le code qui est bugué (vécu). Ton analyste aura l'air bien fin ce jour là. Un exemple tiré du livre (et qui accessoirement, s'est retrouvé dans notre standard comme contre exemple):

Code:
// repaint calendar day
for ( final CustomCalendarDay item : getCalendarDays ()) {
item . setOpeningHours ( dayCode , startTime , endTime , isOverTime );
}
What are the conclusions here ?

1. There was a repaint happening some commits ago. The comment is obsolete!
2. There was a repaint happening some commits ago. That it's gone was an accident!
3. There was no repaint happening so far. But it should have been added by now!
4. The repaint is still happening as an hidden side effect somewhere in the code!
5. The developer actually wanted to type //repeat for all calendar days


Le commentaire, c'est comme la notation hongroise, c'était important quand il était impossible de faire du code lisible. Aujourd'hui, il y a bien des choses qui peuvent être vues comme impolies par des gens ancrés dans leurs habitudes mais qui sont en réalité de bien meilleures pratiques. Et la tendance de fond, c'est que le commentaire est un code smell.

Citation :
Il voit un fatras de lignes et de fonctions. Il n'est pas serein.
Si tu codes en fatras de lignes et de fonctions, il y a un problème

Dernière modification par Zangdar MortPartout ; 28/04/2017 à 19h42.
Je rajoute que les commentaires n'evoluent pas forcement de maniere aussi synchrone que le code.
Le code par definition est a jour, les commentaires tu n'as aucune garantie, et le code review est base sur du best effort.

Maintenant ils peuvent etre necessaire:
Ajouter une reference a un ticket,
Expliquer les contraintes, cas limite qui justifie une implementation non triviale
Anticiper un probleme potentiel ou evol future (Ex: si on doit faire un rollback de cette feature, tel comportement doit etre adopte/implemente).
Quand au point 6, c'est typiquement le truc qui me ferait hurler. Le metier qui te sort un chiffre magique sorti de je ne sais pas ou. C'est le meilleur moyen d'avoir un conflit le jour ou le -20% se transforme en -15% et qu'il faut changer la conf et/ou le code, et que le client insiste pour faire passer ca pour un bug.
Je suis assez d'accord. Mais il n'empêche. Le nombre de fois où les analystes ont compris que leur propres règles de gestion ne tenait pas l'épreuve en suivant le déroulé du programme par ses commentaire n'est pas négligeable.

Quant aux commentaires qui couvriraient du code faux, et toute la justification que Zangdar a donnée, je la connais par cœur. C'est le combat d'arrière-garde des paresseux. Mais ils sont de plus en plus minoritaires et mal vus.
Ils ont eu leur période de gloire dans les années 2010 avec l'arrivée des méthodes Agile qui les confortaient dans le "on ne documente et on ne commente rien.", puis les développeurs passant, plus personne – pas même l'entreprise – ne savaient plus ce que les programmes faisaient.

Les projets Open Source abandonnés faute de personnes pour aider à les maintenir ?
Très simple ! Qui viendrait participer à un projet où il n'y a pas de doc ni de commentaires dans les sources quand pleins d'autres en ont ?

C'est une raison de l'apparition Merge Request dont je parlais. Pour faire un mur à ceux qui refusaient de le faire. Se prémunir contre ceux qui trouvent toujours mille raison de faire du code crado, à l'arrache, et pas documenté.
Et dans beaucoup de projets aujourd'hui, c'est demandé. Indépendamment des autres métriques de qualité sur le code.
@Caniveau Royal : Non mais faut juste que les mecs arrêtent de coder comme des gorets et ça se passe bien. Je vois direct le type de startup: bon livre moi pour hier hein sinon t'es viré. Et 6 mois après ouais, c'est la mort, plus rien n'est maintenable. Du coup non seulement on code comme des gorets, mais en plus on commente comme des gorets, en ayant le sentiment de faire sa job alors qu'on fait juste mettre une couche de febreeze sur du caca.

On dépense énormément d'énergie et de temps ici pour faire du code propre, et changer les anciennes mentalités qui veulent aller vite vite vite.

Citation :
C'est une raison de l'apparition Merge Request dont je parlais. Pour faire un mur à ceux qui refusaient de le faire. Se prémunir contre ceux qui trouvent toujours mille raison de faire du code crado, à l'arrache, et pas documenté.
Nous on fait propre, en prenant le temps, en documentant mais pas dans des commentaires (ça s'appelle des requis fonctionnels et des requis bas niveau en fait et tout est tracé et couvert par un test). Par exemple, ton -20%, c'est un requis fonctionnel et ça ne se décide pas sur un coin de table, ça se trace dans un logiciel de gestion des requis et de traçabilité.

Pour finir, notre définition of done inclut une revue effectuée sous code collaborator. Aujourd'hui j'en ai eu une pour un mec qui a remplacé un , par un ; dans une table Matlab. Ouais, juste 1 caractère modifié. Et c'est moi même qui ai validé le changement: ce qui veut dire le tester sur le produit.

J'ai l'impression que tu associe code non commenté à code fait à l'arrache alors que c'est tout l'inverse. Mais ce n'est pas surprenant car en fait, très peu de gens en entreprise ont eu l'occasion de voir et faire du bon code.

Alors pour ton raccourci "pas de commentaire" = "paresseux" .....
En 25 ans de job, je suis passé par 20 clients différents. Vingt équipes aux pratiques variables.

Tu arrives sur un existant où 10 personnes sont passées dessus les 5 précédentes années,
et le code n'est pas beau. Tu dis quoi ? "Non, je m'en vais, je veux du code 'gants blancs', et je vais voir ailleurs ?"

Les deux tiers des endroits où tu passes, c'est moyen. Le tiers restant ? Soit génial, soit atroce. Et tu vis avec.
Mais l'existant, tu cherches à l'améliorer si ce n'est pas toi qui l'a écrit. Pour toi et pour les autres ensuite.

Tu n'as pas la chance de fonder toujours le logiciel qui va être utilisé. Sinon, tu le ferais bien systématiquement je suis d'accord. Quand tu arrives sur un soft qui est dans un état qui vaut une note de x/20, eh bien, le plus souvent en le commentant, tu expliques ainsi et tout le monde t'en est redevable et sa qualité s'accroît.
J'ai fait de l'aérospatiale, code vieux de 30 ans.

Quand je rencontre du code pourri, je ne le commente pas, je le ré-écris. J'ai refait des framework entiers, découplé et dé-dupliqué du code legacy, et même là tout de suite j'ai un refactoring de 3 semaines actuellement en revue.

C'est pour ça que je prends chaque année des évaluations et des augmentations dithyrambiques. Pas parce que je suis plus rapide que les autres, je suis plus lent, pas parce que je livre plus, je livre moins, mais parce que je clean tout ce que je trouve et que j'étends ce que je standardise au code legacy même quand il ne me concerne pas. Sans commentaires.

Si tu avais lu les liens que je t'ai donné, tu aurais vu que le meilleur cadeau à faire aux autres, ce n'est pas de rajouter des lignes de commentaires mais d'extraire les blocs de caca en méthodes, variables claires, etc ....

D'ailleurs, bien systématiquement dès le départ ça n'existe pas. Je repasse moi même très régulièrement dans mon propre code. Parce que le besoin à changé, parce que j'ai pris une mauvaise décision dans un contexte donné, parce que je me retrouve face à une problématique similaire et que je décide de découper ce que j'ai fait en morceaux réutilisables, etc ...

Alors non, je ne vis pas avec
L'un n'empêche pas l'autre !
Le refactoring est aussi ma partie et j'en connais des centaines de règles.

Mais il n'empêche : chez un client, tu n'as pas le temps matériel de tout reconstruire ; d'ailleurs, il ne te paie pas pour cela, le plus souvent.
Mais je dis : au moins, en passant sur un code – n'importe lequel – ce qu'on en a compris, ce qui éclaircit, on l'écrit en commentaire, pour que l'effort de compréhension que l'on a été amené à faire, le programmeur suivant, il n'ait plus besoin de le faire.
Zangdar :
Je ne comprends pas pourquoi tu voudrais interdire les commentaires ?
Imagine une petite méthode d'une dizaine de lignes qui fait un truc facile à expliquer.
Pourquoi voudrais-tu obliger les gens à lire une dizaine de lignes, plutôt que une seule, c'est à dire l'explication facile du truc ?
Quand bien même ces dix lignes seraient optimisées le plus possible du point de vue de la clarté.
Citation :
Publié par Zangdar MortPartout
J'ai fait de l'aérospatiale, code vieux de 30 ans.

Quand je rencontre du code pourri, je ne le commente pas, je le ré-écris. J'ai refait des framework entiers, découplé et dé-dupliqué du code legacy, et même là tout de suite j'ai un refactoring de 3 semaines actuellement en revue.

C'est pour ça que je prends chaque année des évaluations et des augmentations dithyrambiques. Pas parce que je suis plus rapide que les autres, je suis plus lent, pas parce que je livre plus, je livre moins, mais parce que je clean tout ce que je trouve et que j'étends ce que je standardise au code legacy même quand il ne me concerne pas. Sans commentaires.

Si tu avais lu les liens que je t'ai donné, tu aurais vu que le meilleur cadeau à faire aux autres, ce n'est pas de rajouter des lignes de commentaires mais d'extraire les blocs de caca en méthodes, variables claires, etc ....

D'ailleurs, bien systématiquement dès le départ ça n'existe pas. Je repasse moi même très régulièrement dans mon propre code. Parce que le besoin à changé, parce que j'ai pris une mauvaise décision dans un contexte donné, parce que je me retrouve face à une problématique similaire et que je décide de découper ce que j'ai fait en morceaux réutilisables, etc ...

Alors non, je ne vis pas avec
Comment tu t'assures que le code que tu refais marche comme l'ancien quand tu fais du refactoring ? Scripts de test auto et couverture de code à 100% ?
Je bosse tous les jours sur un soft de plusieurs millions de ligne de code. Les test soft étant quasi inexistant, je suis dans la merde si je veux recoder des algos. Ça mène à dupliquer du code et faire des verrues. C'est horrible mais dans bien des cas, je ne peux pas faire autrement :/
Sans tests, de toute facon ton legacy n'a aucune garantie de bon fonctionnement autre que le fait qu'il n'y ai pas eu de bug reporte depuis X temps.
Donc quand tu fait ton refactoring, tu rajoute les tests en meme temps que le nouveau code.
Effectivement tu n'a aucune garantie que ca fonctionne comme l'ancien, a moins de faire tourner tes nouveaux tests d'integrations sur l'ancienne version (si possible) et la nouvelle et t'assurer qu'ils sont iso fonctionnel.
Si vraiment c'est du code critique et tu n'es pas sur que tes tests couvre 100% des cas d'utilisations, en dernier recours tu construit a cote, tu rajoute quelques pour verifier les usages, et tu force toutes les nouvelles features a passer sur le nouveau code en attendant de pouvoir virer l'historique.

Il n'y a pas 36 solutions avec un code base merdique:
Cas 1: Soit il est stable et on n'y touche pas du tout, donc pas besoin de refactoring,
Cas 2: Soit il est stable mais on dois le faire evoluer et dans ce cas le risque d'introduire est nouveau bug est similaire au risque d'avoir un bug avec le refactoring,
Cas 3: Soit de toute facon il n'est pas stable et autant le faire proprement.

sauf que bien souvent on garde le code de merde avec le discours qui va bien: "rajoute juste ca, et c'est bon on a pas le temps pour l'ameliorer."
Et tu te bat pour montrer qu'en depensant 20jours de plus maintenant on va en economiser 15 sur le support et 15 autres sur chaque evol qui touche ce produit.
Sauf que les 10 de plus sont sur le budget de la R&D qui a d'autres priorites et qui doit livrer de nouvelles fonctionalites et n'a pas le temps/les ressources pour faire du refactoring,
ou sur le budget du projet qui a deja ete vendu avec des delais impossible a tenir et dont le CDP se contrefous des prochains projets puisqu'il ne sera probablement pas dessus,
Et tout le monde se contrefous du budget du support puisqu'il a ete delocalise et coute de toute maniere 10fois moins qu'un dev.

Et au bout d'un moment tu en a marre et tu te barre dans une boite qui accepte de faire les choses correctement et surtout de prendre le temps de les faire.
Citation :
Publié par Ex-voto
Comment tu t'assures que le code que tu refais marche comme l'ancien quand tu fais du refactoring ? Scripts de test auto et couverture de code à 100% ?
Je bosse tous les jours sur un soft de plusieurs millions de ligne de code. Les test soft étant quasi inexistant, je suis dans la merde si je veux recoder des algos. Ça mène à dupliquer du code et faire des verrues. C'est horrible mais dans bien des cas, je ne peux pas faire autrement :/
Le vieux code est peu testé alors couverture de code, écriture de tests avec prise de référence pour comparer ancien/nouveau et puis de l'expérience. Plus tu en fais, plus tu es capable de détecter comme un grand ce que tu pètes et de te poser les bonnes questions. J'arrive à attraper la plupart des choses désormais, il y a parfois quelques régressions qui passent mais rien de majeur comparé au bénéfice et il y a toujours un filet de sécurité car les reviewers testent, et ensuite d'autres équipent passent des cahiers d'essais etc .... J'ai eu une seule fois régression qui est arrivée chez un client et c'était suite à un refactoring majeur avec oubli de dé-commenter une seule ligne de code. Et si elle est arrivée chez le client, c'est parce que le processus habituel ne pouvait pas être suivi car on était tous chez le client et qu'on testait chez lui.

Et l'idée c'est d'y aller petits morceaux par petits morceaux aussi. Après le risque zéro n'existe pas et des fois il faut savoir fuir devant l'ennemi.

J'ai bossé dans ton genre de code, tu ne peux effectivement rien toucher parce qu'il y a trop de magie noire derrière. On avait une structure de pointeur, suivant que tu remplissait la structure de façon déclarative ou que tu modifiais son élément dans une fonction, ça ne donnait pas le même résultat de calcul à la fin. J'ai vu des structures de calcul entièrement dupliquées et quand tu en supprimais une, ça pétait un truc ailleurs dans le code alors que les deux donnaient strictement les même valeurs. Magie.
Ce genre de truc tu peux y aller petit bout par petit bout mais tu peux pas te lancer direct dans un truc majeur. Par contre, je n'ai jamais dupliqué une ligne de code, parfois on peut pas réécrire mais on peut presque toujours découper / dé-dupliquer.

Par contre chez ces mecs j'ai refait intégralement leur framework de test, un truc énormissime avec un budget de 80.000$. Ils étaient flippés à mort et ne voulaient pas que ce qu'on faisait arrive dans leur projet. La politique de l'équipe c'était de ne toucher à rien de ce qui marche, quitte à dupliquer en masse (du coup c'était pourri leur affaire hein). C'est devenu hyper politique entre l'équipe projet et le mec qui payait, du coup tous les soirs on lançait des batchs de tests énormes avec tous les tests qu'on avait modifiés, le matin il fallait dé-pieuter les résultats et comme la moitié des tests faillaient il fallait déterminer si ça venait de nous ou pas, des merges hallucinants à faire parce que les types continuaient de modifier les tests existants et nous on ne pouvait jamais merger chez eux.

On s'en est tirés avec ptet 2 ou 3 trucs qui sont passés et ça leur a prouvé à tous qu'avec de la méthode on s'en sort très bien.

Citation :
Et tu te bat pour montrer qu'en depensant 20jours de plus maintenant on va en economiser 15 sur le support et 15 autres sur chaque evol qui touche ce produit.
Sauf que les 10 de plus sont sur le budget de la R&D qui a d'autres priorites et qui doit livrer de nouvelles fonctionalites et n'a pas le temps/les ressources pour faire du refactoring,
ou sur le budget du projet qui a deja ete vendu avec des delais impossible a tenir et dont le CDP se contrefous des prochains projets puisqu'il ne sera probablement pas dessus,
Et tout le monde se contrefous du budget du support puisqu'il a ete delocalise et coute de toute maniere 10fois moins qu'un dev.
Exactement ça sauf que nous on fait le support alors les mecs en prenaient plein la tronche mais ne changeaient jamais leurs habitudes.

Dernière modification par Zangdar MortPartout ; 29/04/2017 à 03h02.
Citation :
Publié par Ex-voto
Comment tu t'assures que le code que tu refais marche comme l'ancien quand tu fais du refactoring ? Scripts de test auto et couverture de code à 100% ?
Je bosse tous les jours sur un soft de plusieurs millions de ligne de code. Les test soft étant quasi inexistant, je suis dans la merde si je veux recoder des algos. Ça mène à dupliquer du code et faire des verrues. C'est horrible mais dans bien des cas, je ne peux pas faire autrement :/
Il y a trois types de tests automatisables :
1) Les tests unitaires, qui s'exécutent après la compilation mais avant que le projet/module (qui est une partie de l'application à produire) réalise son son édition de lien/production d'artefact.
Ils doivent théoriquement ne tester que des objets "autonomes" (qui ne requièrent pas immédiatement une base de données, une IHM présente, etc.), être quasi-instantanés (100 tests unitaires ne doivent pas prendre plus de 1 ou 2 secondes au total).
Ils doivent être simples et aller à l'essentiel.

2) Les tests d'assemblage. Lorsqu'un module/projet a produit son artefact/librairie ou dll, celle-ci est déployée sur un serveur embarqué (en Java : Tomcat, TomEE, autres) sur une base de données en mémoire (en Java, H2, alimentée par du Liquibase, par exemple).
On joue des tests qui montrent que le module déployé offre bien les services que l'on voudrait.
Les tests d'assemblage du projet A, testera les fonctionnalités de A,
celui de B qui suivra pourra tester les fonctionnalités de B (s'il le veut, en assumant que A est déployé),
celui de C, C + B + A, etc.
Même un mockage de fonctions en tests unitaires n'a pas la valeur d'un test d'assemblage, qui est le plus efficace de tous les types de tests que je pratique.

3) Les tests d'intégration. Lorsque tous les projets/modules ont étés produits et que l'application est créée, elle est déployée. Cette fois, sur un serveur non embarqué, et avec une base réelle.
Des tests supplémentaires sont joués qui peuvent éprouver toute l'application sans limites.
C'est le moment où l'on peut, si l'on veut, mettre en place des tests d'IHM automatisés (par exemple, en Java pour le web avec Selenium) pour la vérifier complètement.
Et donc sur ton existant,

Lorsque tu arrives sur un existant qui a plusieurs millions de lignes de code, il y a en général trois situations :
- Soit les tests unitaires sont là et tu les poursuis.
- Soit ils n'ont jamais été écrits.
- Soit ils ont étés écrits mais ont étés mis en ignore / skip tests depuis longtemps. Deux raisons à cela :
- On a demandé à l'équipe des évolutions trop rapidement sur l'existant, et elle n'a pas eu le temps de ré-accorder les tests avec le code applicatif, alors elle a mis un ignore.
Et il y a deux mots-clefs universels dans les langages de programmation quand on devrait faire quelque-chose mais qu'on a pas envie de faire : ignore, et TODO...

- Les tests unitaires durent 4 minutes pour chaque construction d'application.
C'est le cas lorsque les TU n'ont pas étés répartis en tests d'assemblage ou d'intégration.
Tests Unitaires = à la compilation.
Tests d'Assemblage = au commit, automatisés par un outil d'intégration continue.
Tests d'Intégration = à la veille d'une release.
Si les tests unitaires sont trop lents, 50% à 100% de l'équipe va finir par mettre un skipTests dans ses directives de compilation et ils ne serviront plus à rien...
S'il n'y a aucun test unitaire, il y a toutes les chances que le code ne s'y prête plus depuis longtemps.
Ce que tu feras en tests unitaires (sur des objets autonomes) risque d'être insignifiant en comparaison de la masse de code non testée.
Tu ne pourras pas plus mettre de tests d'assemblage, qui réclament une mise en place initiale d'un script et d'outils dédiés (ticket d'installation : environ 10 jours de boulot...).
Il risque de ne pas y avoir d'issue par là.

Que faire ?

Lorsque je tombe dans un code qui a l'air instable, qui n'est pas testé, le mieux est d'agir en refactoring et en programmation défensive.

Sur une classe qui aura un nombre de ligne trop grand ou un code incompréhensible :
1) Recherche des notions qu'elle aborde : agit-elle sur une chose, deux choses, trois choses, dix choses ?
Si elle parle d'articles, de fournisseurs, de rayons et d'étiquettes en gérant tout l'ensemble, c'est qu'il est temps de la diviser en sous-classes dédiées.

2) Si les notions ne sont pas très visibles ni son fonctionnement,
il faut renommer ses variables et noms de fonctions pour exprimer mieux ce qu'elle fait.
Fait-elle du métier ou de la technique ? Si elle fait les deux, il faudra encore la diviser.
En passant, on commente le code : notre but est de permettre au client de se réapproprier ce code qui tombe en déshérence, faute de personnes pour le comprendre.

3) On met en place ces règles :
- Aucune fonction autre qu'un getter d'objet métier ne peut renvoyer de valeur nulle.

- Aucune fonction validant quelque-chose ne peut se cantonner à renvoyer un booléen ou un String pour dire l'anomalie qu'elle constate.

- Soit une fonction renvoie l'objet qu'on lui a demandé/exécute ce que l'on désire, soit elle renvoie une exception.

- L'exception qu'elle renvoie en cas d'échec n'est pas une Exception en classe de base, mais une classe héritée d'Exception dédiée au problème spécifiquement rencontré : ArticleInexistantException, RayonAbsentException, ArticleSansEtiquetteException, etc. Même chose pour les exceptions techniques.

Le seul retour qu'une fonction s'autorise, c'est en cas de réussite complète. Sinon, elle lève une exception, donc.
Alors, l'appelant de cette fonction soit :
- gère l'exception parce qu'il l'interprète dans son contexte d'appel. Il comprend ce qu'il doit en déduire, et peut éventuellement agir : soit en choisissant une voie d'action alternative, soit en levant une autre exception désignant la conclusion finale qu'il en tire et qui l'empêche d'aboutir (exemple : un appelant pourra transformer un ArticleInexistantException en FournisseurArticleInexistantException si c'est son interprétation finale du problème),

- soit il ne sait pas quoi en faire et il la propage à son tour à son propre appelant.

Si personne n'a intercepté l'exception, le programme s'arrêtera dès le développement dans des situations à évaluer. Il deviendra de plus en plus strict, de plus en plus robuste.
Le but est de parvenir à reformuler dans ses classes le réseau de Petri le plus fin possible qui les représente le mieux.
Des fonctions courtes, où chaque place représente un unique état, tel que :
- l'état initial est commenté par le commentaire au dessus de la fonction "à partir de ceci, je fais faire cela"

- les places et transitions intermédiaires entre le début et la fin de la fonction sont commentées.

- Un bloc d'instruction impératives (sans if, while, for, throw, et qui ne peut être interrompu par une exception en s'exécutant, en un mot : qu'on peut considérer comme atomique), représente une transition, et a un commentaire au dessus de lui pour résumer son action globale.

- Un if, for, while représente les arcs du réseau de Pétri et ont aussi un commentaire au dessus d'eux pour dire ce qu'ils testent.

- Les sorties en exception sont documentées dans les commentaires de méthode. Et chaque sortie correspond à une place distincte du réseau de Pétri. Les causes d'erreurs ne sont pas ainsi fusionnées en une seule ce qui serait ambigu.
Le programme est fait pour le client, à destination des gens qui y exercent leur métier.
Le réseau de Pétri représente ce qu'ils ont demandé.
Quand on le lit, on lit ce que l'on a demandé et l'enchaînement pour le faire. Un analyste fonctionnel en comprend la grande majorité ou bien il y a un problème.
Les commentaires que l'on lit dans le programme sont en rapport avec ce déroulé.

Ça fait une bonne dizaine d'années que je fais du refactoring et du sauvetage d'application chez des clients en situation difficile.

@MadmaX : à la manière dont un plombier va chez des personnes où les installations sont belles et jolies comme d'autres où elles sont vétustes, mal entretenues ou qu'un mauvais professionnel passé (ou le résident lui-même s'est cru capable d'intervenir, mal-à-propos),
à la manière où il y a de bonnes cuisines de restaurants bien organisées et de mauvaises qui sont brouillonnes, mauvaises et lentes,
ou bien des services comptables alertes et précis, et d'autres qu'il faut alerter, surveiller et corriger,
l'informatique a tous les environnements de travail qu'on peut imaginer : du meilleur au moins bon. Le quotidien sera de profiter des unes et de réparer les autres.

Je ne connais pas beaucoup de métiers où ce soit très différent.

Dernière modification par Caniveau Royal ; 29/04/2017 à 07h42.
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés