Retour d'expérience SAHI

Rédigé par gorki - - Aucun commentaire

Le problème :

Sahi, ça marche ou ça marche pas ?

Solution :

Bah euh.... difficile à dire.

Sahi c'est un peu comme Selenium, avec évidemment des différences listées ici.

L'utilisation : faire des tests de non-régression sur une IHM GWT.

La cible : Chrome sous Windows

 

Les plus (+) :

- le studio d'enregistrement marche bien

- il est possible d'ajouter des fonctions custom dans les scénarios.

- il est facile de l'intégrer avec Jenkins (en générant des rapports spéciaux)

 

Les moins (-) :

** sur les architectures testées, ça marche plus ou moins bien :

Jenkins + Chrome sous Linux en local :

(sans interface graphique, i.e. sans server X, i.e. headless, i.e avec XVFB) : ça marche mal : problème de stabilité / reproductibilité. Penser à exporter le server X sans XVFB pour débugger les problèmes Chrome Linux.

Jenkins+ Chrome sous Windows à distance :

pas parfait, mais mieux. Les problèmes ne viennent pas forcément de Sahi, mais des VM

Dans les deux cas : Chrome relancé entre chaque test (résultats pas constants) vs. Chrome utilisé en single session (mieux)

 

** la configuration de base marche mal :

  1. Si Chrome est arrêté entre chaque test, il est killé (cf os.properties) => le profile Chrome est alors corrompu
    • il vaut mieux remplacer dans le browser.xml le chemin vers Chrome par un shell à vous pour dézipper un profile clean avant de relancer.
    • du coup préparer votre profile et dézipper le avant chaque lancement de navigateur
  2. Pour bien être intégrer à Jenkins, mettre sous le gestionnaire de sources (dans des répertoires différents, ils n'évoluent pas au même rythme, pas la peine de vérifier les binaires sahi à chaque déploiement) :
    • userdata,
    • binaires sahi,
    • scripts
  3. Utiliser dans ces scripts les variables pour bien maitriser l'environnement :
    • $WORKSPACE de Jenkins
    • $SAHI_HOME
    • ...
  4. Les scripts de base dans userdata ne sont pas très robustes :
    • Pas de kill de Chrome / Arrêt de Sahi si on kill le build Jenkins
    • Il faut bien nettoyer les logs avant de démarrer SAHI
    • Pas d'attente de démarrage de SAHI
    • La sélection des process à killer est plus ou moins hasardeuse à mon avis, on est resté en singleThread

Et ce n'est qu'une vue rapide.

Conclusion :

Bref, des bonnes idées, mais ce n'est pas du "sur étagère", il y a du boulot pour qu'il soit intégré et robuste, sans parler de la rejouabilité des tests que je ne trouve pas exceptionnelle.

Mais bon quelle idée de contrôler un soft qui n'est pas fait pour être contrôlé (les navigateurs ne sont pas pensé pour ça !!)...

Entre Sahi et Selenium ? Celui que vous connaissez le mieux.

 

Quelques scripts :

Exemple de script de démarrage et attente du lancement de SAHI :

#!/bin/bash

./check.sh
if [ $? -eq 1 ] ; then
        echo "Environnement incorrect"
        exit 1
fi


echo --------
echo SAHI_HOME: $SAHI_HOME
echo SAHI_USERDATA_DIR: $SAHI_USERDATA_DIR_TMP
echo SAHI_EXT_CLASS_PATH: $SAHI_EXT_CLASS_PATH
echo --------

#rm -rf $SAHI_USERDATA_DIR/temp/*
#rm -rf $SAHI_USERDATA_DIR/logs/*
#rm -rf $SAHI_USERDATA_DIR/database/*

OUTPUT_LOG=$SAHI_USERDATA_DIR/logs/sahi_output.log

export POI_JARS=$SAHI_HOME/extlib/poi/excelpoi.jar:$SAHI_HOME/extlib/poi/poi-3.7-20101029.jar:$SAHI_HOME/extlib/poi/dom4j-1.6.1.jar:$SAHI_HOME/extlib/poi/poi-ooxml-3.7-20101029.jar:$SAHI_HOME/extlib/poi/poi-ooxml-schemas-3.7-20101029.jar:$SAHI_HOME/extlib/poi/xmlbeans-2.3.0.jar
SAHI_CLASS_PATH=$SAHI_HOME/lib/sahi.jar:$SAHI_HOME/extlib/rhino/js.jar:$SAHI_HOME/extlib/apc/commons-codec-1.3.jar:$SAHI_HOME/extlib/db/h2.jar:$SAHI_HOME/extlib/license/truelicense.jar:$SAHI_HOME/extlib/license/truexml.jar:$POI_JARS

cd $SAHI_HOME
java -Xmx512m -Djava.io.tmpdir=$SAHI_USERDATA_DIR/temp -classpath $SAHI_EXT_CLASS_PATH:$SAHI_CLASS_PATH net.sf.sahi.Proxy "$SAHI_HOME" "$SAHI_USERDATA_DIR" &> $OUTPUT_LOG &
echo $! > $SAHI_USERDATA_DIR/temp/sahi.pid

echo "Attente du demarrage de sahi"

i=0
STATUS_CODE=1
TIMEOUT=20
while [ $STATUS_CODE -eq 1 ] && [ $i -lt $TIMEOUT ]; do
        cat $OUTPUT_LOG | grep "Finished preparing report" > /dev/null
        STATUS_CODE=$?
        echo -n "."
        sleep 1
        ((i++))
done
echo "Serveur sahi OK"

Exemple de script de lancement de tests et kill de Chrome en fin de script (le userdata.properties est créé à la volé pour les paramètres tel que le port du proxy) :

#!/bin/bash

./check.sh
if [ $? -eq 1 ] ; then
        echo "Environnement incorrect"
        exit 1
fi
URL=$1
BUILD_ID=$2
DEBUG=$3

if [ ! $URL ] || [ ! $BUILD_ID ]
then
        echo "usage : start_and_run.sh <URL> <BUILD ID>"
        exit 1
fi

# Generation du fichier de configuration user
echo "############################################" > $SAHI_USERDATA_DIR/config/userdata.properties
echo "# Fichier généré automatiquement, ne pas modifier (cf start_and_run.sh" >> $SAHI_USERDATA_DIR/config/userdata.properties
echo "############################################" >> $SAHI_USERDATA_DIR/config/userdata.properties
cat $SAHI_USERDATA_DIR/config/userdata.properties.template  >> $SAHI_USERDATA_DIR/config/userdata.properties
printf "\n" >> $SAHI_USERDATA_DIR/config/userdata.properties
echo "proxy.port=$SAHI_PROXY_PORT" >> $SAHI_USERDATA_DIR/config/userdata.properties

# There is only one bypass list for both secure and insecure.
$SAHI_USERDATA_DIR/bin/start_sahi.sh

trap 'cat $SAHI_USERDATA_DIR/temp/sahi.pid | xargs kill' SIGINT SIGTERM EXIT

echo "Attente lancement de SAHI"
sleep 2

if [ "$DEBUG" = "DEBUG" ] ; then
        $SAHI_USERDATA_DIR/bin/testrunner.sh tests.suite $URL chromedebug $BUILD_ID
else
        $SAHI_USERDATA_DIR/bin/testrunner.sh tests.suite $URL chrome $BUILD_ID
fi

 

Jenkins et déploiement automatique

Rédigé par gorki - - Aucun commentaire

Le problème :

Déployer à partir de Jenkins, une application fraichement buildée sur des serveurs distants (avec des scripts en tout genre, mise à jour bdd, fichiers, autres)

Solution :

Il est possible de tout faire dans Jenkins à l'aide des plugins (Publish over SSH et SSH Credentials), mais c'est fastidieux et lent de tester/maintenir ses scripts ainsi.

Je préfère, et de loin, avoir mes scripts disponibles sous un shell pour les tester efficacement et pourquoi pas, les réutiliser ailleurs. Dans ce cas, le plugin de base pour exécuter un script suffit.

Quelques problèmes se sont posés, d'où quelques bonnes pratiques à avoir :

  1. utiliser des clés publiques / clés privées pour ne pas avoir à gérer les mots de passe dans Jenkins.
  2. séparer les jobs de builds des jobs deploy et les organiser avec MultiJob
  3. stocker les scripts sous votre SVN / Git (Jenkins permet de déployer une arborescence dans un sous-répertoire)
    • par exemple : url SVN des scripts => à extraire dans ./deploy
  4. dans la partie build : déterminer automatiquement la version et stocker là dans un fichier. Cela permet de pointer sur le trunk plus facilement
  5. dans la partie deploy :
    • retourner un code à Jenkins en fin de script pour indiquer si le build est OK ou KO
    • utiliser les variables d'environnements locales (Jenkins), distantes.
# tracer l’environnement local (script Jenkins) avec 
env > /path/to/env_jenkins.txt

# tracer l'environnement distant avec : 
ssh $SERVEUR_DIST << FIN
	env > ~/env_distant.txt
FIN

# passer les variables d'un environnement à l'autre (bash remplace les variable locales (Jenkins) au moment de transférer le script) :
ssh $SERVEUR_DIST << FIN
	echo $VARIABLE_JENKINS
	echo \$VARIABLE_DISTANT
FIN
  • comme tout bon script :
    • tester les arguments
    • mettez des logs
    • mettez des messages d'erreurs clairs
    • tester les codes retours de vos commandes : ça ne coute rien !
if [ $? -ne 0 ] ; then exit 1; fi

Merci capt'ain Obvious dirons-nous, mais au moins c'est écrit.
En effet toute cette artillerie peut avoir à fonctionner toutes les nuits, ça merdera forcément, autant que la panne soit facile à identifier.

 

 

Fil RSS des articles de cette catégorie