Jstester

Un utilitaire extrêmement simple de tests unitaires en javascript développé il y a des années et remis au gout du jour.

Présentation

Cet un outil qui n'est absolument pas destiné à produire des tests unitaires d'envergures ou de couvrir l'ensemble des besoins que ce type d'activité exige. C'est un truc écrit en une demi-heure il y a presque dix ans qui répond à un besoin basique : faire rapidement et sans fioritures des tests unitaires de base pour valider un code et s'éviter des régressions bêtes. D'autres outils existent pour des validations plus complexes.

Le code est ici mis à jour en « javascript moderne » sous forme de module. Il fait aussi parti d'une réécriture progressive de ma librairie javascript afin d'obtenir des modules indépendants les uns des autres.

Exemple

import { TestSuite } from './jstester.js';

const testSuite = new TestSuite('html');
testSuite.testing('Boolean');
testSuite.assertEqual({
    title: 'True Equals !false',
    actual: !false,
    expected: true
});
testSuite.testing('String - trim');
testSuite.assertEqual({
    title: 'Trim spaces',
    actual: '  Hello World  '.trim(),
    expected: 'Hello World'
});
Exemple d'utilisation — oui, les tests sont débiles :-).

rendu de la suite de test

Exemple de rendu HTML d'une suite de tests.

Code

/**
 *  Html logger : write pass and fail asserts in a bullet list.
 */
class HtmlLogger {
    /**
     * @param {Object} [options] Options
     * @param {HTMLELement} [options.parent] Where to insert log element
     */
    constructor (options) {
        this.element = document.createElement('ul');
        this.element.id = 'log';
        this.element.classList.add('jstester');
        if (options && options.parent) {
            options.parent.appendChild(this.element);
        } else {
            document.body.appendChild(this.element);
        }
    }
    dispose () {
        this.element.parentNode.removeChild(this.element);
        this.element = null;
    }
    clear () {
        this.element.innerHTML = '';
    }
    log (message) {
        var item = document.createElement('li');
        item.className = 'log';
        item.innerHTML = message;
        this.element.appendChild(item);
    }

    pass (assertion) {
        var item = document.createElement('li');
        item.className = 'pass';
        item.innerHTML = assertion.title;
        this.element.appendChild(item);
    }

    fail (assertion) {
        var item = document.createElement('li');
        item.className = 'fail';
        item.innerHTML = assertion.title;
        item.appendChild(this.detail('actual', assertion.actual));
        item.appendChild(this.detail('expected', assertion.expected));
        this.element.appendChild(item);
    }

    detail (name, content) {
        var dl = document.createElement('dl'),
            dt = document.createElement('dt'),
            dd = document.createElement('dd'),
            pre = document.createElement('pre');
        dt.innerHTML = name;
        pre.innerHTML = content;
        dd.appendChild(pre);
        dl.appendChild(dt);
        dl.appendChild(dd);
        return dl;
    }
}

class ConsoleLogger {
    constructor () {}
    log (message) {
        console.log(message); 
    }
    pass (assertion) {
        console.log('ok: ' + assertion.title); 
    }
    fail (assertion) {
        console.warn('ko: ' + assertion.title); 
        console.warn(assertion);
    }
    clear () {}
    dispose () {}
}

/**
 * Classe de test unitaire
 */
class TestSuite {
    /**
     * 
     * @param {String} [loggerType='html'|'console'] Type de log souhaité (console par défaut)
     * @param {Object} [options] Options
     */
    constructor (loggerType, options) {
        this.logger = loggerType === 'html'
            ? new HtmlLogger(options)
            : new ConsoleLogger(options);
    }

    clear () {
        this.logger.clear();
    }

    dispose () {
        this.logger.dispose();
        this.logger = null;
    }

    testing (title) {
        this.logger.log(title);
    }

    assertEqual (assertion) {
        assertion.operator = '===';
        if (assertion.actual === assertion.expected) {
            this.logger.pass(assertion);
        } else {
            this.logger.fail(assertion);
        }
    }

    assertNull (assertion) {
        assertion.operator = '=== null';
        if (assertion.actual === null) {
            this.logger.pass(assertion);
        } else {
            this.logger.fail(assertion);
        }
    }

    assertFalse (assertion) {
        assertion.operator = '=== false';
        if (assertion.actual === false) {
            this.logger.pass(assertion);
        } else {
            this.logger.fail(assertion);
        }
    }

    assertTrue (assertion) {
        assertion.operator = '=== true';
        if (assertion.actual === true) {
            this.logger.pass(assertion);
        } else {
            this.logger.fail(assertion);
        }
    }
}

export { TestSuite };
Molule jstester.

Licence

jstester - Tests unitaires simple en javascript Copyright (C) 2019 Rui Nibau

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

Historique

2019-02-09
  • upd portage au format module.
2010-05
  • add Création du code.