Bonjour,
Aujourd’hui on va parler d’intégration continue avec Symfony2, Composer et Jenkins.
Après plusieurs jours de galère à chercher de la doc sur comment mettre en place des tests automatisé sur symfony2 avec jenkins, j’ai finalement réussi à faire ce que je voulais. Tout d’abord, plusieurs problèmatiques se posent. Pour les tests unitaires pas besoin de grand chose, on test juste une classe, une fonction ou une méthode. Pour les tests fonctionnels c’est différent. Il faut un environnement, une base de donnée et potentiellement un jeu de donnée.
Passons donc aux choses sérieuses.
Symfony permet de créer différents environnements, typiquement dev
et prod
. Les besoins ne sont pas les mêmes, en dev on a besoin de debug, de sandbox, etc. En prod on a besoin de cache, etc. On va donc commencer par mettre en place en environnement pour les test et faire en sorte qu’il soit le plus petit et le plus indépendant possible.
À la création d’un projet Symfony 2, l’environnement de test est déjà créé, il nous reste à le customiser.
# app/config_test.yml
doctrine:
dbal:
driver: pdo_sqlite
path: %kernel.root_dir%/var/test.db
user: root
On va donc dire à symfony qu’on veut utiliser sqlite comme base de donnée car les jeux de données sont petit et qu’on a pas besoin de performance. J’ai choisi de stocker la base dans un fichier, mais il est très bien possible de la stocker en mémoire en remplaçant l’option path
par memory: true
.
Ensuite pour exécuter sa suite de tests, il faut un bootstrap
pour initialiser une requête d’un test fonctionnel. La le problème c’est que le bootstrap.php.cache
de symfony de base va seulement faire un autoload des vendors et initialiser le kernel. Avec un environnement de test il faut monter une base donnée, créer les tables et charger les fixtures. Il est possible de dire à phpunit d’utiliser un fichier de bootstrap spécifique qui va faire les choses à notre place.
<!-- app/phpunit.xml.dist -->
<phpunit
bootstrap = "tests.bootstrap.php" >
Dans ce fichier on indique à phpunit d’utiliser un fichier spécifique pour exécuter nos tâches de bootstrap.
<?php
// app/tests.bootstrap.php
if (isset($_ENV['BOOTSTRAP_DB_ENV'])) {
passthru(sprintf(
'rm "%s/var/test.db"',
__DIR__
));
passthru(sprintf(
'php "%s/console" doctrine:schema:update --force --env=%s',
__DIR__,
$_ENV['BOOTSTRAP_DB_ENV']
));
passthru(sprintf(
'php "%s/console" doctrine:fixtures:load --append --env=%s',
__DIR__,
$_ENV['BOOTSTRAP_DB_ENV']
));
}
require __DIR__.'/bootstrap.php.cache';
Dans ce fichier on liste les tâches à exécuter si la variable d’environement BOOTSTRAP_DB_ENV
est définie. Là on indique qu’on veut supprimer la base de test existante, créer le schéma et charger les fixtures.
Ensuite pour définir cette variable d’environnement, il faut rajouter ceci dans son fichier phpunit.xml.dist
<!-- app/phpunit.xml.dist -->
<php>
<env name="BOOTSTRAP_DB_ENV" value="test"/>
</php>
Cette modification va permettre de créer une fase de donnée et de charger les fixtures, nécessaires à l’exécution de la suite de tests.
Désormais, lors de l’exécution de bin/vendor/phpunit
la base de données de test sera supprimée, créée et les fixtures seront chargées avant d’exécuter les tests.
Ensuite il faut dire à Jenkins de récupérér composer et d’installer les vendors avant de lancer phpunit.
<!-- build.xml -->
<target name="composer" depends="clean" description="Download composer and install project dependancies">
<exec executable="wget" failonerror="true">
<arg value="-nc" />
<arg value="http://getcomposer.org/composer.phar" />
</exec>
<exec executable="php">
<arg value="composer.phar" />
<arg value="config" />
<arg value="--global" />
<arg value="github-oauth.github.com" />
<arg value="github_oauth-key" />
</exec>
<exec executable="php" failonerror="true">
<arg value="composer.phar" />
<arg value="install" />
<arg value="--dev" />
<arg value="--prefer-dist" />
<arg value="--no-progress" />
<arg value="--no-interaction" />
<arg value="--no-scripts" />
</exec>
</target>
<target name="phpunit" description="Execute tests">
<exec executable="${basedir}/vendor/bin/phpunit" failonerror="true">
<arg value="-c" />
<arg path="${basedir}/app" />
</exec>
</target>
Le paramètre github-oauth.github.com
sert a passer sa clé oauth à composer pour éviter les problèmes de fair-use avec l’api github.
Cette tâche ant va donc dire jenkins de télécharger composer, de configurer la clé oauth github et ensuite de lancer l’installation des vendors en utilisant --prefer-dist
qui permet de récupérer en priorité les archives plutôt qu’un git clone. L’exécution des scripts est la aussi inutiles car tout les scripts nécessaires sont lancés par le bootstrap de test.
La deuxième tâche sert a lancer phpunit avec le fichier de config situé dans app/
.
En configurant Jenkins au post-receive git, l’exécution des tests sera faite à chaque git push. Pour finir il suffit d’activer les rapports nécessaires jenkins pour avoir des statistiques sur son dashboard projet.
J’espère que ça vous sera utile. Bonne journée.
Si vous trouvez une typo, n'hésitez pas à forker et éditer cet article. Merci beaucoup !
“Intégration continue avec Symfony 2, Composer et Jenkins” de Florent Viel est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale 4.0 International.