Tests drupal avec behat
Problématique
Ecrire et jouer rapidement des tests fonctionnels d’un site sous drupal
Solution : Behat avec l’extension pour Drupal. https://drupal.org/project/drupalextension
Installation de l’extensions pour durpal
L’installation est très simple en utilisant composer, il suffit d’écrire le fichier composer.json suivant dans un répertoire de travail
{
"require": {
"drupal/drupal-extension": "*"
},
"config": {
"bin-dir": "bin/"
}
}
et voilà, il ne reste qu’à lancer la commande :
composer install
Cela aura pour effet d’installer l’extension drupal et les dépendances (behat inclus)
Initialisation et configuration
La première chose à faire est l’initialisation de l’environnement de travail de behat. La commande suivante permet génère l’arborescence minimal et les fichiers nécessaires à behat
./bin/behat --init
l’étape suivante est la configuration de behat avec le fichier behat.yml.
default:
filters:
tags: "@drush"
paths:
features: 'features'
extensions:
Behat\MinkExtension\Extension:
goutte: ~
selenium2: ~
base_url: http://localhost:8888
Drupal\DrupalExtension\Extension:
blackbox: ~
drush:
#alias: /home/cbrun/Apps/drush/drush/drush
root: /data/services/web/demo/cms/drupal/quick-drupal-20140214100728/drupal
region_map:
left sidebar: "#sidebar-first"
Avec :
- filters : permet de filtrer les tests ayant pour tags “@drush”
- base_url : url du site à tester
- drush : paramétrage à la commande drush
- root : répertoire du site drupal à tester
- region_map : permet de définir le mapping entre les régions et les identifiants css
Enfin, avant d’écrire des scénario, il reste à modifier le fichier bootstrap. Il faut éditer le fichier feature/bootstrap/FeatureContext.php, pour qu’il ressemble à ça
<?php
/**
* @file
* boostrap
*/
use Behat\Behat\Context\ClosuredContextInterface,
Behat\Behat\Context\TranslatedContextInterface,
Behat\Behat\Context\BehatContext,
Behat\Behat\Context\Step\Then,
Behat\Behat\Context\Step\Given,
Behat\Behat\Context\Step\When,
Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;
use Drupal\DrupalExtension\Context\DrupalContext;
//
// Require 3rd-party libraries here:
//
require_once 'PHPUnit/Autoload.php';
require_once 'PHPUnit/Framework/Assert/Functions.php';
/**
* Features context.
*/
class FeatureContext extends DrupalContext {
/**
* Initializes context. * Every scenario gets its own context object.
*
* @param array $parameters
* context parameters (set them up through behat.yml)
*/
public function __construct(array $parameters) {
// Initialize your context here.
}
/**
* @Given /^wait (\d+)$/
*/
public function wait($arg1) {
$this->getSession()->wait($arg1);
}
}
Et voilà, on est prêt à écrire des tests pour drupal. Le contexte Drupal qui est utilisé dans notre fichier bootstrap va nous permettre d’écrire dans nos scénarios des commandes drupal, drush pour tester nos sites
Pour avoir la liste des commandes utilisables pour écrire nos scénarios, il suffit de demander à behat ce qu’il peut interpréter
./bin/behat -dl
Scénarios
Test de l’authentification d’un utilisateur
Premier fichier de tests à écrire dans feature/login.feature
# behat features/login.feature
Feature: Login
Les tests de login
@drush
Scenario: Login with drush
Given I am logged in as a user with the "authenticated user" role
When I click "My account"
Then I should see the heading "History"
Ce test va créer un utilisateur, l’authentifier. Ensuite il y aura clic sur la page “Mon compte”. Le test sera valide si la page contient la chaîne “History”.
Pour lancer le tests, il suffit de lancer la commande :
./bin/behat
Il faut bien sûr avoir un Selenium qui fonctionne pour exécuter les tests
Tests de la présence d’un block dans une région
Le tests ci-dessous permet de valider que le block login est présent dans la colonne de gauche. Il est valide sur une installation vierge avec le thème standard
# behat features/block.feature
Feature: Block
Les tests des blocks
@drush
Scenario: Find a heading in a region
Given I am not logged in
When I am on the homepage
Then I should see the heading "User login" in the "left sidebar" region
Création d’un contenu par un administrateur
Le scénario ci-dessous va créer et authentifier un utilisateur ayant le rôle administrateur. Puis, il y aura création d’un contenu de type article. Le test sera valide si drupal retourne le message que le contenu est bien créé
Feature: Article
Tests on articles
@drush @javascript
Scenario: Admin can create a article
Given I am logged in as a user with the "administrator" role
When I am on "/node/add/article"
And I fill in the following:
| Title | Test article |
| Body | This is the body of article |
And faire un screenshot
And I press "Save"
And faire un screenshot
Then faire un screenshot
And I break
And I should see the text "Article"
And I should see the text "Test article"
And I should see the text "has been created."
Astuces
Faire une pause dans un scénario
Le code ci-dessous ajouter au fichier feature/bootstrap/FeatureContext.php permet d’ajouter la commande wait XXXX qui permet de faire une pause de XXXX ms.
/**
* @Given /^wait (\d+)$/
*/
public function wait($arg1) {
$this->getSession()->wait($arg1);
}
Ajouter un break
l’extensions drupal permet dans les scénarios de stopper le scénarios jusqu’à ce que l’utilisateur appuie sur la touche Enter. Pratique pour le débugging des scénarios
Ajouter une commande de copies d’écran
Là, aussi, il faut modifier le fichier feature/bootstrap/FeatureContext.php. Un exemple ci-dessous de ce fichier avec la fonction
class FeatureContext extends MinkContext
{
private $stepnum;
/**
* Initializes context.
* Every scenario gets it’s own context object.
*
* @param array $parameters context parameters (set them up through behat.yml)
*/
public function __construct(array $parameters)
{
// Initialize your context here
$this->stepnum=0;
}
/**
* @Given /^je fais une copie écran$/
*/
public function jeFaisUneCopieEcran()
{
$this->stepnum=$this->stepnum+1;
$file=fopen(’screen_’.$this->stepnum.’.png’,’w’);
$screen=$this->getSession()->getDriver()->getScreenshot();
fwrite($file,$screen);
fclose($file);
}
}
Et voilà, nous pouvons utiliser la commande suivante dans nos scénarios
Je fais une copie écran
Conclusion
Avec cette extensions et behat, il devient de plus en plus facile et rapide d’écrire des scénarios de tests.