Vous gérez vos tests à l’aide de Xray, et vous avez des tests automatisés. Vous souhaitez que les résultats des tests automatisés remontent automatiquement dans Xray ? Vous êtes au bon endroit !
Avant de rentrer dans le vif du sujet, présentons rapidement l’outil Xray !
Xray est un plugin de test de Jira. Il permet de gérer la partie qualification d’un projet :
- Planification de campagnes de tests
- Création de cas de test avec possibilité de les lier à une User Story (exigence d’un produit)
- Exécution des tests
- Génération de rapports de tests
“Très bien ! Mais moi je veux suivre les résultats de mes tests automatisés via Xray !”, me direz-vous.
Eh bien, ça tombe bien ! Parce que c’est possible ! Et, cerise sur le gâteau, c’est justement l’objet de cet article !
A noter que Xray peut importer plusieurs types de format de résultats de tests. Ce tutoriel utilisera le framework TestNG. Si vous souhaitez utiliser un autre framework, la logique sera la même mais il faudra adapter les dépendances et la configuration du plugin maven-surefire en conséquence.
Ce tutoriel est un complément à la documentation technique de Xray (disponible ici)
Pré-requis
- Avoir un compte Jira avec le plugin Xray (logique mais je le précise quand même 😉)
- Avoir un compte git et savoir l’utiliser
- Avoir une instance Jenkins disponible et utilisable
- Avoir un test automatisé fonctionnel utilisant le framework TestNG et pouvant être exécuté par un système Linux (pour en savoir plus sur TestNG, c’est par ici)
- Gérer le développement des tests automatisés avec Maven (pour en savoir plus, c’est ici)
- Avoir le plugin maven-surefire présent dans le fichier pom.xml du projet de tests automatisés.
Pour information, l’IDE que j’utilise aujourd’hui pour créer ces tests automatisés est IntelliJ IDEA Community (disponible ici).
Nous pouvons maintenant attaquer les choses sérieuses !
Etapes de ce tutoriel
- Etape n°1 : Modifications du fichier pom.xml
- Etape n°2 : Modification du fichier testng.xml
- Etape n°3 : Ajout des annotations Xray dans les tests automatisés
- Etape n°4 : Configuration de Jenkins
- Etape n°5 : Configuration du fichier Jenkinsfile
- Etape n°6 : Lancement du job de Jenkins et vérification des résultats
Retrouvez toutes les étapes de ce tutoriel en vidéo et si vous préférez lire (et peut-être, avouez-le, utiliser la fonction copier-coller !), les étapes sont également détaillées ci-dessous !
Etape n°1 : Modifications du fichier pom.xml
Commençons par ouvrir le fichier “pom.xml” de notre projet :
<?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>exoauto</groupId>
<artifactId>webdriver_java</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins>
</build>
</project>
Afin de lui ajouter les dépendances nécessaires pour profiter de l’extension Xray de TestNG !
Qu’est ce que c’est que cette histoire “d’extension Xray” ?
C’est très simple, il s’agit de donner la possibilité à l’automaticien de test d’ajouter des annotations TestNG spécifiques à Xray. Cela permet de définir 3 types d’informations :
- requirement : permet d’associer le test automatisé à l’exigence (User Story) que l’on souhaite,
- test : permet d’associer le test automatisé à un test présent dans Xray,
- labels : permet d’associer une étiquette (label) au test.
Ainsi, lors de la remontée des résultats des tests dans Xray, les différentes associations seront effectuées automatiquement ! Elle est pas belle la vie ?
Petite précision, il n’est pas obligatoire de mettre les 3 paramètres. Par exemple, si vous ne souhaitez pas associer d’étiquette, vous n’êtes pas obligés d’utiliser l’attribut “labels”.
Voici notre “pom.xml” avec l’ajout des dépendances Xray-TestNG :
<?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>exoauto</groupId>
<artifactId>webdriver_java</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0</version>
<scope>test</scope>
</dependency>
<!--===========================AJOUT DEPENDANCE XRAY-TESTNG============================================================-->
<dependency>
<groupId>com.xpandit.xray</groupId>
<artifactId>xray-testng-extensions</artifactId>
<version>1.1.0</version>
<scope>test</scope>
</dependency>
<!--===================================================================================================================-->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins>
</build>
<!--===============================AJOUT REPOSITORY POUR XRAY=========================================-->
<repositories>
<repository>
<id>xpandit</id>
<name>xpand-releases</name>
<url>http://maven.xpand-it.com/artifactory/releases</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<!--=================================================================================================-->
</project>
A la fin de ce fichier “pom.xml”, on peut constater l’ajout d’un “repository”. En effet, le “repository” par défaut est le “maven repository”, or ici la dépendance “com.xpandit.xray” ne se trouve pas dans le “maven repository” mais à l’url “http://maven.xpand-it.com/artifactory/releases« .
Configuration du plugin maven-surefire
Il faut maintenant configurer le plugin maven-surefire pour :
- spécifier que l’on souhaite utiliser le fichier “testng.xml” (cf. https://testng.org/doc/documentation-main.html#testng-xml ) pour lancer le ou les tests,
- prendre en compte les “attributes”, c’est à dire les paramètres requirement, test et labels lors de la génération du rapport des résultats (le fichier testng-results.xml)
Ce qui nous donne ceci :
<?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>exoauto</groupId>
<artifactId>webdriver_java</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.xpandit.xray</groupId>
<artifactId>xray-testng-extensions</artifactId>
<version>1.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
<!--=============================== PARTIE AJOUTER DANS LA CONFIGURATION : =======================================================================================-->
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
<properties>
<property>
<name>reporter</name>
<value>org.testng.reporters.XMLReporter:generateTestResultAttributes=true,generateGroupsAttribute=true</value>
</property>
</properties>
<!--==============================================================================================================================================================-->
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>xpandit</id>
<name>xpand-releases</name>
<url>http://maven.xpand-it.com/artifactory/releases</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
</project>
Etape n°2 : Modification du fichier testng.xml
Lors du lancement des tests, il faut spécifier à TestNG que l’on souhaite utiliser et prendre en compte des annotations spécifiques (dans notre cas les annotations Xray). Il faut donc ajouter le “listener” de Xray qui se nomme “XrayListener” dans le fichier “testng.xml”.
Fichier “testng.xml” avec ajout de la partie “<listeners>” :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite thread-count="1" name="Surefire suite" verbose="0">
<listeners>
<listener class-name="com.xpandit.testng.annotations.XrayListener"></listener>
</listeners>
<test thread-count="1" name="Surefire test" verbose="0">
<classes>
<class name="com.projet.istqb.BaseTests"/>
<class name="com.projet.istqb.TestCpc"/>
</classes>
</test> <!-- Surefire test -->
</suite> <!-- Surefire suite -->
N.B : pour avoir une petite astuce de génération du fichier “testng.xml”, vous pourrez vous référer à la vidéo tuto que nous allons partager sur ce sujet 😉
Etape n°3 : Ajout des annotations Xray dans les tests automatisés
Maintenant, ouvrons le code source de notre test automatisé TestNG, qui pour le moment ne contient que des annotations classiques de ce framework…
package com.projet.istqb;
import org.testng.annotations.Test;
import pages.AnswPage;
import pages.IstqbPage;
import pages.MailboxPage;
import pages.ToolboxPage;
import static org.testng.Assert.assertEquals;
/* Classe TestCpc :
* Navigateur cible : Google Chrome.
* Cette classe représente le test "Cent pout Cent" qui consiste à vérifier que le mail reçu, de la part de
* "contact@hightest.nc", contient bien la phrase : "Vous avez bien répondu à 20 question(s) sur 20, soit 100 %
* de réussite. Félicitations, vous avez obtenu le score maximal !". Cette phrase est écrite uniquement en cas de
* résussite à 100 %.
*/
public class TestCpc extends BaseTests{
private String expResult = "Vous avez bien répondu à 20 question(s) sur 20, soit 100 % de réussite. Félicitations, vous avez obtenu le score maximal !";
private String email = "neoanderson@yopmail.com";
/* Méthode testSucessfulCpc :
* Cette méthode permet d'exécuter le cas de test avec le scénario suivant :
* Etape 1 - Cliquer sur "Toolbox"
* Etape 2 - Cliquer sur le lien vers le quiz ISTQB Fondation en français
* Etape 3 - Cliquer sur les bonnes réponses du test
* Etape 4 - Cliquer sur le bouton "Terminer!"
* Etape 6 - Entrer une adresse e-mail yopmail.com (ne pas cocher la case pour la newsletter)
* Etape 7 - Cliquer sur "OK"
* Etape 8 - Ouvrir la page "www.yopmail.com"
* Etape 9 - Vérifier que le mail reçu de la part de "contact@hightest.nc" indique bien la phrase attendue :
* "Vous avez bien répondu à 20 question(s) sur 20, soit 100 % de réussite. Félicitations, vous avez obtenu
* le score maximal !".
*/
@Test
public void testSucessfulCpc(){
ToolboxPage toolboxPage = homePage.clickToolboxLink();
IstqbPage istqbPage = toolboxPage.clickLinkByHref();
AnswPage answPage = istqbPage.clickRadio();
MailboxPage mailboxPage = answPage.emailResult(email);
String result = mailboxPage.getResult();
assertEquals(result,expResult);
}
}
… et ajoutons maintenant l’annotation Xray avec les informations que l’on souhaite :
// ne pas oublier d'ajouter tout en haut de la page :
// import com.xpandit.testng.annotations.Xray;
@Test
@Xray(requirement = "HTUTO-34", test="HTUTO-35")
public void testSucessfulCpc(){
ToolboxPage toolboxPage = homePage.clickToolboxLink();
IstqbPage istqbPage = toolboxPage.clickLinkByHref();
AnswPage answPage = istqbPage.clickRadio();
MailboxPage mailboxPage = answPage.emailResult(email);
String result = mailboxPage.getResult();
assertEquals(result,expResult);
}
}
Ici le test automatisé sera associé à l’exigence dont la clé (identifiant dans Xray) = HTUTO-34 et au test dont la clé = HTUTO-35. Attention : le test présent dans Xray avec la clé HTUTO-35 est un test de type “Generic” car on souhaite identifier ce test comme un test automatisé.
Bien ! Notre test est prêt à être exécuté ! Alors faisons-le avec la commande suivante :
mvn surefire:test
Un rapport est généré dans le dossier “surefire-report” et devrait se nommer “testng-results.xml”.
Ouvrez ce fichier, vous devriez voir à l’intérieur un nœud nommé “attributes”. Si ce n’est pas le cas, c’est qu’il y a une erreur de configuration quelque part ! Faites bien attention aux versions des dépendances que vous utilisez (par exemple, la version TestNG 7.1.0 n’a pas fonctionné avec mon projet) !
Exemple de fichier “testng-results.xml” :
Une fois que vous avez vérifié que votre fichier “testng-results.xml” est correctement généré, vous pouvez passer à la configuration de Jenkins pour l’intégration continue des résultats des tests dans Xray.
Etape n°4 : Configuration de Jenkins
Connectez-vous sur votre instance Jenkins, cliquez sur “Administrer Jenkins” puis sur “Gestion des plugins”.
Cliquez sur l’onglet “Disponibles” et recherchez “Xray”. Vous devriez avoir parmi vos résultats le plugin “Xray – Test Management for Jira Plugin”. Installez-le et redémarrez Jenkins !
Cliquez sur “Administrer Jenkins” puis sur “Configurer le système” ; vous devriez voir maintenant une partie intitulée “Xray Configuration”.
Comment remplir “Xray Configuration” ?
Il faut d’abord demander à votre administrateur Jira préféré la génération d’une clé API. Si vous êtes l’administrateur, bravo, vous pouvez générer la clé API sans rien demander à personne 🙂 !
La génération d’une clé devrait vous fournir les paramètres suivants : Client ID et Client Secret.
Ces 2 paramètres sont à enregistrer dans la partie “Credentials”. Il suffit de cliquer sur “ajouter” et d’insérer la donnée Client ID dans le champ “Username” (Nom utilisateur, pas “ID”) et Client Secret dans le champ “Password”.
Vous devriez obtenir une “Configuration ID” qui sera à insérer dans le script du pipeline (cf. fichier “Jenkinsfile” présenté un peu plus loin).
Exemple de configuration :
Créez un job de type pipeline avec le nom que vous souhaitez (si le type “pipeline” n’est pas disponible parmi vos items, c’est qu’il manque un ou plusieurs plugins dans votre instance Jenkins !).
Comment configurer mon pipeline ?
Voici un exemple de configuration du pipeline :
Partie “Général” :
La case “Supprimer les anciens builds” est cochée : cela permet de demander à Jenkins de conserver un nombre limité de builds (à configurer à l’aide du champ “Nombre maximum de builds à conserver”).
Partie “Build Triggers” :
La case “Construire périodiquement” est cochée : cela permet d’exécuter le script du pipeline à une fréquence déterminée (vous pouvez cliquer sur le point d’interrogation de “Planning” pour en savoir plus).
Partie “Pipeline” :
Dans le champ “Repository URL” : insérez l’URL de votre dépôt git.
Dans le champ “Credentials” : cliquez sur “Ajouter” puis enregistrer le login et le mot de passe de votre utilisateur git.
Dans le champ “Branch Specifier” : insérer la branche où se trouve votre “Jenkinsfile” (master par défaut).
Dans le champ “Script Path” : insérer le chemin où se trouve le script du pipeline (nommé “Jenkinsfile”) dans votre répertoire git (en général on met le “Jenkinsfile” à la racine du projet)
Il ne reste plus qu’à cliquer sur “Apply” puis “Sauver” !
Voilà, votre job Jenkins est prêt pour l’action !
Mais… il ne manque pas quelque chose ? (Là, c’est le moment où on voit si vous avez suivi !)
Effectivement, nous avons spécifié à Jenkins où se trouve le script du pipeline mais nous ne l’avons pas encore créé !
Alors allons-y !
Etape n°5 : Configuration du fichier Jenkinsfile
Par défaut, le script de configuration du pipeline se nomme “Jenkinsfile”. Ce script va servir à exécuter un test automatisé puis envoyer les résultats à Xray.
Script Pipeline : Jenkinsfile
pipeline {
agent any
tools {
// Installation Maven selon le nom donné dans la configuration globale de Jenkins
maven "Maven"
}
stages {
stage('Pre Build'){
steps{
sh "chmod +x driver/chromedriver"
}
}
stage('Build') {
steps {
// Exécuter Maven (version pour un système Unix)
sh "mvn -Dmaven.test.failure.ignore=true clean"
sh "mvn install"
}
stage('Import results to Xray') {
steps {
step([$class: 'XrayImportBuilder', endpointName: '/testng', importFilePath: 'target/surefire-reports/testng-results.xml', importToSameExecution: 'true', projectKey: 'HTUTO', serverInstance: 'fd45sd-dq7856-dsdd5656ytz'])
}
}
}
}
}
Description de la partie “stages” :
- “Pre Build” : sert à permettre l’exécution de “chromedriver” (version linux)
- “Build” : sert à effacer les résultats des tests précédents, compiler et exécuter le test automatisé, ici « TestCpc »
- “Import results to Xray” : sert à envoyer les résultats à Xray.
Etape n°6 : Lancement du job de Jenkins et vérification des résultats
Enfin ! Nous allons pouvoir constater le fruit de notre labeur 🙂 !
Il y a deux façons de faire : soit vous attendez que Jenkins lance un build automatiquement (puisque nous avons configuré un lancement périodique à l’étape n° 3), soit vous lancez le job manuellement en cliquant sur “lancer un Build”.
Une fois le Build lancé, cliquez sur “Console Output” du build en cours et vérifier qu’il n’y a pas eu d’échec d’exécution.
Ensuite, allez sur votre projet Xray pour vérifier que le résultat du test automatisé a bien été importé.
Exemple d’un résultat de test automatisé dans Xray :
Voilà ! Vous savez maintenant intégrer les résultats de vos tests automatisés de manière continue dans un projet Xray !
J’espère que ce tutoriel vous aura été utile 🙂 !
~ Jérôme Liron, ingénieur test applicatif chez Hightest