Et si on faisait de la BDD (Behavior Driven Development)

Ecrit par << Paquet Judicaël >>

La BDD (Behavior Driven Development) est une pratique Agile créée par Dan North en 2003 qui a pour but de créer des tests fonctionnels avec un langage naturel compris de tous.

Cette pratique encourage le rapprochement des équipes techniques et des équipes fonctionnelles ; en effet c’est une idée similaire au rapprochement voulu par les méthodes Agile.

Principes de la BDD

Voici les 3 principes principaux de la BDD qu’il faut retenir :

  1. La participation des équipes non techniques au projet
  2. Des scénarios automatisés pour décrire des comportements afin de faire de la non régression et pour commenter le code
  3. Mieux comprendre le comportement attendu pour les équipes techniques.

Mise en place complexe

Cette pratique implique beaucoup de changements au niveau des mentalités de l’entreprise. C’est pour cette raison, qu’elle est beaucoup moins fréquente dans les entreprises que celle des tests unitaires.

Nous avons vu de nombreuses DSI tenter de mettre cette pratique en place dans le passé ;  cependant elles n’ont pas su capitaliser dessus. Un accompagnement est vivement conseillé pour la mise en place de pratique telle que celle-ci.

Des Product Owner pas toujours préparés

Souvent en Agile, nous demandons aux Product Owner d’écrire eux-même les tests d’acceptances pour renforcer la qualité fonctionnelle des livrables.

Cette pratique se fait parfois par les développeurs dans certaines entreprises ; ça n’a pas beaucoup de sens d’imposer ce travail à ceux-ci. Cela va certes probablement améliorer un peu la qualité générale mais je ne suis pas convaincu qu’ils écrivent tous ces tests avec beaucoup d’envie (et donc de rigueur).

j’ai d’ailleurs écrit un article sur un type de user-story qui impose d’écrire ce type de tests aux Product Owner : Un format de user-story très efficace : le story A4.

En tant que coach, nous voyons de plus en plus de Définition of Done inclure des tests d’acceptances sous forme de tests fonctionnels (Article si vous ne connaissez pas le Definition of Done : Faire la Definition of Done des user-story) ; les coach Agile y sont sûrement pour quelque chose car nous essayons d’amener les équipes à chercher constamment à améliorer la qualité des produits livrés.

Cependant cela fonctionne pour des Product Owner (PO) qui ont de l’expérience dans ce poste mais la tâche peut s’avérer plus compliquée pour les Product Owner qui découvrent le métier. Il est indispensable que les PO inexpérimentés soient accompagnés individuellement par un coach si on ne veut pas que l’écriture de ces tests deviennent un point de blocage.

Ecrire un premier test fonctionnel

Ecrire en Gherkin

Nous allons à présent voir comment écrire un test fonctionnel. Pour cela nous allons l’écrire en langage Gherkin qui est le langage naturel compris par l’ensemble des outils de tests fonctionnels.

Le langage Gherkin est un langage naturel lisible par toute personne qu’elle soit du côté business ou du côté technique. Ce langage va décrire des comportements sans détailler comment ceux-ci sont intégrés.

Le langage Gherkin est un langage qui suit une structure spécifique où chaque ligne et l’indentation sont importantes (comme le python ou le YAML pour les personnes techniques qui passent par ici).

Voici un exemple simple proposé par cucumber (un outil de tests fonctionnels très populaire) :

 1: Feature: Some terse yet descriptive text of what is desired
 2:   Textual description of the business value of this feature
 3:   Business rules that govern the scope of the feature
 4:   Any additional information that will make the feature easier to understand
 5: 
 6:   Scenario: Some determinable business situation
 7:     Given some precondition
 8:       And some other precondition
 9:     When some action by the actor
10:       And some other action
11:       And yet another action
12:     Then some testable outcome is achieved
13:       And something else we can check happens too
14: 
15:   Scenario: A different situation
16:       ...

Certains outils reconnaissent le français mais certaines équipes privilégient de tout écrire en anglais car ces contenus se retrouveront partiellement dans le code ; il est devenu très rare que le code soit encore écrit en français de nos jours.

Vous allez utiliser cette syntaxe pour décrire vos tests. Vous allez décrire la fonctionnalité dans son ensemble dans la partie feature puis vous allez définir différents scénarios possibles.

Il est toujours conseillé de proposer des scénarios qui valident une situation et des scénarios qui invalident également cette même situation. Comme ça en cas d’erreur d’inversement d’une condition dans le code, on le détectera tout de suite (l’erreur est humaine).

Ce n’est pas un test end-to-end ou GUI

En effet, comme me l’a rappelé Michaël, le BDD doit impérativement se focaliser sur un use case et non sur le GUI (Graphical User Interface) ou au détail de l’infrastructure.

C’est un point important car le risque est de finir avec un ensemble de tests trop long à s’exécuter ; cela pousserait les équipes à finalement passer outre les tests en cas d’urgence.

Faisons notre premier test en PHP

Afin de bien comprendre les principes de la BDD (Behavior Driven Development), nous allons installer un Symfony 3 qui est le framework PHP actuellement le plus populaire en France sur lequel nous allons appliquer nos premiers tests BDD. Voici le minimum requis pour installer le nécessaire sur un Linux Ubuntu 16.04 :

sudo apt-get update
sudo apt-get install -y mysql-server apache2 php7.0 libapache2-mod-php7.0 php7.0-mysql php7.0-cli php7.0-xml phpunit php7.0-curl composer php7.0-mbstring
sudo a2enmod rewrite
service apache restart

Ensuite nous devons installer notre Symfony 3 afin de pouvoir faire notre premier test unitaire :

sudo mkdir -p /usr/local/bin
sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
sudo chmod a+x /usr/local/bin/symphony
sudo chmod -R 777 /var/www
sudo symfony new /var/www/mon_projet

Nous allons tenter de lancer le serveur web intégré de Symfony afin de vérifier que tout est bien installé :

cd /var/www/mon_projet
bin/console server:run

Nous allons installer Behat qui est un outil qui permet de faire des tests fonctionnels en PHP. Dans Symfony, il est possible de l’installer facilement grâce au fichier composer.json à la racine du projet :

"require-dev": {
    "behat/behat": "^3.1",
    "behat/mink": "^1.7",
    "behat/mink-browserkit- driver": "^1.3",
    "behat/mink-extension": "^2.2",
    "behat/symfony2-extension": "^2.1",
    "behatch/contexts": "^2.5",

Sachez que Behat est installable totalement indépendamment de Symfony car il peut être utilisé sur tous les projets PHP.

Nous allons à présent initialiser Behat qui va créer un dossier features avec un fichier features/bootstrap/FeatureContext.php :

sudo vendor/bin/behat -- init

Nous allons écrire notre premier test avec le langage Gherkin (vu plus haut). Bonne nouvelle, Behat reconnait parfaitement ce langage. Voici un exemple de tests dans le fichier features/AppBundle/check.feature

Feature: test

Scenario: Test my connection
    When I try to connect on my account
        And I put "toto" in login
        And I put ""xxx" in password
        And I validate the form
    Then I'm connected

En lançant Behat avec la commande « sudo vendor/bin/behat », Behat nous fera un retour complet du type :

Feature: test

Scenario: Test my homepage                 # features/AppBundle/test.feature:2Scenario: Test my connection     When I try to connect on my account
    When I try to connect on my account
        And I put "toto" in login
        And I put ""xxx" in password
        And I validate the form     
    Then I'm connected

1 scénario (1 indéfinis)
2 étapes (2 indéfinis)
0m0.02s (7.08Mb)

>> default suite has undefined steps. Please choose the context to generate snippets:

[0] None
[1] FeatureContext
> 1

-- - FeatureContext a des étapes manquantes. Définissez-les avec les modèles suivants :

    /**
     * @When I try to connect on my account :arg1 :arg2
     */

    public function iTryToConnectOnMyAccount($arg1,$arg2)
    {
         throw new PendingException();
    }

   /**
    * @Then I'm connected
    */

    public function iMConnected()
    {
        throw new PendingException();
    }

Behat nous indique que le développeur devra écrire un minimum de code pour pouvoir avoir notre test fonctionnel. Nous allons donc écrire le contenu de notre test fonctionnel pour qu’il soit testable concrètement en remplissant le fichier features/bootstrap/FeatureContext.php qui a été créé lors de l’initialisation de Behat :

<?php

use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;

/**
 * Defines application features from the specific context.
 */

class FeatureContext implements Context
{
    private $_contentPage;

    /**
     * Initializes context.
     *
     * Every scenario gets its own context instance.
     * You can also pass arbitrary arguments to the
     * context constructor through behat.yml.
     */

    public function __construct()
    {
        $this->user = new User; 
    }

    /**
     * @When I try to connect on my account :arg1 :arg2
     */

    public function iTryToConnectOnMyAccount($arg1,$arg2)
    {
        $this->user->login = $arg1;
        $this->user->pswd = $arg2;
    }

    /**
     * @ThenI'm connected
     */
    public function iMConnected()
    {
         if ($this->user->isGoodPswd() !== true) {
             throw new ConnectionException();
        }
    }
}

En lançant Behat à nouveau, vous aurez une grosse erreur qui apparait car la connexion n’existe pas pour « toto ».

Conclusion BDD (Behavior Driven Development)

Mettre en place de la BDD (Behavior Driven Development) n’est pas simple. Avec un bon accompagnement sur le sujet, vous saurez profiter de ces tests fonctionnels pour diminuer le risque de regressions futures dans vos applications .

Avec ce type de tests, vous diminuerez considérablement le taux de bug à l’avenir sur l’application concernée. Un gain de temps considérable qu’il ne faut pas négliger.

 

2 réponses sur “Et si on faisait de la BDD (Behavior Driven Development)”

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.