Chapitre en accès libre
Installer Maven et vérifier la chaîne complète
18 min de travail — lecture et pratique
Ce que vous allez obtenir
À la fin de ce chapitre, trois choses seront vraies sur votre poste :
- La commande
mvn -vrépond, et elle affiche votre JDK 11. - Un projet Maven existe sur votre disque, avec un
pom.xmlque vous comprenez ligne par ligne. - La commande
mvn testse termine parBUILD SUCCESS.
C’est la chaîne d’outils que vous utiliserez pendant tout le parcours. Chaque projet Selenium des modules suivants repartira exactement de ce squelette. Si cette étape est propre, vous n’y reviendrez plus. Si elle est bancale, elle vous coûtera du temps à chaque module.
Prérequis. Un JDK 11 installé et java -version qui répond (chapitre précédent). Si ce
n’est pas le cas, arrêtez-vous ici : Maven ne sert à rien sans JDK. Et plusieurs des pannes
listées plus bas dans ce chapitre sont en réalité des pannes de JDK, pas de Maven.
Durée. Comptez une vingtaine de minutes, dont plusieurs minutes d’attente pendant le premier build. Ce n’est pas du temps perdu : la section sur le dépôt local explique ce qui se passe pendant cette attente.
Pourquoi Maven, avant de l’installer
Vous savez déjà compiler un fichier Java avec javac et l’exécuter avec java. Tant que vous
avez un fichier, ça marche. Le problème arrive dès que le projet grossit.
Un test Selenium a besoin de la bibliothèque Selenium. Selenium a besoin d’autres
bibliothèques. Chacune a une version. Sans outil, vous téléchargez les fichiers .jar un par
un, vous les rangez quelque part, et vous écrivez une longue ligne de commande pour les passer
en -classpath. Puis un collègue récupère votre projet et ne peut pas le lancer, parce que
ses .jar ne sont pas au même endroit.
Maven prend en charge trois choses, et ce sont celles qui nous intéressent ici :
| Ce que Maven fait | Concrètement |
|---|---|
| Gestion des dépendances | Vous écrivez quelques lignes de XML nommant une bibliothèque et sa version. Maven la télécharge, et télécharge aussi tout ce dont elle dépend. |
| Structure de projet standard | Le code va dans src/main/java, les tests dans src/test/java. Toujours, sur n’importe quel projet Maven. |
| Cycle de vie de build | mvn test veut dire : résoudre les dépendances, compiler le code, compiler les tests, exécuter les tests. Toujours dans cet ordre, toujours la même commande. |
C’est aussi ce qui permet à une machine d’intégration continue de lancer vos tests sans que
vous soyez devant : ce dont le build a besoin est décrit dans le pom.xml, pas dans la
configuration de votre poste. Cela ne garantit pas qu’un build qui passe chez vous passera
ailleurs — la version du JDK, le système d’exploitation ou l’accès réseau peuvent différer —
mais cela supprime une cause d’écart majeure : les bibliothèques rangées à la main. C’est pour
ça qu’on travaille avec mvn test dès maintenant, et pas seulement avec le bouton « Run » de
VS Code.
Installer Maven
Maven se distribue sous forme d’archive à décompresser. Il n’y a pas d’installateur, pas d’assistant, rien à cocher. Vous décompressez un dossier et vous indiquez à votre système où le trouver. C’est déroutant la première fois, et c’est tout.
Rendez-vous sur la page de téléchargement officielle : https://maven.apache.org/download.cgi
et prenez le Binary zip archive (Windows) ou le Binary tar.gz archive (macOS, Linux)
de la dernière version 3.9.x. Les exemples ci-dessous utilisent 3.9.9 : remplacez par le
numéro que vous avez effectivement téléchargé.
Ne prenez pas le « Source » : c’est le code source de Maven lui-même, il faudrait le compiler. Vous voulez le « Binary ».
Windows
Décompressez l’archive dans un dossier sans espace ni accent dans le chemin. Les espaces
dans les chemins sont une source classique d’échecs silencieux avec les scripts .cmd.
Utilisez par exemple :
C:\outils\apache-maven-3.9.9
Vous devez obtenir un dossier C:\outils\apache-maven-3.9.9\bin contenant un fichier
mvn.cmd. Si votre chemin ressemble à C:\outils\apache-maven-3.9.9\apache-maven-3.9.9\bin,
vous avez un dossier de trop : remontez d’un niveau.
Ensuite, ajoutez ce bin au PATH :
- Touche Windows, tapez
variables d environnement, ouvrez Modifier les variables d’environnement système. - Bouton Variables d’environnement….
- Dans Variables utilisateur, sélectionnez
Path, puis Modifier…. - Nouveau, et collez :
C:\outils\apache-maven-3.9.9\bin - OK, OK, OK.
Point critique, et c’est la première chose à vérifier quand ça ne marche pas : une fenêtre de terminal déjà ouverte ne voit pas les nouvelles variables d’environnement. Fermez complètement votre terminal (et VS Code) et rouvrez-en un neuf. Sinon vous testerez pendant dix minutes une configuration qui est déjà correcte.
Si vous préférez un gestionnaire de paquets et que vous avez les droits nécessaires :
winget install Apache.Maven
Le paquet ajoute normalement Maven au PATH. Ouvrez un terminal neuf, lancez mvn -v, et si la
commande n’est pas reconnue, repérez le dossier d’installation et ajoutez son bin au PATH à
la main, comme ci-dessus.
macOS
Avec Homebrew, si vous l’avez déjà :
brew install maven
Homebrew place mvn dans le PATH tout seul. Vous pouvez passer directement à la
vérification.
Sans Homebrew, en manuel. Attention : sous macOS, le dossier de téléchargement s’appelle
Downloads sur le disque, même si le Finder l’affiche en français.
cd ~/Downloads
tar xzvf apache-maven-3.9.9-bin.tar.gz
sudo mv apache-maven-3.9.9 /usr/local/apache-maven
echo 'export PATH=/usr/local/apache-maven/bin:$PATH' >> ~/.zshrc
source ~/.zshrc
Attention aux guillemets dans la ligne echo : ce sont des apostrophes simples droites.
Avec des guillemets doubles, $PATH serait remplacé par sa valeur au moment de l’écriture,
et votre .zshrc figerait un PATH obsolète.
Si votre shell est bash et non zsh (macOS antérieur à Catalina, ou configuration
personnelle), remplacez ~/.zshrc par ~/.bash_profile. Pour savoir lequel vous utilisez :
echo $SHELL
Linux
Selon votre bureau et votre langue, le dossier de téléchargement s’appelle Downloads ou
Téléchargements. Vérifiez avec ls ~ avant de lancer la première ligne.
cd ~/Downloads
tar xzvf apache-maven-3.9.9-bin.tar.gz
sudo mv apache-maven-3.9.9 /opt/apache-maven
echo 'export PATH=/opt/apache-maven/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
Pourquoi pas sudo apt install maven ? Deux raisons. D’abord, la version packagée par
votre distribution est généralement plus ancienne que celle publiée par Apache. Ensuite, le
paquet maven tire un JDK ou un JRE en dépendance ; selon ce qui est déjà installé, cela peut
changer le java par défaut du système et vous faire quitter le JDK 11 sans que vous l’ayez
demandé. C’est une panne pénible à diagnostiquer. L’archive manuelle ne touche à rien d’autre.
Le cas M2_HOME
Beaucoup de tutoriels vous demandent de définir une variable M2_HOME. Ce n’est plus
nécessaire. Les scripts de lancement de Maven 3.9 ne lisent plus du tout M2_HOME : ils
déterminent leur propre répertoire d’installation et renseignent MAVEN_HOME eux-mêmes.
C’était une obligation de Maven 2, et l’habitude a survécu.
Une variable M2_HOME qui traîne n’empêchera donc pas mvn de démarrer. En revanche, des
outils tiers plus anciens la lisent encore — scripts d’intégration, anciennes configurations
d’IDE — et si elle pointe vers une installation que vous avez supprimée, ces outils-là
échoueront avec un message parlant d’un répertoire introuvable. Pour voir ce que vous avez :
# macOS / Linux
echo $M2_HOME
echo $MAVEN_HOME
REM Windows (invite de commandes)
echo %M2_HOME%
echo %MAVEN_HOME%
Si ça n’affiche rien (ou %M2_HOME% tel quel sous Windows), il n’y a rien à faire. Si ça
affiche un chemin vers un dossier qui n’existe plus, supprimez la variable.
Ce qui compte, c’est le PATH. Pas M2_HOME.
Critère de réussite n° 1 : mvn -v
Ouvrez un terminal neuf et lancez :
mvn -v
Vous devez voir cinq lignes de cette forme :
Apache Maven 3.9.9 (<un long identifiant de commit>)
Maven home: C:\outils\apache-maven-3.9.9
Java version: 11.0.22, vendor: Eclipse Adoptium, runtime: C:\Program Files\Eclipse Adoptium\jdk-11.0.22.7-hotspot
Default locale: fr_FR, platform encoding: UTF-8
OS name: "windows", version: "10.0", arch: "amd64", family: "windows"
Les chemins, les numéros et l’encodage affiché seront différents chez vous : platform encoding vaut souvent Cp1252 sous Windows et UTF-8 sous macOS et Linux, et ce n’est pas
un problème à ce stade. Deux éléments seulement sont à vérifier, et ils sont non négociables :
- La première ligne commence par
Apache Maven 3. - La troisième ligne dit
Java version: 11.
Cette troisième ligne est la vraie information de ce chapitre. Maven vous dit avec quel JDK il va compiler, qui n’est pas forcément celui que vous croyez avoir installé.
Quand ça rate
mvn : commande introuvable / 'mvn' n'est pas reconnu en tant que commande interne ou externe
Le PATH n’est pas pris en compte. Dans l’ordre :
- Avez-vous ouvert un terminal neuf depuis la modification du PATH ? Commencez par là : fermez tout, y compris VS Code, et rouvrez.
- Le chemin que vous avez ajouté existe-t-il vraiment, avec un
mvn.cmd(oumvn) dedans ?
winget install Apache.Maven0
# macOS / Linux
ls /opt/apache-maven/bin
- Vérifiez ce que votre système voit :
REM Windows
where mvn
# macOS / Linux
which mvn
The JAVA_HOME environment variable is not defined correctly
Maven a démarré, mais il ne trouve pas de JDK. Vérifiez la valeur :
# macOS / Linux
echo $JAVA_HOME
REM Windows
echo %JAVA_HOME%
Le chemin affiché doit être la racine du JDK, pas son dossier bin. Il doit contenir un
sous-dossier bin et un sous-dossier lib. Une erreur classique est de pointer
...\jdk-11\bin au lieu de ...\jdk-11.
mvn -v répond, mais affiche Java version: 17. (ou 8, ou 21)
C’est le piège le plus coûteux de ce chapitre, parce que tout semble fonctionner. Votre
machine a plusieurs JDK et Maven prend le mauvais. Il faut forcer JAVA_HOME sur le JDK 11.
# macOS
export JAVA_HOME=$(/usr/libexec/java_home -v 11)
# Linux : lister les JDK installés, puis choisir
ls /usr/lib/jvm
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
Le nom exact du dossier varie selon la distribution et le fournisseur du JDK : reprenez celui
que ls affiche chez vous.
Sous Windows, reprenez Variables d’environnement et corrigez JAVA_HOME pour qu’il
pointe sur le dossier de votre JDK 11.
Ces export ne valent que pour le terminal courant : ajoutez la ligne à votre ~/.zshrc ou
~/.bashrc pour la rendre permanente, puis source le fichier.
Relancez mvn -v jusqu’à voir Java version: 11.. Ne passez pas à la suite avant.
Le dépôt local .m2, et pourquoi le premier build est long
Avant de créer le projet, comprenez ce qui va se passer, sinon la prochaine étape ressemblera à un plantage.
Quand Maven a besoin d’une bibliothèque, il regarde d’abord dans un dossier sur votre disque
appelé le dépôt local. S’il ne l’y trouve pas, il la télécharge depuis le dépôt
central (repo.maven.apache.org) et l’enregistre dans le dépôt local. La fois
suivante, il ne téléchargera plus rien.
Le dépôt local se trouve ici :
| Système | Emplacement |
|---|---|
| Windows | C:\Users\<votre-nom>\.m2\repository |
| macOS | /Users/<votre-nom>/.m2/repository |
| Linux | /home/<votre-nom>/.m2/repository |
Le dossier .m2 commence par un point. Sous macOS et Linux, cette convention le rend masqué :
Cmd + Maj + . affiche les fichiers cachés dans le Finder, et ls -a les liste dans un
terminal. Sous Windows, il est visible dans l’explorateur ; le plus rapide reste de taper
%USERPROFILE%\.m2 dans la barre d’adresse.
Conséquences pratiques, et elles vont vous servir tout le parcours :
- Le premier build est long — plusieurs minutes, avec de nombreuses lignes
Downloading from central:. Maven ne télécharge pas seulement JUnit : il télécharge aussi ses propres greffons de compilation, d’exécution de tests, de nettoyage. Ce n’est pas un blocage, c’est le fonctionnement normal. Laissez tourner. - Les builds suivants sont rapides — quelques secondes, sans aucun téléchargement.
- Si vous voyez encore des téléchargements au troisième build, quelque chose ne va pas :
soit le réseau coupe en cours de route et laisse des fichiers incomplets, soit vous avez
une dépendance en version
SNAPSHOTque Maven revérifie à chaque fois. - Un dépôt local corrompu (réseau coupé pendant un téléchargement) produit des erreurs
incompréhensibles du type
Could not resolve dependenciesalors que le réseau fonctionne. Le remède : supprimer le sous-dossier fautif de.m2/repositoryet relancer. En dernier recours, supprimer.m2/repositoryen entier — vous ne perdez rien d’autre que du temps de retéléchargement.
Le proxy d’entreprise
Cette section ne concerne que les postes derrière un réseau d’entreprise. Si vous travaillez depuis chez vous, sautez-la — mais lisez le premier paragraphe : le jour où vous serez en mission, vous saurez où chercher.
Reconnaître le symptôme
Derrière un proxy non configuré, Maven ne dit pas « proxy ». Il ne dit rien pendant très longtemps, puis il affiche une erreur de connexion. Elle a cette forme (le libellé final peut être traduit dans la langue de votre système) :
[ERROR] Failed to execute goal on project qa-socle: Could not resolve dependencies...
Could not transfer artifact org.junit.jupiter:junit-jupiter:pom:5.10.2
from/to central (https://repo.maven.apache.org/maven2):
Connect to 10.255.255.1:8080 [/10.255.255.1] failed: Connection timed out
Trois signatures à reconnaître, toutes les trois de nature réseau :
| Ce que vous lisez | Ce que ça veut dire |
|---|---|
Connection timed out après une longue attente |
Le trafic sortant est filtré. Il faut un proxy. |
Connection refused immédiatement |
Rien n’écoute à l’adresse indiquée : l’hôte ou le port du proxy est faux. |
PKIX path building failed: unable to find valid certification path |
Le proxy déchiffre le HTTPS et présente son propre certificat, que votre JDK ne connaît pas. |
Configurer le proxy : settings.xml
Maven lit sa configuration personnelle dans un fichier settings.xml placé dans le dossier
.m2, à côté de repository. Ce fichier n’existe pas par défaut : vous le créez.
- Windows :
C:\Users\<votre-nom>\.m2\settings.xml - macOS / Linux :
~/.m2/settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<proxies>
<proxy>
<id>proxy-entreprise</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.mon-entreprise.local</host>
<port>8080</port>
<username>mon-identifiant</username>
<password>mon-mot-de-passe</password>
<nonProxyHosts>localhost|127.0.0.1|*.mon-entreprise.local</nonProxyHosts>
</proxy>
</proxies>
</settings>
Quatre pièges à connaître :
<protocol>http</protocol>même pour du HTTPS. Ce champ décrit le protocole pour joindre le proxy, pas celui de la ressource demandée. Un proxy d’entreprise classique s’atteint en HTTP. Mettrehttpsici est une erreur fréquente.- Le mot de passe est en clair dans le fichier. C’est un vrai problème. Si votre mot de
passe de proxy est votre mot de passe de session Windows, ne l’écrivez pas ici : demandez
à votre IT s’il existe un compte de service ou un proxy sans authentification pour les
outils de développement. Maven sait aussi chiffrer ce mot de passe
(
mvn --encrypt-password, qui suppose d’avoir créé au préalable un mot de passe maître avecmvn --encrypt-master-password) ; cela protège d’une lecture accidentelle, pas d’un vol de fichier. <nonProxyHosts>est séparé par des barres verticales|, pas par des virgules.- Un caractère spécial dans le mot de passe (
&,<,>) casse le XML.&s’écrit&,<s’écrit<,>s’écrit>.
Si vous ne connaissez ni l’hôte ni le port de votre proxy, vous pouvez souvent les lire dans les paramètres réseau de votre navigateur d’entreprise, ou dans le fichier de configuration automatique que votre poste utilise.
Le certificat interne (erreur PKIX)
Si vous obtenez PKIX path building failed, le proxy réécrit le trafic HTTPS. Il faut
ajouter son certificat racine au magasin de confiance de votre JDK 11. Il vous faut deux
choses que vous n’avez pas forcément : le fichier de certificat, distribué par votre service
informatique, et les droits d’écriture dans le répertoire du JDK.
Une fois le fichier en main, la commande est celle-ci — terminal administrateur sous Windows,
sudo sous macOS et Linux :
brew install maven0
-cacerts désigne le magasin de confiance du JDK courant (option disponible à partir du
JDK 9). changeit est le mot de passe par défaut de ce magasin ; s’il a été modifié sur
votre poste, votre IT vous donnera le bon. Vérifiez ensuite que l’alias est bien présent :
keytool -list -cacerts -storepass changeit -alias proxy-entreprise
Dites-le clairement à votre IT : « J’ai besoin que repo.maven.apache.org soit
joignable depuis mon poste, et du certificat racine du proxy pour l’ajouter au truststore de
mon JDK. »
Si vous n’avez pas les droits
Soyez lucide : sans autorisation réseau, ce chapitre est bloqué, et aucun texte ne le débloquera. Ce n’est ni votre faute ni un défaut de la formation. Trois issues :
- Ouvrir un ticket auprès de votre IT en demandant précisément l’accès à
repo.maven.apache.org(et les coordonnées du proxy). Formulez la demande dans ces termes-là : c’est un besoin standard pour un poste de développement Java. - Demander si l’entreprise dispose déjà d’un miroir interne (Nexus, Artifactory). Si
oui, votre IT vous donnera une URL à mettre dans un bloc
<mirror>desettings.xml, et tout fonctionnera sans toucher au proxy. - Faire ce parcours sur un poste personnel, si vous en avez un. Vous évitez d’emblée toute la catégorie de pannes décrite dans cette section.
Créer le projet
Pourquoi pas l’archétype
Maven sait générer un projet tout fait avec une commande. Nous n’allons pas l’utiliser comme point de départ, et voici pourquoi — ce n’est pas une question de goût.
L’archétype maven-archetype-quickstart en version 1.4 produit un pom.xml qui contient
ceci :
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
et cette dépendance :
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
C’est-à-dire : Java 7 et JUnit 4. Nous travaillons en Java 11 et JUnit 5. Il faudrait donc générer le projet, puis corriger plusieurs endroits du fichier — en sachant lesquels. Écrire le fichier soi-même est plus court, et surtout vous saurez ce que fait chaque ligne, ce qui vous servira à chaque fois qu’un build échouera.
L’archétype ajoute aussi une dépendance au réseau supplémentaire : il faut le télécharger avant de pouvoir générer quoi que ce soit. Derrière un proxy, c’est un point de panne de plus, et un point de panne qui survient avant même que vous ayez un projet à déboguer.
Pour information, la commande existe et vous la croiserez :
mvn archetype:generate -DgroupId=fr.stratest.qa -DartifactId=demo -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false. Sans-DinteractiveMode=false, elle vous pose une série de questions dans le terminal et vous propose une très longue liste d’archétypes. Ne la lancez pas maintenant.
L’arborescence
Créez la structure suivante. Le nom qa-socle est celui que nous reprendrons dans les
chapitres suivants.
qa-socle
├── pom.xml
└── src
├── main
│ └── java
│ └── fr
│ └── stratest
│ └── qa
│ └── Environnement.java
└── test
└── java
└── fr
└── stratest
└── qa
└── ChaineOutilsTest.java
Deux règles à respecter dans cette arborescence :
- Le nom du fichier doit être exactement celui de la classe publique qu’il contient,
extension
.javacomprise.Environnement.javapourclass Environnement. C’est une erreur de compilation franche si vous vous trompez, et elle est facile à lire :class Environnement is public, should be declared in a file named Environnement.java. - L’imbrication
fr/stratest/qadoit correspondre à la lignepackage fr.stratest.qa;en tête des fichiers. Attention ici : si le dossier ne correspond pas, Maven compile quand même sans rien dire et range la classe d’après la déclarationpackage. Vous ne verrez donc pas d’erreur tout de suite — seulement VS Code qui souligne le fichier, et un projet que personne ne retrouve. Respectez la convention dès le départ.
En une commande :
# macOS / Linux
mkdir -p ~/projets/qa-socle/src/main/java/fr/stratest/qa
mkdir -p ~/projets/qa-socle/src/test/java/fr/stratest/qa
cd ~/projets/qa-socle
REM Windows (invite de commandes)
mkdir %USERPROFILE%\projets\qa-socle\src\main\java\fr\stratest\qa
mkdir %USERPROFILE%\projets\qa-socle\src\test\java\fr\stratest\qa
cd /d %USERPROFILE%\projets\qa-socle
Ouvrez ensuite ce dossier dans VS Code : Fichier > Ouvrir le dossier…, et sélectionnez
qa-socle. Important : ouvrez le dossier qa-socle lui-même, pas son parent, sinon
l’extension Java de VS Code ne reconnaîtra pas le projet.
Le pom.xml
À la racine de qa-socle, créez pom.xml avec exactement ce contenu :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.stratest.qa</groupId>
<artifactId>qa-socle</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
</plugin>
</plugins>
</build>
</project>
Ligne par ligne, ce qui compte :
| Élément | Rôle |
|---|---|
modelVersion |
Toujours 4.0.0. C’est la version du format du fichier, pas de votre projet. |
groupId |
Votre « espace de noms », par convention un nom de domaine à l’envers. |
artifactId |
Le nom du projet. Il donne son nom au fichier .jar produit. |
version |
SNAPSHOT signifie « en cours de développement, non figée ». |
project.build.sourceEncoding |
Sans cette ligne, Maven utilise l’encodage de la machine et vous obtenez un avertissement ; surtout, vos accents deviennent illisibles sur une autre machine. |
maven.compiler.source / target |
Compiler en Java 11. C’est ce qui relie ce fichier à l’exigence du parcours. |
junit-jupiter |
JUnit 5. L’artefact junit-jupiter est un agrégat : il tire l’API, le moteur d’exécution et les tests paramétrés en une seule déclaration. |
<scope>test</scope> |
Cette bibliothèque n’est disponible que dans src/test/java, et n’est pas embarquée dans le livrable. |
maven-compiler-plugin |
Fixé en 3.13.0. |
maven-surefire-plugin |
C’est lui qui exécute les tests. Fixé en 3.2.5, compatible avec JUnit 5.10. |
Pourquoi fixer explicitement la version des deux greffons ? Parce que sans cette
indication, la version employée est celle que votre version de Maven associe par défaut à la
phase. Elle n’est pas la même partout : Maven 3.6.3 utilise maven-compiler-plugin 3.1 et
maven-surefire-plugin 2.12.4, tandis que Maven 3.9.9 utilise 3.13.0 et 3.2.5. Le même
pom.xml ne se comporterait donc pas de la même façon chez vous et sur le serveur — et avec
Surefire 2.12.4, vos tests JUnit 5 ne seraient tout simplement pas exécutés. Fixer les
versions rend le build reproductible.
Ce pom.xml est votre point de départ pour tout le parcours. Dans les chapitres Selenium,
vous y ajouterez une dépendance, et une seule.
Les deux fichiers Java
src/main/java/fr/stratest/qa/Environnement.java :
package fr.stratest.qa;
public class Environnement {
public static String versionJava() {
return System.getProperty("java.specification.version");
}
public static void main(String[] args) {
System.out.println("JDK detecte : " + versionJava());
}
}
src/test/java/fr/stratest/qa/ChaineOutilsTest.java :
package fr.stratest.qa;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class ChaineOutilsTest {
@Test
void mavenCompileEtExecuteUnTest() {
assertEquals(4, 2 + 2);
}
@Test
void leBuildTourneSurUnJdk11OuSuperieur() {
String version = Environnement.versionJava();
System.out.println(">>> JDK utilise par le build : " + version);
int majeur = Integer.parseInt(version.split("\\.")[0]);
assertTrue(majeur >= 11, "JDK trop ancien : " + version);
}
}
Un mot sur la ligne version.split("\\.")[0]. Depuis Java 9, la propriété
java.specification.version vaut 11, 17, 21 — un simple nombre. Mais sur un JDK 8 elle
vaut 1.8, et un Integer.parseInt("1.8") lèverait une NumberFormatException : le test
partirait en erreur au lieu d’afficher le message que nous avons écrit. En découpant sur le
point, 1.8 devient 1, la comparaison 1 >= 11 est fausse, et vous lisez
JDK trop ancien : 1.8. Un test doit échouer proprement, surtout celui qui sert à
diagnostiquer votre installation.
Ces deux tests ne testent rien d’intéressant, et c’est volontaire. Le premier prouve que la
chaîne compile et exécute du code de test. Le second prouve que la classe de src/main/java
est bien visible depuis src/test/java, et affiche le JDK réellement utilisé par le build.
Notez qu’il n’y a aucun accent dans les chaînes de caractères. C’est délibéré pour ce chapitre : tant que l’encodage du terminal n’est pas vérifié, un accent mal affiché vous ferait croire à une panne qui n’existe pas.
Critère de réussite n° 2 : mvn test
Depuis le dossier qa-socle — celui qui contient pom.xml — lancez :
cd ~/Downloads
tar xzvf apache-maven-3.9.9-bin.tar.gz
sudo mv apache-maven-3.9.9 /usr/local/apache-maven
echo 'export PATH=/usr/local/apache-maven/bin:$PATH' >> ~/.zshrc
source ~/.zshrc0
Le premier lancement prend plusieurs minutes et affiche de nombreuses lignes
Downloading from central:. C’est le remplissage du dépôt local décrit plus haut. Ne
l’interrompez pas : une interruption laisse des fichiers incomplets qu’il faudra nettoyer.
À la fin, vous devez voir ceci — les durées varieront, le reste non :
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running fr.stratest.qa.ChaineOutilsTest
>>> JDK utilise par le build : 11
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.042 s -- in fr.stratest.qa.ChaineOutilsTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Les quatre points à vérifier :
>>> JDK utilise par le build : 11Tests run: 2— et pasTests run: 0Failures: 0, Errors: 0BUILD SUCCESS
Si ces quatre lignes sont là, votre chaîne d’outils est en place. C’est l’objectif du chapitre, et il est atteint.
Quand ça rate
| Message | Cause | Ce que vous faites |
|---|---|---|
The goal you specified requires a project to execute but there is no POM in this directory |
Vous n’êtes pas dans le bon dossier. | ls (ou dir) et vérifiez que pom.xml est là. Sinon, cd vers qa-socle. |
Non-parseable POM ... expected START_TAG |
XML mal formé : une balise non fermée, ou des guillemets typographiques collés depuis un traitement de texte. | Recopiez le pom.xml depuis ce chapitre. Les guillemets doivent être des " droits. |
Tests run: 0 et BUILD SUCCESS |
Surefire n’a pas trouvé vos tests. | Trois causes : le fichier ne finit pas par Test.java ; il n’est pas sous src/test/java ; la version de maven-surefire-plugin est antérieure à 2.22, la première à savoir exécuter JUnit 5 — ce qui arrive si vous avez omis le bloc <plugin> et que votre Maven associe par défaut la 2.12.4. |
package org.junit.jupiter.api does not exist |
La dépendance n’est pas résolue, ou l’import est mauvais. | Vérifiez le bloc <dependencies>, puis relancez avec mvn -U test pour forcer la revérification. |
Could not transfer artifact ... Connection timed out |
Réseau ou proxy. | Reprenez la section sur le proxy d’entreprise. |
Fatal error compiling: invalid target release: 11 |
Maven compile avec un JDK antérieur à 11. | mvn -v et corrigez JAVA_HOME. |
warning: unmappable character for encoding |
Encodage. | Vérifiez la présence de project.build.sourceEncoding et enregistrez vos fichiers en UTF-8 dans VS Code (indicateur en bas à droite de la fenêtre). |
WARNING: system modules path not set in conjunction with -source 11 |
Vous compilez avec un JDK plus récent que 11. | Avertissement sans conséquence ici, mais c’est le signe que vous n’êtes pas sur le JDK 11 demandé. Corrigez JAVA_HOME. |
Deux commandes de diagnostic à connaître :
mvn -X test
Mode débogage : très verbeux, mais il affiche le settings.xml lu, le dépôt local utilisé et
chaque URL contactée. C’est l’outil pour comprendre un problème de réseau.
mvn -o test
Mode hors ligne : Maven n’utilise que le dépôt local. Si cette commande réussit alors que
mvn test échoue, votre problème est un problème de réseau, pas un problème de projet.
Vérifier ce qui a été produit
Un dossier target est apparu à côté de pom.xml. Il contient :
target/classes— vos classes compilées desrc/main/javatarget/test-classes— vos classes de test compiléestarget/surefire-reports— les rapports d’exécution, en.txtet en.xml
Ce dossier est entièrement reconstructible : il ne se sauvegarde pas et ne se versionne jamais. Pour le supprimer :
mvn clean
Et pour tout refaire de zéro, la commande que vous taperez le plus souvent du parcours :
mvn clean test
Récapitulatif : votre poste est-il prêt ?
Cochez les six points. Tous, pas cinq sur six.
- [ ]
java -versionaffiche une version 11 - [ ]
mvn -vafficheApache Maven 3. - [ ] La ligne
Java version:demvn -vaffiche11. - [ ] Le dossier
.m2/repositoryexiste et n’est pas vide - [ ]
mvn testse termine parBUILD SUCCESS - [ ] La sortie affiche
Tests run: 2, Failures: 0, Errors: 0
Si un seul point manque, traitez-le maintenant. Les chapitres suivants supposent ces six points acquis, et une panne d’environnement qui remonte trois modules plus loin est beaucoup plus difficile à diagnostiquer, parce qu’elle se déguise en erreur Selenium.
Ce que ce chapitre ne couvre pas
Pour que ce soit dit, plutôt que découvert à la mauvaise heure :
- Les autres phases du cycle de vie Maven.
package,install,deploy,sitene sont pas abordées. Vous n’en avez pas besoin pour exécuter des tests. - La portée des dépendances au-delà de
test(compile,provided,runtime), et la résolution des conflits de versions transitives. Vues au module Maven/TestNG. - La propriété
maven.compiler.release, qui remplace le couplesource/targetdepuis le JDK 9 et vérifie en plus que vous n’utilisez pas d’API trop récente. Nous restons sursource/target, plus répandu dans les projets existants que vous rencontrerez. - Le fichier
testng.xmlet les suites TestNG. Ce chapitre installe JUnit 5. TestNG arrivera plus tard, et cohabitera avec JUnit dans le mêmepom.xml. - Les dépendances Selenium. Elles ne sont pas encore dans ce
pom.xml: c’est l’objet du premier chapitre Selenium. Rien à ajouter pour l’instant. - Le Maven Wrapper (
mvnw), qui permet de figer la version de Maven par projet. - Les dépôts privés d’entreprise (Nexus, Artifactory) au-delà de la mention faite plus haut, et la publication d’artefacts.
- Git et le
.gitignore. Le dossiertargetne doit pas être versionné, mais le versionnement est traité dans son propre module.
Ce qu’il faut retenir
Trois idées, et elles vous serviront bien après ce chapitre :
mvn -v vous dit quel JDK Maven utilise. Pas quel JDK vous avez installé : celui qu’il
utilise. Quand un build se comporte de façon inexplicable, c’est la première commande à
lancer.
Le dépôt local .m2 explique la lenteur du premier build et la rapidité des suivants.
Quand une résolution de dépendance échoue sans raison apparente, supprimer le sous-dossier
concerné est souvent le remède le plus rapide.
Un pom.xml écrit à la main est un pom.xml que vous savez réparer. Vous venez d’en
écrire un dont vous connaissez chaque balise, et dont les versions de greffons sont fixées —
donc dont le comportement ne dépend pas de la version de Maven installée sur la machine.
Au chapitre suivant, vous ajouterez une dépendance à ce pom.xml et vous écrirez le code qui
ouvre un navigateur tout seul.