Qualité
Programmation dirigée par les tests
1. Tests unitaires
a. Principes
La programmation impérative ou objet nécessite la création de classes, d’instances et de fonctions.
Celles-ci ont un comportement déterministe qui est reproductible. En clair, une fonction utilisée avec les mêmes paramètres produit le même résultat.
Voici un exemple simple :
>>> def carre(x):
... return x**2
...
Il est possible de créer un test sur cette fonction. Cela consiste à mettre en regard une série de paramétrages et pour chacun le résultat attendu :
>>> def test_carre():
... for x, r in {2: 4, 0: 0, -2:4}.items():
... if carre(x) != r:
... print('test échoué')
... break
... else:
... print('test réussi')
...
b. Interprétation
Lorsque l’on exécute cette fonction, deux résultats sont possibles. Il se peut que la fonction réussisse :
>>> test_carre()
test réussi
Cela ne signifie pas que la fonction est correcte, mais qu’elle passe tous les tests prévus. La représentativité des tests est donc cruciale. Voici un exemple :
>>> def moyenne(valeurs):
... return sum(valeurs)/len(valeurs)
...
Si l’on ne teste pas spécifiquement la fonction avec une liste de valeurs vide, on passe à côté d’un cas d’utilisation. Voici un autre cas (tester [-5, 6, -1]) :
>>> def balance(valeurs):
... sum([abs(n) for n in valeurs])/sum(valeurs)
...
L’autre possibilité est que le test soit négatif. Là encore, cela ne veut pas forcément dire que la fonction n’est pas valide. Cela signifie simplement que l’un des tests ne passe pas. Il faut alors vérifier s’il s’agit d’une erreur de la fonction testée ou d’une erreur du test.
Voici un exemple d’une fonction particulièrement mal écrite :
>>> def choix(valeur):
... if valeur < 0:
... return 0 ...
Programmation dirigée par la documentation
1. Documentation interne
a. À destination des développeurs
Écrire une documentation à l’intérieur même du code est le meilleur moyen de fournir les explications au lecteur du code.
Cela facilite donc la prise en main du code pour toute personne qui voudrait s’y investir, et dans un contexte de logiciel libre, par exemple, c’est indispensable. Le nombre de logiciels libres qui souffrent d’une communauté trop restreinte uniquement parce que le code est mal documenté est trop important et nuit gravement à la pérennité du logiciel libre en question.
Cela nous sert également à reprendre son propre code après être passé sur d’autres projets entre-temps.
Une des particularités de Python est de créer des tests unitaires au sein de la documentation (http://docs.python.org/library/doctest.html). Le procédé est simpliste, permet au lecteur de voir une mise en situation et peut servir de test unitaire minimaliste.
Ainsi, en Python, il n’y a pas de commentaire de code, mais de vraies documentations qui permettent d’appréhender le code dès lors qu’elles sont complètes et bien réalisées.
b. À destination des utilisateurs
Aider le développeur à se plonger dans le code de son application ou de sa bibliothèque est loin d’être la seule motivation de ces documentations. En effet, Python propose des outils absolument magnifiques. D’abord, il y a pydoc qui offre depuis python 3.2 une meilleure présentation, c’est un outil de recherche rapide et dont l’option -b ouvre dans un navigateur :
$ pydoc module_test
Cela permet de visualiser la documentation de la même manière que si l’on avait ouvert une console et utilisé la commande help sur le module.
Mais une autre commande permet de générer une documentation HTML :
$ pydoc -w module_test
Le résultat est désuet, mais efficace. Pour produire quelque chose visuellement plus attrayant, il y a epydoc :
$ epydoc --html module_test -o path
Il s’installe ainsi :
$ sudo aptitude install python-epydoc
Le tout fait que la documentation peut être publiée sans autre effort de rédaction.
2. Documentation externe
a. Présentation...
Optimisation
1. Qualimétrie
La qualimétrie consiste à produire des indicateurs de qualité pondérables et à évoluer un processus de développement logiciel sur cette base. La pondération fixe les priorités à donner à chaque indicateur et par conséquent, doit guider les équipes MOE et MOA dans leurs choix. Deux évaluations avec des indicateurs différents mènent donc potentiellement à des résultats distincts.
Ces indicateurs couvrent l’ensemble du processus de développement, pas uniquement la qualité du code elle-même. Cela peut être la qualité des tests unitaires, fonctionnels, de performance liés au projet, mais également les processus de signalisation d’un bug, la solidité de la solution de gestion de version utilisée, la formation des équipes de développement et la cohérence du travail en groupe ou encore la qualité de la documentation.
Ceux-ci sont fortement liés à la politique de gestion des exigences du projet qui peut être inexistante à très détaillée et précise.
Il existe une norme qui est ISO 9126 et hiérarchise ces indicateurs :
-
Capacité fonctionnelle (regarde la conformité fonctionnelle) :
-
Aptitude
-
Exactitude
-
Interopérabilité
-
Sécurité
-
Fiabilité (donne le taux de confiance que l’on peut avoir dans le logiciel) :
-
Maturité
-
Tolérance aux pannes
-
Possibilités de récupération
-
Facilité d’utilisation (indique la complexité de prise en main du logiciel au regard de sa complexité fonctionnelle et son taux d’adhésion) :
-
Compréhensibilité
-
Facilité d’apprentissage
-
Exploitabilité
-
Attractivité
-
Efficacité (mesure les « performances » du logiciel) :
-
Efficacité en termes de temps
-
Efficacité en termes de ressources
-
Maintenabilité (indique l’effort à fournir pour maintenir/corriger/adapter le logiciel en assurant sa continuité de fonctionnement) :
-
Facilité d’analyse
-
Facilité de modification
-
Stabilité
-
Testabilité
-
Portabilité (donne des éléments sur la qualité...