SoapUI : scripting et automatisation de test

Présentation du problème

SoapUI est un outil très utile dans la SOA. Il permet d’appeler des services et de contrôler les réponses.
Il est aussi possible de lancer certains projets SoapUI en ligne de commande.
Cela peut s’avérer utile dans des contextes d’intégration continue ou pour monitorer des plateformes.
Cet article donnera un exemple d’utilisation dans un cadre de monitoring, mais il est possible de reprendre et d’adapter les principes pour d’autres contextes.

 

Architecture plateforme

Pour ce projet d’exemple, l’architecture des plateformes OSB/SOA Oracle est la suivante :

schéma d'architecture plateforme
schéma d’architecture plateforme
  • En amont, 2 load-balancers F5 distincts pour les flux OSB (projets de bus) et SOA (projets BPEL)
  • Derrière les F5, 2 serveurs dédiés Oracle, avec des ports distincts pour les flux OSB et SOA
  • Pour finir, ces serveurs partageront 2 clusters distincts pour les flux OSB et SOA

Cette architecture est reproduite à l’identique sur tous les environnements du projet :

  • Développement: identifié par la lettre ‘f’
  • Recette: identifié par la lettre ‘r’
  • Préproduction: identifié par la lettre ‘h’
  • Production: identifié par la lettre ‘p’

 

Projet SoapUI

Dans SoapUI, on crée un projet qui va tester les 2 types de flux OSB et SOA.

Référencement des flux

Le but étant de vérifier l’état des plateformes, il est important d’utiliser des flux de lecture de données, très simples et peut gourmands en ressources. Ici, ce seront des transcodifications.
On charge donc ces flux dans SoapUI et on replace le nom du serveur et le numéro de port par des variables. Ces variables seront surchargées dans le script batch selon le composant à monitorer (load-balancer, serveur oracle ou cluster).

initialisation des variables
initialisation des variables

On teste les appels aux services (en n’oubliant pas de définir les valeurs du nom du serveur et du port) :

import SOAP UI flux OSB
import SOAP UI flux OSB
import SOAP UI flux SOA
import SOAP UI flux SOA

On remarque qu’à chaque fois, le résultat contient une valeur et aucune erreur.

 

Suite de test

Maintenant que l’on a 2 flux de test valides, on crée une suite de tests dans SoapUI dans laquelle des vérifications automatiques seront faites.
Les vérifications sont les mêmes pour OSB et SOA, à savoir :

  • Validité de la réponse SOAP
  • Validation du schéma
  • Pas d’exception ou erreur remontée
  • Vérification du code retour OK
exemple de contrôle SOA
exemple de contrôle SOA

 

Lancement en ligne de commande

Pour ceux utilisant la version gratuite de SoapUI, il va probablement falloir écrire le script de lancement à la main. Ce script pourra ensuite être automatisé via un outil dédié (cron, planificateur de tâches, …).
En effet, certains plugins SoapUI ne sont compatibles qu’avec la version Pro du produit (par exemple, le plugin Jenkins).

Rédaction

Pour pouvoir lancer les contrôles automatiquement, on passe par un script. Ici du batch Windows, mais du Shell Linux pourrait aussi le faire.
Ce script :

  • Prend en entrée l’environnement (‘f’ pour développement, ‘r’ pour recette, …)
  • Exécute les 2 flux de test OSB/SOA sur chaque composant d’infrastructure : load-balancer, serveur Oracle et cluster
  • Ecrit les résultats de test dans des répertoires dédiés, classés par environnement et composant d’infrastructure
script batch
script batch

Voici un exemple de squelette en langage batch Windows :
@echo off
:: CONSTANTES
set REP_SOAPUI=C:\travail\portables_apps\SoapUI
set REP_SORTIE=%~dp0\..\sortie\ControleInfra
set SCRIPT_SOAPUI=%~dp0\ControleInfra-soapui-project.xml
set PORT_CLUSTER_OSB=8011
set PORT_CLUSTER_SOA=8001
set PORT_ORACLE_HTTP_OSB=9010
set PORT_ORACLE_HTTP_SOA=9000
:: VARIABLES DE CONTEXTE
if %1 == F_ (
set NOM_LOAD_BALANCEUR_OSB=f__osb___
set NOM_LOAD_BALANCEUR_SOA=f__soa___
set NOM_CLUSTER_1=f__soa__
set NOM_CLUSTER_2=f__soa__
) else if %1 == ... (
set NOM_LOAD_BALANCEUR_OSB=...
set NOM_LOAD_BALANCEUR_SOA=...
set NOM_CLUSTER_1=...
set NOM_CLUSTER_2=...
)
:: EXECUTION DU SCRIPT
:: serveur OSB port OSB serveur SOA port SOA dossier de sortie
call :appelWS %NOM_LOAD_BALANCEUR_OSB% %PORT_CLUSTER_OSB% %NOM_LOAD_BALANCEUR_SOA% %PORT_CLUSTER_SOA% %1\LoadBalancer
call :appelWS %NOM_CLUSTER_1% %PORT_ORACLE_HTTP_OSB% %NOM_CLUSTER_1% %PORT_ORACLE_HTTP_SOA% %1\OracleHTTP1
call :appelWS %NOM_CLUSTER_2% %PORT_ORACLE_HTTP_OSB% %NOM_CLUSTER_2% %PORT_ORACLE_HTTP_SOA% %1\OracleHTTP2
call :appelWS %NOM_CLUSTER_1% %PORT_CLUSTER_OSB% %NOM_CLUSTER_1% %PORT_CLUSTER_SOA% %1\cluster1
call :appelWS %NOM_CLUSTER_2% %PORT_CLUSTER_OSB% %NOM_CLUSTER_2% %PORT_CLUSTER_SOA% %1\cluster2
goto:eof
:: FONCTION GENERAL APPEL WS
:appelWS
del /F /S /Q %REP_SORTIE%\%5
mkdir %REP_SORTIE%\%5
call %REP_SOAPUI%\bin\testrunner.bat -A -M -sTestSuite -PnomServeurOSB=%1 -PnumeroPortOSB=%2 -PnomServeurSOA=%3 -PnumeroPortSOA=%4 -f%REP_SORTIE%\%5 %SCRIPT_SOAPUI%
goto:eof

Les différentes parties du script sont logiques par rapport à notre besoin :

  • CONSTANTES : définition des répertoires de travail, du script SoapUI (étape ci-dessus) et des ports
  • VARIABLES DE CONTEXTE : définition des noms de serveur en fonction de l’environnement passé en entrée
  • EXECUTION DU SCRIPT : exécution des tests OSB/SOA sur chaque composant d’infrastructure.
    Pour chaque composant, on fait un appel à …
  • FONCTION GENERALE APPEL WS : exécution d’un test OSB/SOA sur un composant particulier.
    C’est ici qu’est appelé le script « testrunner », fourni par SoapUI et permettant de lancer un projet en ligne de commandes

 

Exécution

On peut maintenant lancer le script en spécifiant un environnement :

exécution script développement
exécution script développement

 

Résultats

En allant dans le répertoire de sortie, on voit la structure suivante :

répertoires de sortie
répertoires de sortie
  • un dossier par environnement (‘f’ pour développement, ‘r’ pour recette, …)
  • pour chaque environnement, un dossier par composant d’infrastructure : load-balancer, serveur Oracle et cluster
  • pour chaque composant, un fichier de rapport global est créé : test_case_run_log_report.xml
    rapport global OK
    rapport global OK

     

Ce rapport comprend une ligne par type de flux SOA/OSB et on y retrouve (entre autres) le status du test. Un echec aurait montré status=FAILURE.

  • Pour chaque flux SOA/OSB, le détail du test SoapUI.

    rapport détaillé OSB OK
    rapport détaillé OSB OK

On peut y voir :

  • Le statut OK
  • L’absence de message, donc l’absence d’erreur
  • La requête SoapUI
  • La réponse de la plateforme

 

En cas d’échec sur un flux, nous aurions eu des messages dans :

  • le rapport global

    rapport global FAIL
    rapport global FAIL
  • le rapport détaillé

    rapport détaillé OSB FAIL
    rapport détaillé OSB FAIL

 

Concaténation des résultats

Par défaut, Soap-UI éclate ses résultats dans différents fichiers et sous-dossiers. De plus, ces fichiers sont parfois verbeux.
Pour simplifier la compréhension et l’analyse, on pourrait ne garder que les données utiles et les rassembler dans un seul fichier.
Soap-UI permet, dans une suite de test, de créer un script Groovy qui sera exécuté après les tests (TearDown).

Script Soap-UI version gratuite

La version gratuite de Soap-UI permet de créer des scripts. Toutefois, certaines notions, comme celle d’environnement, n’existent pas dans cette version. Cette limitation peut être un problème pour une exploitation fine des résultats.

Création de script Groovy (version libre)
Création de script Groovy (version libre)

Un code d’exemple permettant d’avoir tous les statuts (OK/FAIL) et messages d’erreur :
// Try-catch block to handle exceptions
try {
// 1. Create a Report.csv file inside the CSV Reports folder
// Retrieve the project root folder
def projectPath = new com.eviware.soapui.support.GroovyUtils(context).projectPath
// Create a File object for Report csv file
String reportFilePath = projectPath + "/../sortie/report.log";
def reportFile = new File(reportFilePath);
// Check for existence of report file and create a file
if(!reportFile.exists())
{
reportFile.createNewFile();
}
/* ------------------------------------------------------------------------------- */
// 2. Inserting data in the file
// Iterate over all the test steps results
for(stepResult in testRunner.getResults())
{
// Trime all messages
def trimedMessages = "";
for(resMessage in stepResult.getMessages())
{
trimedMessages = trimedMessages + resMessage.replaceAll("\r|\n" , "NEW_LINE") + "NEW_MESSAGE";
}
// Write all the necessary information in the file
reportFile.append('dateTime : ' + new Date(stepResult.getTimestamp()).toString());
// Environment notion is not implemented in free SoapUI edition :(
//reportFile.append('\nenvironment : ' + runner.testSuite.project.activeEnvironment.name);
reportFile.append('\ntestSuite : ' + testRunner.testCase.testSuite.name);
reportFile.append('\ntestCase : ' + testRunner.testCase.name);
reportFile.append('\nstatus : ' + stepResult.getStatus());
reportFile.append('\nmessages : ' + trimedMessages);
reportFile.append('\nEOL\n');
}
}
catch(exc)
{
log.error("Exception happened: " + exc.toString());
}

 

Script Soap-UI version Pro

Cette version permet d’ajouter la notion d’environnement. L’interface est presque identique :

Création de script Groovy (version Pro)
Création de script Groovy (version Pro)

Le code doit être un peu revu pour rajouter l’environnement (et parce que les objets ne sont pas exactement les mêmes que ceux de la version libre) :
...
// 2. Inserting data in the file
// Iterate over all the test suite results
for(testRunner in runner.getResults())
{
// Iterate over all the test steps results
for(stepResult in testRunner.getResults())
{
// Trime all messages
def trimedMessages = "";
for(resMessage in stepResult.getMessages())
{
trimedMessages = trimedMessages + resMessage.replaceAll("\r|\n" , "NEW_LINE") + "NEW_MESSAGE";
}
// Write all the necessary information in the file
reportFile.append('dateTime : ' + new Date(stepResult.getTimestamp()).toString());
reportFile.append('\nenvironment : ' + runner.testSuite.project.activeEnvironment.name);
reportFile.append('\ntestSuite : ' + testRunner.testCase.testSuite.name);
reportFile.append('\ntestCase : ' + testRunner.testCase.name);
reportFile.append('\nstatus : ' + stepResult.getStatus());
reportFile.append('\nmessages : ' + trimedMessages);
reportFile.append('\nEOL\n');
}
}
...

 

Analyse du fichier de sortie

Une fois les test suites exécutées, le fichier de sortie est alors alimenté :

Fichier de sortie
Fichier de sortie

La structure étant :

  • Date d’exécution du test
  • L’environnement : développement, intégration, production, …
  • Test suite et test case
  • Status : OK ou FAIL
  • Messages d’erreur (selon le contexte)
  • Un marqueur de fin de ligne « logique » (EOL).
    Peut être utile pour du parsing en vue, par exemple, d’une d’intégration ELK.

 

Automatisation avec Jenkins

Jenkins propose un plugin officiel pour lancer un script Soap-UI Pro (la version gratuite est bloquée).
Le nom de ce plugin est : SoapUI Pro Functional Testing
Il s’installe facilement avec la gestionnaire de plugins :

plugin Jenkins
plugin Jenkins

Attention : Il peut y avoir une erreur SSL bloquant le téléchargement du plugin. Le contournement est expliqué ici : Skip Certificate Check plugin. Une erreur SSL continuera d’apparaitre, mais le téléchargement aura bien lieu :).
On peut alors créer un nouveau projet :

nouveau projet Jenkins
nouveau projet Jenkins

Dans lequel se trouve deux options :

  • Planifier des éxécution
  • Lancer une test suite sur un environnement spécifique avec Soap-UI pro
Configuration du projet Jenkins
Configuration du projet Jenkins

 

Pour aller plus loin

Ce genre de script peut-être adapté pour différents contextes :

  • Test de performance
  • Tests unitaires ou d’intégration en continue
  • Intégration des logs dans ElasticSearch (probablement le sujet d’un prochain article)

Les tests seront alors lancés automatiquement et consultables en ligne :

Builds Jenkins
Builds Jenkins

 

Références

Functional Tests | Test Automation : documentation SoapUI sur l’automatisation de tests
ClassNotFoundException after updating to SoapUI 5.2.0 : Résolution d’une erreur Java lors de l’exécution de SoapUI en ligne de commande
Mocks SOAPUI mutualisés : tu pousses le bouchon un peu trop loin… : les bouchons, une autre fonctionnalité de SoapUI
SoapUI Pro Functional Testing : plugin Jenkins pour Soap-UI Pro
Working with Scripts : écriture de scripts groovy avec Soap-UI