DokuWiki

It's better when it's simple

Outils pour utilisateurs

Outils du site


fr:devel:unittesting

:!: à relire pour corrections

Tests unitaires de Dokuwiki

Brièvement expliqué, un Test_unitaire consiste à écrire du code pour tester des “unités” d'un autre code, de sorte que les tests peuvent être relancés à tout moment pour déterminer si le code a été “cassé” ou non (par opposition au test manuel des applications, qui est long et potentiellement peu fiable). Le mot “unité” est utilisé pour désigner tout ce qui fournit une API clairement définie, telle qu'une classe ou une fonction PHP.

Les tests unitaires de DokuWiki sont situés dans le répertoire _test d'un checkout git . Ils ne sont pas inclus dans les versions régulières.

Nous utilisons le cadre de test PHPUnit pour PHP. Cette page vous guide dans la préparation de votre environnement de test, l'exécution des tests et l'écriture de vos propres tests.

Configuration

Télécharger le fichier phar convenant à votre version de PHP.

cd dokuwiki/_test
php fetchphpunit.php

Lancer des tests

L'exécution de la suite de tests est simple, voici comment.

Tous les tests

Il suffit de se rendre dans le répertoire _test et de lancer phpunit :

cd _test/
php phpunit.phar

Test sur des fichiers uniques

Vous pouvez exécuter un fichier test spécifique en le donnant comme paramètre :

cd _test
php phpunit.phar tests/inc/input.test.php

Tests groupés

Vous incluez ou excluez les tests de leur groupe :

  cd _test
  # run all tests that require an internet connection this is edited in firevim
  php phpunit.phar --group internet
  # run all tests that don't require an internet connection  
  php phpunit.phar --exclude-group internet

Greffons

Les tests de greffons sont marqués avec un groupe nommé plugin_<nom du plugin> :

cd _test
php phpunit.phar --group plugin_extension

Veuillez noter que certains greffons peuvent en nécessiter d'autres afin de passer, soit en tant que dépendances, soit parce que certains codes d'intégration sont en cours de test. Vérifiez s'ils ont un fichier requirements.txt dans leur dossier pour les greffons nécessaires.

Écriture de tests

PHPUnit rend la rédaction de nouveaux tests aussi indolore que possible. En général, il s'agit d'écrire une classe PHP assez simple et de la placer dans le bon répertoire avec le bon nom de fichier. Une fois cela fait, le test peut être immédiatement exécuté comme expliqué ci-dessus.

Pour un aperçu général sur la façon de rédiger des tests unitaires, veuillez vous référer au Manuel PHPUnit en français et aux tests existants, nos parties spécifiques DokuWiki sont décrites ci-dessous.

Conventions de nommage

Les tests sont placés quelque part sous le répertoire ./_test/tests/. En général, il est recommandé que la structure de ce répertoire suive celle du code DokuWiki qu'il teste, c'est-à-dire que les tests pour ./feed.php vont directement sous ./_test/tests alors que les tests pour ./inc/auth/plain.php iraient sous ./_test/tests/inc/auth.

Tous les tests doivent se terminer par .test.php pour être trouvés automatiquement par la suite de tests. Pour les fichiers de code DokuWiki qui contiennent de nombreuses fonctions sans rapport ou complexes, vous pouvez créer plusieurs fichiers de test. Par exemple, plutôt que d'avoir un seul fichier _test/tests/inc/common.test.php, il est recommandé d'avoir des fichiers comme _test/tests/inc/common_clientip.test.php et _test/tests/inc/common_obfuscate.test.php.

Chaque fichier de test doit contenir une classe héritant de DokuWikiTest. Cette classe peut avoir plusieurs fonctions de test, chacune d'entre elles étant nommée par un test_. À l'intérieur de ces fonctions, votre assertion peut être écrite.

Environnement

Notre suite de tests utilise une méthode setUpBeforeClass() pour instancier chaque classe de test qui sera utilisée :

  • configurer un répertoire minimal data (copié à partir de _test/data) dans le répertoire TEMP du système
  • créer un répertoire de configuration personnalisé dans le répertoire TEMP du système
    • avec les paramètres de configuration par défaut
    • quelques dérogations à _test/conf
  • relancer l'initialisation de DokuWiki

Cette installation ne chargera aucun plugin. Si vous avez besoin d'activer un plugin, vous pouvez remplacer le tableau DokuWikiTest::$pluginsEnabled et fournir les noms des plugins à charger.

Remarque: N'oubliez pas d'appeler parent::setUpBeforeClass() pour écraser la méthode setUpBeforeClass()

De plus, la suite de tests exécute une méthode setUp() avant chaque test. Elle fait :

  • recharger la configuration du dokuwiki
  • recharger le contrôleur de plugin et les plugins
  • recharger le gestionnaire d'événements
  • s'assurer de l'existence de certains fichiers (voir init_files())
  • assurer les chemins dokuwiki (voir init_path())
  • recharger les variables globales comme $_SERVER.
Remarque: N'oubliez pas d'appeler parent::setUp() pour écraser la méthode setUp()

Il n'y a pas de véritable isolement de processus entre tous les tests, chaque classe de test devrait avoir un environnement DokuWiki assez propre pour travailler. Cela inclut également le mécanisme d’autoloader de DokuWiki, il ne devrait donc pas être nécessaire de require_once des fichiers vous-même.

Intégration de tests

Les tests unitaires doivent tester des parties de code minimales (unités) dans la mesure du possible. Mais avec une application complexe comme DokuWiki, cela n'est pas toujours possible. C'est pourquoi notre suite de tests permet d'effectuer des tests d'intégration simples ainsi que d'utiliser une fausse requête.

Grâce à ce mécanisme, une requête HTTP est falsifiée et la sortie HTML qui en résulte peut être inspectée. Cela permet également de tester les événements des plugins.

Lancer une requête

la classe TestRequest est utilisée pour lancer une requête. Une requête contient trois étapes :

  1. Initialisation
  2. Preparation de la requête
  3. Envoi de la requête

L'intialisation est faite par :

$request = new TestRequest();

Une fois qu'elle est initialisée, vous pouvez préparer la demande. La préparation peut consister à enregistrer des accroches d'événements ou à définir des variables de demande.

Les variables de la requête sont configurées en méthodes via des mutateurs et ressemblent à ceci :

Variable Setter method
$_SERVER $request->setServer()
$_SESSION $request->setSession()
$_POST $request->setPost()
$_GET $request->setGet()

Enfin, vous devez exécuter la requête. Cela peut être fait en appelant la méthode $request->execute('someurl'). La valeur de retour de la méthode d'exécution est le contenu html rendu par DokuWiki.

En plus, il y a deux méthodes pour des appels en POST et GET. Ils peuvent être plus courts qu'en utilisant les méthodes du mutateur.

// a get request
$request->get(array('id' => 'start'), '/doku.php');
// a post request
$request->post(array('id' => 'start'), '/doku.php');

Le résultat d'une requête est un objet TestResponse.

Exemple: Accroches d’événements

Comme mentionné, les requêtes ne sont pas de vraies requêtes. Chaque appel que vous passez dans votre test modifie le comportement de DokuWiki sur la requête.

Ici, ceci est utilisé pour accrocher un événement.

function testHookTriggering() {
    global $EVENT_HANDLER;
 
    $request = new TestRequest(); // initialize the request
    $hookTriggered = false; // initialize a test variable
 
    // register a hook
    $EVENT_HANDLER->register_hook('TPL_CONTENT_DISPLAY', 'AFTER', null,
        function() use (&$hookTriggered) {
            $hookTriggered = true;
        }
    );
 
    // do the request
    $request->execute();
 
    // check the result of our variable
    $this->assertTrue($hookTriggered, 'Hook was not triggered as expected!');
}

Exemple: Utiliser phpQuery après une requête

Il arrive que vous souhaitiez examiner le html résultant d'une requête. Pour fournir un peu de confort, nous utilisons la librairie phpQuery. Avec cela, vous pouvez utiliser un style de type jQuery sur le html.

Un simple exemple suit :

function testSimpleRun() {
    // make a request
    $request = new TestRequest();
    $response = $request->execute();
 
    // get the generator name from the meta tag.
    $generator = $response->queryHTML('meta[name="generator"]')->attr('content');
 
    // check the result
    $this->assertEquals('DokuWiki', $generator);
}

Tests des greffons et des thèmes

Parfois, vous avez besoin de tests unitaires dans vos extensions 1). Ici, vous pouvez utiliser les mêmes classes et méthodes que celles utilisées dans le noyau de DokuWiki. L'assistant de greffon a une option pour ajouter un exemple de test dans votre squelette de plugin.

Il suffit de placer vos tests dans le dossier <extension dir>/_test/. Les tests doivent être conformes à la convention de nommage, par exemple, vos scénarios de test doivent étendre la classe DokuWikiTest et le nom du fichier doit se terminer par .test.php.

Pour fonctionner, votre greffon doit être activé pendant le test. Pour ce faire, il faut le mettre, ainsi que tous les greffons dont il dépend, dans le membre $pluginsEnabled.

Les tests de greffon doivent déclarer un groupe pour tous leurs tests nommé plugin_<nom du plugin> pour faciliter leur exécution séparée.

Si votre greffon a besoin de fichiers supplémentaires pendant le test, vous pouvez les copier dans le répertoire de test en utilisant la méthode setUpBeforeClass(). Veillez à appeler le parent en premier.

Voici un petit exemple :

/**
 * @group plugin_data
 * @group plugins
 */
class helper_plugin_data_test extends DokuWikiTest {
 
    protected $pluginsEnabled = array('data', 'sqlite');
 
    public static function setUpBeforeClass(){
        parent::setUpBeforeClass();
        // copy our own config files to the test directory
        TestUtils::rcopy(dirname(DOKU_CONF), dirname(__FILE__).'/conf');
    }
 
    public function testExample() {
        $this->assertTrue(true,'if this fails your computer is broken');
    }
}

La configuration d'un greffon peut simplement être modifiée en écrivant dans le tableau $conf. Les modifications peuvent par exemple être effectuées dans les fonctions de test elles-mêmes ou dans la fonction setUp(). Les changements de configuration dans la fonction setUpBeforeClass() n'auront aucun effet. Jetez un coup d’œil à cet exemple :

    function setUp(){
        global $conf;
 
        parent::setUp();
 
        $conf ['plugin']['creole']['precedence'] = 'Creole';
        $conf ['plugin']['creole']['linebreak']  = 'Whitespace';
    }

L'indexation correcte des plugins est donc $conf ['plugin']['plugin name']['option name'].

Intégration continue avec Travis CI

Les auteurs de greffons sont encouragés à les enregistrer auprès de Travis CI pour bénéficier de tests automatisés. L' assistant greffon ajoute un .travis.yml approprié à votre plugin lorsque vous sélectionnez l'option Unit Test. L'environnement de compilation nécessaire est fourni par le dokuwiki-travis script.

Conditions requises

Si vos tests nécessitent l'installation de greffons supplémentaires, fournissez un fichier requirements.txt dans le répertoire racine de votre greffon. Voir pour les détails le README dans le dépôt dokuwiki-travis.

Javascript + test Frontend

Il est possible d'intégrer des tests javascript écrits en qunit aux tests automatisés avec l'IC Travis. La base en est le npm, grunt et phantomjs 2).

.travis.yml
language: php
php:
  - "5.5"
  - "5.4"
  - "5.3"
env:
  - DOKUWIKI=master
  - DOKUWIKI=stable
  - DOKUWIKI=old-stable
before_install:
  - wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh
  - npm install
install: sh travis.sh
script:
  - cd _test && phpunit --stderr --group plugin_yourplugin
  - cd ../lib/plugins/yourplugin && grunt

npm nécessite un package.json pour installer les dépendances :

package.json
{
  "name": "yourplugin",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-qunit": "^0.7.0",
    "jquery": "^2.1.4",
    "qunitjs": "^1.18.0"
  }
}

grunt nécessité un Gruntfile.js pour définir les tâches :

Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'), // the package file to use
 
    qunit: {
      all: ['_jstest/*.html']
    }
});
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.registerTask('default', ['qunit']);
};

Enfin, les fichiers html de sortie doivent être ajustés pour pouvoir fonctionner avec les node_modules pour les tests automatisés et avec les bibliothèques en ligne pour les tests des navigateurs :

qunit.test.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>tests for your plugin</title>
    <link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.18.0.css">
    <script src="../node_modules/jquery/dist/jquery.js"></script>
    <script>window.jQuery || document.write('<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"><\/script>')</script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
<script>window.QUnit || document.write('<script src="//code.jquery.com/qunit/qunit-1.18.0.js"><\/script>')</script>
<script src="../script/myscript.js"></script>
<script src="mytest.tests.js"></script>
 
</body>
</html>

Voir le greffon edittable pour une mise en œuvre de cette approche.

Greffons

Les greffons peuvent utiliser toutes les fonctionnalités mentionnées ci-dessus. Les tests de votre greffon doivent être placés dans un répertoire appelé _test dans votre greffon. Chaque classe de test doit étendre le DokuWikiTest.

Assurez-vous d'assigner les noms des groupes plugin et plugin_<plugin> :

<?php
/**
 * Tests to ensure creole syntax is correctly processed
 * and creates expected XHTML output
 *
 * @group plugin_creole
 * @group plugins
 */
class plugin_creole_test extends DokuWikiTest {
...
}

Voir aussi

Crédits

  • traduction : — digitalin 2020-08-16 11:38
1)
les extensions sont des greffons et des thèmes
fr/devel/unittesting.txt · Dernière modification : 2023-10-19 19:07 de 81.64.99.22

Sauf mention contraire, le contenu de ce wiki est placé sous les termes de la licence suivante : CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki