
L'import d'une librairie doit être rapide à déceler
Il est également important de bien différencier la source des librairies : standard, externe ou locale
Les imports sont à placer au début d'un script.
Ils précèdent les Docstrings.
Une ligne par librairie.
Exemple : import
os
Une ligne peut néanmoins inclure plusieurs composantes.
Exemple : from subprocess import Popen, PIPE
L'import doit suivre l'ordre suivant : Bibliothèques standard, Bibliothèques tierces et imports locaux. Sautez une ligne entre chacun de ces blocs.
Pas d'espace avant : mais un après.
Exemple : {oeufs: 2}
Opérateurs: un espace avant et un après.
Exemple : i = 1 + 1
Aucun espace avant et après un signe = lorsque vous assignez la valeur par défaut du paramètre d'une fonction.
Exemple : def elephant(trompe=True, pattes=4)
Une instruction par ligne.
Ecrivez des phrases complètes, ponctuées et compréhensibles.
Le commentaire doit être cohérent avec le code.
Il doit suivre la même indentation que le code qu'il commente.
Evitez d'enfoncer des portes ouvertes : ne décrivez pas le code, expliquez plutôt à quoi il sert.
Il doit être en anglais.
Modules : nom court, tout en minuscules, tiret du bas si nécessaire. great_module
paquets : nom court, tout en minuscules, tirets du bas très déconseillés. paquet
classes : lettres majuscules en début de mot. MyGreatClass
fonctions : minuscules et tiret du bas : my_function()
méthodes : minuscules, tiret du bas et self en premier paramètre : my_method(self)
arguments des méthodes et fonctions : identique aux fonctions. my_function(param=False)
variables : identique aux fonctions.
constantes : tout en majuscules avec des tirets si nécessaire. I_WILL_NEVER_CHANGE
privé : précédé de deux tirets du bas : __i_am_private
protégé : précédé d'un tiret du bas : _i_am_protected
def maFonction(a, b):
"""
Cette fonction est une fonction de test
Elle sert a calculer a + b
:param a : Valeur 1
:param b : Valeur 2
:return : Somme des Valeur 1 et Valeur 2
"""
return(a + b)
print(maFonction(1, 2))
Couverture des fonctions (ou méthodes) : est-ce que toutes les méthodes du code ont été appelées par les tests ?
Couverture des instructions : est-ce que les tests sont passés sur chaque ligne de code ?
Couverture des chemins d’exécution (décisions) : est-ce que l’on est passé dans toutes les branches de notre code ? Par exemple, l’instruction if génère deux branches de code : une dans laquelle la condition évaluée est vraie, une autre où la condition est fausse.
Couverture des points de tests (MCDC) : est-ce que chaque condition sur le test d’une variable a été couverte ?
La complexité cyclomatique d'une méthode est définie par le nombre de chemins linéairement indépendants qu'il est possible d'emprunter dans cette méthode.
Plus simplement, il s'agit du nombre de points de décision de la méthode (if, case, while, ...) + 1 (le chemin principal).
La complexité cyclomatique d'une méthode vaut au minimum 1, puisqu'il y a toujours au moins un chemin.
Une complexité cyclomatique trop élevée (supérieure à 30) indique qu'il faut refactoriser la méthode. Une complexité cyclomatique inférieure à 30 peut être acceptable si la méthode est suffisament testée.
La complexité cyclomatique est liée à la notion de "code coverage", c'est à dire la couverture du code par les tests. Dans l'idéal, une méthode devrait avoir un nombre de tests unitaires égal à sa complexité cyclomatique pour avoir un "code coverage" de 100%. Cela signifie que chaque chemin de la méthode a été testé.
La notion de qualité d'une application repose aussi sur la notion de sécurité .
Différentes métriques peuvent être mises en place pour :
détecter les vulnérabilités de composants tiers (CVE : Common Vulnerabilities and Exposures)
détecter des problèmes potentiels d'injection de dépendances, d'injection SQL ...
détecter des mauvaises configurations, des fichiers non sécurisés ...
PylintFlake8, PylamaBandit pour la partie sécurité, radon pour la complexitéSonarQube est un logiciel libre permettant de mesurer la qualité du code source en continu sur de nombreux langages
identification des duplications de code
mesure du niveau de documentation
respect des règles de programmation
détection des bugs potentiels
évaluation de la couverture de code par les tests unitaires
analyse de la répartition de la complexité
analyse du design et de l'architecture d'une application
mesure d'une dette technique