Question

J'essaie d'intégrer des tests unitaires JavaScript dans mon processus de génération automatisée. Actuellement, JSUnit fonctionne bien avec JUnit, mais il semble s'agir d'un abandonware et manque d'un bon support pour AJAX, le débogage et les délais.

Quelqu'un a-t-il eu de la chance en automatisant (avec ANT) une bibliothèque de tests unitaires telle que YUI test, JQuery's QUnit ou jQUnit ( http://code.google.com/p/jqunit/ )?

Remarque: j'utilise une bibliothèque AJAX construite sur mesure. Le problème avec le DOH de Dojo est qu'il vous oblige à utiliser leurs propres appels de fonction AJAX et gestionnaires d'événements pour fonctionner avec tous les tests d'unité AJAX.

Était-ce utile?

La solution

Il existe de nombreux frameworks de tests unitaires javascript (jsUnit, scriptaculous, ...), mais jsUnit est le seul que je connaisse qui puisse être utilisé avec une construction automatisée.

Si vous effectuez un test réel, vous ne devriez pas avoir besoin du support AJAX. Par exemple, si vous utilisez un framework ajax RPC tel que DWR, vous pouvez facilement écrire une fonction fictive:

   function mockFunction(someArg, callback) {
      var result = ...; // some treatments   
      setTimeout(
function() { callback(result); }, 300 // some fake latency
); }

Et oui, JsUnit gère les délais d'attente: temps de simulation dans jsUnit Tests

Autres conseils

Je suis sur le point de commencer à utiliser Javascript TDD sur un nouveau projet sur lequel je travaille. Mon plan actuel consiste à utiliser qunit pour effectuer les tests unitaires. Lors du développement des tests, vous pouvez exécuter le test simplement en actualisant la page de test dans un navigateur.

Pour une intégration continue (et pour que les tests soient exécutés dans tous les navigateurs), je vais utiliser Selenium pour charger automatiquement le harnais de test dans chaque navigateur et lisez le résultat. Ces tests seront exécutés à chaque enregistrement du contrôle de code source.

Je vais également utiliser JSCoverage pour obtenir une analyse de la couverture de code des tests. Cela sera également automatisé avec Selenium.

Je suis en train de mettre cela en place. Je mettrai à jour cette réponse avec des détails plus précis une fois la configuration définie.

Outils de test:

Je suis un grand fan de de js-test-driver

Il fonctionne bien dans un environnement CI et est capable de capturer les navigateurs actuels pour les tester sur plusieurs navigateurs.

J'ai récemment lu un article de Bruno utilisant JsUnit et créant un framework JsMock en plus de cela ... très intéressant. Je pense utiliser son travail pour commencer à tester un peu mon code Javascript.

Mock Javascript ou Comment tester le JavaScript en dehors de l'environnement du navigateur

Je viens de demander à Hudson CI d'exécuter JasmineBDD (sans tête ), au moins pour les tests unitaires javascript purs.

(Hudson exécutant Java via un shell, exécutant Envjs et JasmineBDD.)

Je n'ai pas encore réussi à utiliser une grande bibliothèque, comme un prototype.

Je suis d’accord pour dire que jsunit est en train de mourir sur la vigne. Nous venons de le remplacer par le test YUI.

Semblable à l'exemple utilisant qUnit, nous exécutons les tests avec Selenium. Nous exécutons ce test indépendamment de nos autres tests au sélénium simplement parce qu'il ne possède pas les dépendances inhérentes aux tests de régression d'interface utilisateur normaux (par exemple, le déploiement de l'application sur un serveur).

Pour commencer, nous avons un fichier javascript de base qui est inclus dans tous nos fichiers HTML de test. Ceci gère la configuration de l'instance YUI, du lanceur de test, de l'objet YUI.Test.Suite ainsi que de Test.Case. Il possède une méthode accessible via Selenium pour exécuter la suite de tests, vérifier si le programme d'exécution de test est toujours en cours d'exécution (les résultats ne sont disponibles qu'après l'avoir terminée) et obtenir les résultats du test (nous avons choisi le format JSON)

var yui_instance; //the YUI instance
var runner;  //The YAHOO.Test.Runner
var Assert; //an instance of YAHOO.Test.Assert to save coding
var testSuite; //The YAHOO.Test.Suite that will get run.

/**
 * Sets the required value for the name property on the given template, creates
 * and returns a new YUI Test.Case object.
 * 
 * @param template the template object containing all of the tests
 */
function setupTestCase(template) {
    template.name = "jsTestCase";
    var test_case = new yui_instance.Test.Case(template);
    return test_case;
}

/**
 * Sets up the test suite with a single test case using the given 
 * template.
 * 
 * @param template the template object containing all of the tests
 */
function setupTestSuite(template) {
    var test_case = setupTestCase(template);
    testSuite = new yui_instance.Test.Suite("Bond JS Test Suite");
    testSuite.add(test_case);
}

/**
 * Runs the YAHOO.Test.Suite
 */
function runTestSuite() {
    runner = yui_instance.Test.Runner;
    Assert = yui_instance.Assert;

    runner.clear();
    runner.add(testSuite);
    runner.run();
}

/**
 * Used to see if the YAHOO.Test.Runner is still running.  The
 * test results are not available until it is done running.
 */
function isRunning() {
    return runner.isRunning();
}

/**
 * Gets the results from the YAHOO.Test.Runner
 */
function getTestResults() {
    return runner.getResults(yui_instance.Test.Format.JSON);
}

En ce qui concerne le sélénium, nous avons utilisé un test paramétré. Nous exécutons nos tests à la fois dans IE et FireFox dans la méthode data, en analysant les résultats du test dans une liste de tableaux d’objets, chaque tableau contenant le nom du navigateur, le nom du fichier test, le nom du test, le résultat obtenu (réussite, échec ou non). et le message.

Le test réel n'affirme que le résultat du test. Si ce n'est pas égal à "passer" puis le test échoue avec le message renvoyé par le résultat du test YUI.

    @Parameters
public static List<Object[]> data() throws Exception {
    yui_test_codebase = "file:///c://myapppath/yui/tests";

    List<Object[]> testResults = new ArrayList<Object[]>();

    pageNames = new ArrayList<String>();
    pageNames.add("yuiTest1.html");
    pageNames.add("yuiTest2.html");

    testResults.addAll(runJSTestsInBrowser(IE_NOPROXY));
    testResults.addAll(runJSTestsInBrowser(FIREFOX));
    return testResults;
}

/**
 * Creates a selenium instance for the given browser, and runs each
 * YUI Test page.
 * 
 * @param aBrowser
 * @return
 */
private static List<Object[]> runJSTestsInBrowser(Browser aBrowser) {
    String yui_test_codebase = "file:///c://myapppath/yui/tests/";
    String browser_bot = "this.browserbot.getCurrentWindow()"
    List<Object[]> testResults = new ArrayList<Object[]>();
    selenium = new DefaultSelenium(APPLICATION_SERVER, REMOTE_CONTROL_PORT, aBrowser.getCommand(), yui_test_codebase);
    try {
        selenium.start();

        /*
         * Run the test here
         */
        for (String page_name : pageNames) {
            selenium.open(yui_test_codebase + page_name);
            //Wait for the YAHOO instance to be available
            selenium.waitForCondition(browser_bot + ".yui_instance != undefined", "10000");
            selenium.getEval("dom=runYUITestSuite(" + browser_bot + ")");

            //Output from the tests is not available until 
            //the YAHOO.Test.Runner is done running the suite
            selenium.waitForCondition("!" + browser_bot + ".isRunning()", "10000");
            String output = selenium.getEval("dom=getYUITestResults(" + browser_bot + ")");

            JSONObject results = JSONObject.fromObject(output);
            JSONObject test_case = results.getJSONObject("jsTestCase");
            JSONArray testCasePropertyNames = test_case.names();
            Iterator itr = testCasePropertyNames.iterator();

            /*
             * From the output, build an array with the following:
             *  Test file
             *  Test name
             *  status (result)
             *  message
             */
            while(itr.hasNext()) {
                String name = (String)itr.next();
                if(name.startsWith("test")) {
                    JSONObject testResult = test_case.getJSONObject(name);
                    String test_name = testResult.getString("name");
                    String test_result = testResult.getString("result");
                    String test_message = testResult.getString("message");
                    Object[] testResultObject = {aBrowser.getCommand(), page_name, test_name, test_result, test_message};
                    testResults.add(testResultObject);
                }
            }

        }
    } finally {
        //if an exception is thrown, this will guarantee that the selenium instance
        //is shut down properly
        selenium.stop();
        selenium = null;
    }
    return testResults;
}
/**
 * Inspects each test result and fails if the testResult was not "pass"
 */
@Test
public void inspectTestResults() {
    if(!this.testResult.equalsIgnoreCase("pass")) {
        fail(String.format(MESSAGE_FORMAT, this.browser, this.pageName, this.testName, this.message));
    }
}

J'espère que cela vous sera utile.

Un nouveau projet vous permet d'exécuter les qunit dans un environnement Java (comme ant) ??afin de peut pleinement intégrer votre suite de tests côté client avec vos autres tests unitaires.

http://qunit-test-runner.googlecode.com

Je l'ai utilisé pour tester des plugins jQuery, objx , du code OO personnalisé et cela fonctionne pour tout sans modification.

Le projet sur lequel je travaille utilise Js-Test-Driver . Hébergement de Jasmine sur Chrome 10 avec Jasmine-JSTD-Adapter , y compris l'utilisation de Couverture de code . Tests inclus dans JS-Test-Driver. Bien qu'il y ait des problèmes à chaque fois que nous changeons ou mettons à jour les navigateurs sur environnement CI , les tests Jasmin sont en cours d'exécution. Je n'ai pas eu de problème avec les tests ansynchrones, mais pour autant que je sache, Jasmine Clock permet de les résoudre, mais je n'ai pas encore eu la possibilité de les corriger.

J'ai publié une petite bibliothèque permettant de vérifier les tests JavaScript dépendant du navigateur sans passer par un navigateur. . C'est un module node.js qui utilise zombie.js pour charger la page de test et inspecter les résultats. J'en ai écrit sur mon blog . Voici à quoi ressemble l'automatisation:

var browsertest = require('../browsertest.js').browsertest;

describe('browser tests', function () {

it('should properly report the result of a mocha test page', function (done) {
    browsertest({
        url: "file:///home/liam/work/browser-js-testing/tests.html",
        callback: function() { 
            done();
        }
    });
});

});

J'ai regardé la date de votre question et à l'époque, il y avait quelques bons tests JS lib / framework. Aujourd'hui, vous pouvez trouver beaucoup plus et dans différents domaines tels que TDD, BDD, Assetion et le support des coureurs avec / sans.

Il y a beaucoup de joueurs dans ce jeu comme Mocha, Chai, Qunit, Jasmine, etc ... Vous trouverez plus d'informations dans le ce blog sur les tests JS / Mobile / Web ...

Un autre framework de test JS pouvant être exécuté avec Ant est CrossCheck . Il existe un exemple d’exécution de CrossCheck via Ant dans le fichier de construction du projet.

CrossCheck tente, avec un succès limité, d’émuler un navigateur, y compris des implémentations de type fictif de XMLHttpRequest et du délai d’expiration / intervalle.

Cependant, il ne gère pas le chargement de javascript depuis une page Web. Vous devez spécifier les fichiers javascript que vous souhaitez charger et tester. Si vous gardez tous vos fichiers JS séparés de votre code HTML, cela pourrait fonctionner pour vous.

J'ai écrit une tâche Ant qui utilise Phantom JS , un navigateur sans kit web, pour exécuter les fichiers de test HTML QUnit. dans un processus de construction Ant. La construction peut également échouer si des tests échouent.

https://github.com/philmander/ant-jstestrunner

C’est une bonne évaluation de plusieurs outils de test.

Outils de test des unités JavaScript pour TDD

Je préfère personnellement https://code.google.com/p/js-test-driver/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top