Fiabilité des fichiers dans des frameworks PHP

Nous présentons ici les résultats obtenus lors de l'étude statistique des fichiers de projets de type "framework" : Akelos, Prado, CodeIgniter et Solar. Il s’agit de déterminer s’il existe des ressemblances ou différences entre ces projets du point de vue de la fiabilité des fichiers qui les constituent. On commencera par commenter les résultats projet par projet, avant d’essayer de dégager des métriques communes qui favorisent l’apparition de bugs et d’autres qui la freinent. Le commentaire du premier projet sera détaillé pour une meilleure compréhension du principe de l’analyse, puis les suivants seront plus brefs.

Akelos


Ici, on peut tout d’abord noter que la distribution des bugs est très spécifique. L’écrasante majorité des fichiers n’a jamais été marquée « buggé » - problème de repérage des bugs ? Oubli de mots-clés définissant un bug ? - et la décroissance du nombre de fichiers en fonction du nombre de bugs constatés sur ces fichiers est extrêmement rapide.

Ensuite, on peut constater que les quatre principaux facteurs dégagés par le modèle sont la profondeur de l’arbre d’héritage (dit_per_class), la taille de la classe (csz_pr_class) , le nombre de méthodes par classes (nom_per_class) et le ratio nombre de lignes commentées par nombre de lignes non commentées (comments). Les deux principaux effets sont "attendus" : la proportion de commentaires diminue le nombre de bugs tandis que le nombre moyen de méthodes par classes contenues dans un fichier l'augmente. Les deux effets secondaires quant à eux le sont moins. Premièrement, plus la taille moyenne des classes du fichier est grande, moins on observe de bugs. Cet effet est assez difficile à interpréter. Secondement, la profondeur moyenne de l’arbre d’héritage des classes d’un fichier favorise l’apparition de bugs. Cela semble aller contre l’idée commune que l’on se fait de l’héritage : il est censé améliorer le code. Une interprétation de cet effet serait de dire que l’on pourrait voir là un signe d’une "mauvaise" utilisation de l’héritage dans ce projet. C’est bien sûr aux parties prenantes du projet de le déterminer...

Enfin, le graphique des fichiers dans le plan des deux principaux facteurs dégagés par le modèle permet de voir que ces deux facteurs permettent bien de distinguer les fichiers avec un nombre faible de bugs (aucun bug) de ceux avec un nombre "élevé" (plus d’un bug), mais repère assez mal les fichiers "moyennement" buggés (un bug).

Prado

Pour Prado, on peut remarquer que le nombre de bugs se répartit sensiblement de la même façon.

Les quatre facteurs principaux sont la taille de l’interface de classe (définition à affiner!), la taille de la classe (csz_pr_class), la profondeur de l’arbre d’héritage (dit_per_class), et le nombre de contributeurs au fichier. On se limitera à l’interprétation des deux effets principaux.

Le nombre de contributeurs au fichier influence positivement le nombre de bugs constatés sur ce fichier. On peut y voir deux choses: un effet mécanique et un effet plus "pertinent".

L’effet mécanique concerne les "petits" contributeurs, i.e. ceux qui rapportent des bugs principalement. Mécaniquement, plus un projet a de petits contributeurs qui font de la correction de bugs, plus l’effet du nombre de contributeurs sur le nombre de bugs sera positif - et trivial. L’effet plus "pertinent" concerne les contributeurs qui développent à proprement parler. Un nombre de contributeurs important entraîne fatalement des problèmes de coordination, en particulier dans des projets Open Source, et peut nuire à la fiabilité du code.

La profondeur moyenne de l'arbre d'héritage influence elle aussi positivement le nombre de bugs constatés sur les fichiers. On peut faire la même interprétation que pour Akelos.

CodeIgniter

La répartition du nombre de bugs par fichier pour le projet CodeIgniter est quelque peu différente. On remarque d’une part qu’aucun fichier n’a été marqué comme non buggé, ce qui peut sembler suspect - est-ce la réalité ou un problème d’identification des bugs sur les fichiers ? - et d’autre part que le nombre de bugs décroît moins rapidement. On peut aussi y voir le signe d’un code "vieux" et souvent remanié, ce qui est le cas de CodeIgniter.

Les quatre métriques principales dégagées par le modèle sont le nombre de contributeurs (nb_contributors), le nombre de variables moyen par classe du fichier (vars_per_class), eloc_per_class et enfin la taille de l’interface de classe moyenne (cis_per_class).

Là encore, l’interprétation des effets de cis_per_class(qui favorise l’apparition de bugs) et eloc_per_class (effet inverse) est difficile étant donné qu’on ne connaît pas très bien leur signification. Pour ce qui est du nombre de contributeurs, on observe le même effet que précédemment. Enfin, plus le nombre moyen de variables par classe du fichier est grand moins, il y a de bugs - difficile à expliquer.

Enfin, sur le dernier graphique, on peut remarquer que les fichiers sont biens discriminés par la variable cis_per_class en abscisse (très buggés à droite et peu buggés à gauche) mais que l'effet de la variable eloc_per_class ne semble pas cohérent avec le graphique précédent. En effet, celui-ci montre que cette variable a un effet de réduction du nombre de bugs. Or, il semble que les fichiers buggés prennent des valeurs plus grandes que les autres pour cette variable (ils sont au-dessus). Ce qui pourrait paraître une anomalie peut en fait s’expliquer par la domination de l’effet cis_per_class sur l’effet eloc_per_class : les fichiers très buggés qui prennent de fortes valeurs pour eloc_per_class prennent aussi des valeurs élevées pour cis_per_class, et c’est cette dernière caractéristique qui domine. Cela peut donc expliquer la répartition "étonnante" des fichiers dans le plan des deux facteurs principaux. On en conclut que la métrique vraiment importante est cis_per_class.

Solar

La distribution des bugs pour le projet Solar est assez semblable à celles d’Akelos et Prado. Elle dénote peut-être d’un projet récent et encore peu remanié.

Les quatre métriques prépondérantes dégagées par le modèle sont le nombre moyen de variables par classe du fichier (vars_per_class), la proportion de commentaires dans le code (comments), la complexité cyclomatique moyenne par classe du fichier (wmci_per_class) et enfin la profondeur moyenne de l’arbre d’héritage par classe du fichier (dit_per_class).

Ici, on observe des effets intéressants qui distingue quelque peu ce projet des autres, en cela que ces effets estimés semble tous concorder peu ou prou à l’intuition que l’on s’en fait a priori, et en font un cas d'école.

Premièrement, le nombre moyen de variables par classe, contrairement à ce qu’on observe pour CodeIgniter, augmente le nombre de bugs, ce qui est plus conforme à l’intuition : un nombre important de propriétés définies dans une même classe augmenterait son instabilité. Deuxièmement, l’effet de la métrique "comments" reste le même. Troisièmement, la complexité cyclomatique d’une classe augmente le nombre de bugs. Quatrièmement enfin, la profondeur moyenne de l’arbre d’héritage par classe du fichier le diminue, ce qui nous "rassure" : l’héritage, bien utilisé permet de rendre un code d’une qualité significativement plus grande.

Conclusion sur les frameworks

On peut tirer quatre conclusions - provisoires - à partir de ces études.

D’abord la distribution du nombre de bugs par fichier est sensiblement la même - modulo l‘ancienneté du projet - d’un framework à l’autre.

Ensuite, on retrouve régulièrement certaines métriques avec des effets identiques : la proportion de commentaires dans le code, d'un côté, qui diminue le nombre de bugs, la taille moyenne de l’interface de classe ou le nombre de contributeurs à un fichier, de l'autre, qui l’augmentent.

A contrario, on retrouve des métriques dans différents projets qui ont des effets inverse selon le projet concerné : la profondeur moyenne de l’arbre d’héritage ou le nombre de variables par classe du fichier.

Ce qui nous amène à la quatrième et dernière conclusion : les interprétations précédentes ne sont que des tentatives et sont menées plutôt à titre d’exemples tant une interprétation vraiment pertinente nécessite une bonne connaissance des caractéristiques du projet concerné (ancienneté, compétences spécifiques, etc.).

Bref, c’est aux parties prenantes du projet d’utiliser, si elles le souhaitent, ces analyses et de leur donner un sens ou non.