Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Vers l’industrialisation du logiciel

Introduction

L’industrialisation du logiciel répond à des problématiques de productivité et de qualité du logiciel produit. Sans industrialisation, il n’est pas possible de réaliser des applications d’envergure, impliquant des équipes de plus de deux personnes et dont les durées de réalisation sont prévues sur du long terme.

Ce chapitre traite de plusieurs aspects de l’industrialisation, notamment la gestion de sources, la production du livrable, les tests unitaires et la qualité du code.

Travail en équipe : intégration avec Git

NetBeans propose des intégrations avec les fournisseurs de gestion de sources les plus communs, dont fait partie Git.

Le système de gestion de sources tient un rôle central dans le développement d’applications. Ce gestionnaire permet le suivi des modifications et le partage des sources au sein d’une équipe.

Git est un produit de gestion de sources dit « distribué et concurrent ».

L’aspect distribué de Git permet à chacun d’avoir une gestion de sources locale, ce qui facilite le suivi des versions y compris sur le poste de développement.

L’aspect concurrent de Git permet de gérer les modifications concurrentes d’une même ressource, c’est-à-dire que deux développeurs peuvent modifier le même fichier au même moment. De plus un mécanisme de fusion est proposé pour réconcilier les modifications incompatibles.

1. Fonctionnement de Git

Comme évoqué en introduction, Git permet de travailler en équipe, et ce de manière parallèle ; de plus, il a cette caractéristique d’avoir des référentiels de sources distribués. Cela fait de Git ce qu’on appelle un DCVCS : Distributed Concurrent Version Control System, autrement dit un Système distribué et concurrent de contrôle des versions.

a. Git, un système distribué

L’aspect distribué de Git permet aux développeurs de travailler sur une version locale de la base de code, ce qui leur permet de n’être pas forcément en permanence connecté au référentiel central.

Le fonctionnement de Git est expliqué par la figure suivante :

images/05EI01.png

Aspect distribué de Git

Dans cette figure :

les développeurs « clonent » le repository central dans leur repository local (1) ; le repository local matérialise les fichiers en cours d’édition auprès du développeur (2). Les développeurs modifient les fichiers simultanément.

b. L’aspect concurrent de Git

La concurrence des modifications est possible avec Git, comme montré ci-après.

images/05EI02.png

Aspect concurrent de Git

Dans cette séquence, le fichier modifié par l’instruction...

Construction du projet : utilisation de Maven dans NetBeans

Comme abordé dès le chapitre Créer son premier projet avec NetBeans, s’appuie sur des standards de gestion de configuration pour pouvoir gérer la manière dont les projets sont organisés, en matière de structure, de compilation et de production du livrable.

1. Fonctionnement de Maven

Maven s’est imposé comme un standard polyvalent de gestion de la configuration de projet. Maven permet notamment de définir un standard de structuration de projet, de gestion des dépendances et de construction du projet.

a. Maven : la convention comme philosophie

L’utilisation de Maven peut être déroutante pour certains développeurs. En effet, Maven s’appuie sur des conventions de fonctionnement, définies à l’avance, pour automatiser une partie du travail des développeurs.

Maven s’attend à trouver une certaine organisation de projet, un certain nommage des répertoires. Si ces standards sont respectés, la compilation est alors d’une facilité imbattable. Hors de ce cadre, il faut rentrer dans un mode plus déclaratif et l’utilisation de Maven perd de son intérêt.

Toutes les personnalisations à réaliser seront définies dans le fichier de projet Maven, le pom.xml  déjà évoqué auparavant.

b. Structuration du projet

Maven impose ce que l’on appelle un Layout de projet, c’est-à-dire une organisation standard des dossiers constituant un projet.

Le layout par défaut pour le Java regroupe quatre emplacements standards :

src/main/java

L’emplacement principal où le développeur met toutes les sources java.

src/main/resources

L’emplacement où le développeur met toutes les ressources du programme qui ne sont pas censées être compilées, telles que les configurations par défaut, les images ou les ressources de traduction.

src/test/java

Ce répertoire contient tous les tests (unitaires, d’intégration) du projet. C’est une bonne pratique de séparer les tests du code principal, ce point sera abordé juste après.

src/test/resources

Comme pour les ressources principales, contient tout ce qui n’est...

Exécution des tests unitaires dans NetBeans

Les tests unitaires constituent un des fondements des méthodes de développement actuelles, s’intégrant très bien avec les méthodologies dites agiles.

Un test unitaire permet, comme son nom l’indique, de tester unitairement une fonctionnalité de l’application, indépendamment du contexte global dans lequel elle est normalement utilisée.

Les tests unitaires doivent être les plus automatiques possibles, car ils permettent de vérifier, à chaque construction du projet, qu’il n’y a pas eu de régression ou d’incompatibilité.

Avec Maven, d’ailleurs, il n’est par défaut pas possible de générer le binaire représentant l’artefact si un des tests unitaires est en échec.

1. Méthodologie de définition du test unitaire

Il est très important de suivre une méthodologie qui permet de rendre le test unitaire réellement unitaire et automatique.

Il est en effet possible d’utiliser des frameworks comme JUnit, qui sera abordé juste après, et de concevoir des tests qui sont vus comme unitaires, mais qui en réalité ne vérifient pas grand-chose ou ne sont pas rejouables plus d’une fois.

En Java, le test unitaire se matérialise par une méthode faisant partie d’une classe de test. Chaque méthode de test contient le scénario correspondant au cas d’utilisation à tester.

a. Approche systématique : hypothèse, action, vérification

Le contenu d’un test unitaire doit faire apparaître ces trois étapes : hypothèse, action et vérification.

L’hypothèse représente le contexte initial nécessaire à la réalisation de l’action. 

Il peut s’agir de la préparation d’un jeu de données adapté pour tester une partie précise de la fonctionnalité, ou de la préparation d’une ressource externe, telle que la connexion à une base de données ou la définition d’un fichier utile au service qui est en test.

L’action est l’appel à une fonction unique qui est considérée comme étant en test. Il doit absolument s’agir...

Analyse de la qualité de code intégrée à l’outil

La qualité du code est un enjeu majeur des projets de développement logiciel. Une mauvaise qualité du code peut avoir des retentissements immédiats sur la satisfaction de l’utilisateur final lors de l’utilisation du produit, et se traduit en général par un impact sur la rentabilité du projet.

Il est donc vital de veiller à la bonne qualité du code, et ce depuis le démarrage de la réalisation du projet.

Dans ce cadre, les outils de qualimétrie peuvent aider à surveiller le niveau de qualité du produit, et dans certains cas, comme avec NetBeans, proposer au développeur le conseil d’amélioration directement au moment de l’écriture du code.

1. Utilisation de l’analyseur de code intégré de NetBeans

NetBeans bénéficie d’un inspecteur de code intégré, ce qui permet au développeur la prise en compte de la qualimétrie dès les premières lignes de code.

Pour pouvoir activer cette inspection, il faut se placer sur le menu Source - Inspect.

Cela ouvre la fenêtre suivante :

images/05EI39.png

Sélection de la configuration d’inspection

Il y a deux types d’analyse : des analyses globales, représentées par le bouton radio Configuration, et des analyses sur des critères (bonnes pratiques) uniques, activables par un clic sur Single Inspection.

a. Analyse globale

Les analyses globales permettent de prendre en charge un ensemble de critères de qualité à vérifier. La valeur par défaut pour cette configuration est NetBeans Java Hints, et c’est un bon réglage pour commencer.

En cliquant sur Inspect, l’analyse démarre et le rapport apparaît dans la vue Inspector.

images/05EI40.png

Résultats des tests unitaires

En cliquant sur la ligne indiquée en warning, le développeur peut accéder au code et corriger l’infraction à la bonne pratique. Une aide succincte est également fournie pour pouvoir orienter la correction.

En l’occurrence, il manque de la Javadoc sur les membres positionnés à public.

Sur un projet plus large, comme ceux vus au chapitre précédent, le rapport est plus significatif.

b. Analyse sur critère unique...

Exercice corrigé : Conception d’un service de lecture de fichiers CSV en approche TDD

Ce court exercice permet de mettre en œuvre les principes d’industrialisation vus dans ce chapitre, notamment l’approche Test Driven Development abordée dans la partie relative à la qualité du logiciel.

1. Spécifications de l’exercice

Il faut développer une librairie chargée de lire les données d’un fichier CSV pour les désérialiser en liste d’instance de la classe Passenger.

a. Préparation du projet

Déclarer un projet Maven permettant de définir une librairie Java.

La compilation doit être configurée pour un niveau Java 11. Il faut ajouter l’outillage nécessaire pour réaliser les tests unitaires et évaluer la couverture de test.

b. Modélisation des données

Voici un extrait du fichier CSV en question :

Name                        ;PClass;Age ;Sex   ;Survived 
Allen, Miss E Walton        ;1st   ;29  ;female;1        
Allison, Miss Helen Loraine ;1st   ;2   ;female;0        
Allison, Mr Hudson Joshua   ;1st   ;30  ;male  ;0        
Allison, Mrs Hudson JC      ;1st   ;25  ;female;0       

Extrait des lignes contenues dans le fichier exemple

Il faut fournir une classe Passenger dont les attributs permettront de stocker les données présentes dans le fichier.

Redéfinir la méthode toString() qui permettra d’afficher une instance de Passenger de manière intelligible.

Pour des raisons de simplicité, le fichier peut être mis dans le projet, dans une zone appropriée pour les ressources considérées comme ressources de test.

c. Désérialisation grâce à la classe CSVReader

Définir une classe de service, nommée CSVReader, qui contiendra une fonctionnalité de lecture des données du fichier.

Le prototype de la méthode est le suivant :

List<Passenger> readAllPassengers(); 

La méthode doit conserver l’ordre dans lequel les données sont inscrites dans le fichier.

Il faut pouvoir imprimer la liste dans...