La qualité logicielle :
enjeux, outillage, processus
Hello!Je suis Sylvain Leroy
Vous pouvez me trouver sur :[email protected] / @sleroy0 about.me/sylvain_leroy
2007
Ingénieur Recherche
Informatique
2011
Création Société Tocea
2014
Acquisition Tocea Groupe Metrixware
CTO Tocea
2015
Acquisition EchoesGroupe Metrixware
CTO Metrixware
Projet Recherche
Ma Société
▧Assistance Qualité / Recette applications
▧Modernisation automatique d’applications
▧Offre Intégration Usine Logicielle
▧Formateurs Bonnes Pratiques /Cleancode / Qualité / Devops
▧Distributeur Outils de qualité de code (Optimyth)
▧Komea Dashboard (Pilotage développements par la qualité/productivité)
▧Offres Cobol/Mainframe
Contrôler la qualité du
code
Analyser la qualité
d’un logiciel
L’audit fonctionnel
Vérifier l’adéquation du logiciel avec les attentes métiers / utilisateurs
La méthodologie DDDpublic boolean peutReserver(Cargo cargo, Voyage voyage) {
double maxReservations = voyage.capacite * Constants.SURCAPACITE_RATIO;
if (voyage.tailleCargoReserve + cargo.taille >maxReservations) {
return false; }}
public boolean peutReserver(Cargo cargo, Voyage voyage) {if (!overbookingRegle.estAutorisee(cargo, voyage)) {
return false; }}
Domain Driven Design
▧Définition d’un langage commun utilisateur / concepteurs / développeurs
▧Documentation d’un lexique des termes métiers (et règles métiers)
▧Inférence entre le métier et la structure de l’application
▧Définition d’un modèle métier▧Nécessité de silo-ter
fonctionnellement/données => Architecture microservices
▧Des frameworks existent (optionnels) : Qi4J
Le choix des technologies
Choisissez vos technologies avec soin
Nexus Lifecycle Auditor ($$)
Le choix d’une technologie peut avoir un impact sur la qualité du produit
JDBC pur
193 lignes Java
Spring JDBC
140 lignes Java
MyBatis
46 lignes XML
Spring Data
20 lignes Java
Exemple d’utilisation
Groovy/Grails
Exemple d’utilisation JSP vs
Thymeleaf vs Mustache ?
Spring Initializr
Les choix de licences
GPL/LGPL/AGPL/WTF/ASF/CC?
https://www.inria.fr/content/download/5896/48452/version/2/file/INRIA_recueil_fiches_licences_libres_vf.pdf
Qu’utilisez-vous pour générer du
PDF ?IText ?
Quelle version ?>=5 ?
Vous devez tout mettre en opensource ou payer une licence
Antepedia(€)
Fossology
L’architecture de l’application
Mesurer le respect des règles d’architecture définies dans
l’application
Structure101, Macker, ...
<?xml version="1.0"?><macker> <ruleset name="Simple example"> <access-rule> <deny> <from class="**Print*" /> <to class="java.**" /> </deny> </access-rule> </ruleset></macker>
https://innig.net/macker/
(Checking ruleset: Layering rules ...)
Only the model can talk to the persistence layerIllegal reference from net.innig.macker.example.layering.gui.ThingerUI to net.innig.macker.example.layering.persistence.PersistenceException
(1 error)
Macker rules checking failed
Macker
(free)
Structure101 ($$)
SonarQube (free/€€)
La maîtrise des technologies
Contrôlez l’application des bonnes pratiques liées à une technologie
Conception de l’applicationTraquez les bad smells
Utilisation de Design Patterns
Outillage
●JDeodorant●Code Badsmell
Detector●CodePro Analytix
L’algorithmieExemple Parcours de LinkedList
LinkedList<Integer> notes = …int total =0;for (int i = 0 ; i < notes.size() ; ++i) { total += notes.get(i);}
L’algorithmie (suite)
public static String treatString(final String str) { final int length = str.length(); final List<Character> charList = new ArrayList<Character>(str.length()); for (int zIndex = -1; zIndex < length - 1; ++zIndex) { charList.add(str.charAt(zIndex + 1)); } final List<Character> charList2 = new LinkedList<Character>(); int z2Index = -2; final int value = 8; final int res = value % 3; while (z2Index < length - 2) { charList2.add(charList2.size(), charList.get(z2Index + res)); z2Index++; } final char[] array = new char[length]; for (int i = 0; i < length; ++i) { array[length - i - 1] = charList2.get(i); } return new String(array); }}
L’algorithmie (bad smells)
public static String treatString(final String str) { final int length = str.length(); final List<Character> charList = new ArrayList<Character>(str.length()); for (int zIndex = -1; zIndex < length - 1; ++zIndex) { charList.add(str.charAt(zIndex + 1)); } final List<Character> charList2 = new LinkedList<Character>(); int z2Index = -2; final int value = 8; final int res = value % 3; while (z2Index < length - 2) { charList2.add(charList2.size(), charList.get(z2Index + res)); z2Index++; } final char[] array = new char[length]; for (int i = 0; i < length; ++i) { array[length - i - 1] = charList2.get(i); } return new String(array); }}
CC=4
Nommage !
Performance!
MagicNumbers
Indice complexe
Faille de sécurité!
L’algorithmie (solution)
new StringBuilder(str).reverse();
Attention aux faux-positifs!Exemple Règles Hibernate
Equals/Hascode doivent être implémentés
Analyse syntaxique, sémantique, héritage des classes, fonctionnelle
(que vérifie le equals)...
La qualité des tests
Combien de tests unitaires pour ce code ?
public static String foo(int i) { if ( i >= 0 ) { return "foo"; } else { return "bar"; }}
Combien de tests unitaires pour ce code ?
public static String foo(int i) { if ( i >= 0 ) { return "foo"; } else { return "bar"; }}
@Testpublic void shouldReturnBarWhenGiven1() { assertEquals("bar", foo(1));}
@Testpublic void shouldReturnFooWhenGivenMinus1() { assertEquals("foo", foo(-1));}
Outillage PIT
Pouvez-vous me citer des métriques
intéressantes ?
Quelles métriques utiles ?
A lire : Métriques et critères d'évaluation de la qualité du code source d’un logiciel
Métrique Seuil conseillé
Nombre d’erreurs bloquantes /critiques 0
Taux de couverture de code 80%
Densité de commentaire 20-40%
Complexity Cyclomatique (Méthode) <= 10
Complexité NPath <= 5
Couverture (branches) 80%
Couvertures (% loc) 80%
Nombre de lignes de code / module Small (2K), Intermediate(8K), Medium(32K), Large(128K), Very Large (512K)
% API Publique documentée 100%
Couplage afférent/efférent 20
La notion de référentiel
En pratique, une release contient :
Comment construire son référentiel
▧Evaluer l’impact du défaut associé à la règle
BLOCKER : Conséquence visible à l’utilisateur ?CRITICAL : Conséquence invisible mais
comportement anormal vérifiéMAJOR : Conséquence invisible, comportement
anormal possible mais non déterministeCRITICAL : Impact sur la capacité à tester
(unitairement, intégration)MINOR, INFO : Pas d’anomalie de
comportement possible
Attention au paramétrage des règles
OUtils et process pour contrôler la qualité de
code
Un processus
de revue de code
Utilisez une convention de
codageDéfinissez des règles communes
Un portail de
qualimétrie
Intégration Sonar + Maven▧ <project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
...
</project>
▧mvn sonar:sonar -DsonarHostURL=...
Intégration Sonar + Gradle▧ apply plugin: "sonar"
▧ sonar {
server {
url = "http://my.server.com"
}
database {
url = "jdbc:mysql://my.server.com/sonar"
driverClassName = "com.mysql.jdbc.Driver"
username = "Fred Flintstone"
password = "very clever"
}
}
▧gradle sonarAnalyze
Pour aller plus loin :
Formation Cleancode / Développeurs
Formation Tests automatisés, TDD/BDD
Formation Audit de code