Pregunta

Estoy intentando incorporar algunas pruebas unitarias de JavaScript en mi proceso de compilación automatizado.Actualmente JSUnit funciona bien con JUnit, pero parece ser abandonware y carece de buen soporte para AJAX, depuración y tiempos de espera.

¿Alguien ha tenido suerte al automatizar (con ANT) una biblioteca de pruebas unitarias como YUI test, JQuery's QUnit o jQUnit (http://code.google.com/p/jqunit/)?

Nota:Utilizo una biblioteca AJAX personalizada, por lo que el problema con DOH de Dojo es que requiere que uses sus propias llamadas a funciones AJAX y controladores de eventos para trabajar con cualquier prueba unitaria AJAX.

¿Fue útil?

Solución

Existen muchos marcos de pruebas unitarias de JavaScript (jsUnit, scriptaculous, ...) pero jsUnit es el único que conozco que puede usarse con una compilación automatizada.

Si está realizando una prueba unitaria "verdadera", no debería necesitar soporte AJAX.Por ejemplo, si está utilizando un marco RPC ajax como DWR, puede escribir fácilmente una función simulada:

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

Y sí, JsUnit maneja tiempos de espera: Simulación de tiempo en pruebas jsUnit

Otros consejos

Estoy a punto de empezar a utilizar Javascript TDD en un nuevo proyecto en el que estoy trabajando.Mi plan actual es usar qunitar para realizar las pruebas unitarias.Mientras se desarrollan las pruebas, se pueden ejecutar simplemente actualizando la página de prueba en un navegador.

Para una integración continua (y garantizar que las pruebas se ejecuten en todos los navegadores), usaré Selenio para cargar automáticamente el arnés de prueba en cada navegador y leer el resultado.Estas pruebas se ejecutarán en cada registro del control de fuente.

yo también voy a usar JSCoverage para obtener un análisis de cobertura de código de las pruebas.Esto también se automatizará con Selenium.

Actualmente estoy en medio de la configuración de esto.Actualizaré esta respuesta con detalles más exactos una vez que haya resuelto la configuración.


Herramientas de prueba:

Soy un gran fan de controlador de prueba js

Funciona bien en un entorno de CI y es capaz de capturar navegadores reales para realizar pruebas entre navegadores.

Recientemente leí un artículo de Bruno usando JsUnit y creando un marco JsMock además de eso...muy interesante.Estoy pensando en utilizar su trabajo para comenzar a realizar pruebas unitarias de mi código Javascript.

Simulacro de Javascript o cómo realizar una prueba unitaria de Javascript fuera del entorno del navegador

Yo solo consiguió que Hudson CI ejecutara JasmineBDD (sin cabeza), al menos para pruebas unitarias de JavaScript puro.

(Hudson ejecuta Java a través de Shell, ejecuta Envjs, ejecuta JasmineBDD).

Sin embargo, todavía no he logrado que funcione bien con una biblioteca grande, como un prototipo.

Examinar Prueba YUIT

Estoy de acuerdo en que jsunit está muriendo en la vid.Acabamos de terminar de reemplazarlo con YUI Test.

De manera similar al ejemplo que usa qUnit, estamos ejecutando las pruebas usando Selenium.Estamos ejecutando esta prueba independientemente de nuestras otras pruebas de selenio simplemente porque no tiene las dependencias que tienen las pruebas de regresión de UI normales (p. ej.implementar la aplicación en un servidor).

Para comenzar, tenemos un archivo javascript base que se incluye en todos nuestros archivos html de prueba.Esto maneja la configuración de la instancia YUI, el ejecutor de pruebas, el objeto YUI.Test.Suite y Test.Case.Tiene métodos a los que se puede acceder a través de Selenium para ejecutar el conjunto de pruebas, verificar si el ejecutor de pruebas todavía se está ejecutando (los resultados no están disponibles hasta que finalice) y obtener los resultados de la prueba (elegimos el formato 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 cuanto al lado del selenio, utilizamos una prueba parametrizada.Ejecutamos nuestras pruebas tanto en IE como en FireFox en el método de datos, analizando los resultados de la prueba en una lista de matrices de objetos y cada matriz contiene el nombre del navegador, el nombre del archivo de prueba, el nombre de la prueba, el resultado (aprobado, fallado o ignorado). y el mensaje.

La prueba real simplemente afirma el resultado de la prueba.Si no es igual a "aprobar", entonces no pasa la prueba con el mensaje devuelto por el resultado de la prueba 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));
    }
}

Espero que esto sea útil.

Hay un nuevo proyecto que te permite ejecutar. qunitar pruebas en un entorno Java (como ant) ​​para que pueda integrar completamente su conjunto de pruebas del lado del cliente con sus otras pruebas unitarias.

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

Lo he usado para realizar pruebas unitarias de complementos de jQuery, objx Código, JavaScript OO personalizado y funciona para todo sin modificaciones.

El proyecto en el que estoy trabajando utiliza Controlador de prueba Js alojamiento Jazmín en Chrome 10 con Adaptador Jasmine-JSTD incluyendo hacer uso de Cobertura de código pruebas incluidas en JS-Test-Driver.Si bien existen algunos problemas cada vez que cambiamos o actualizamos los navegadores en el entorno de CI Las pruebas de Jasmine se están ejecutando bastante bien con solo problemas menores con las pruebas anincrónicas, pero hasta donde yo sé, estos se pueden solucionar usando Jasmine Clock, pero aún no he tenido la oportunidad de parchearlos.

He publicado un pequeña biblioteca para verificar pruebas de JavaScript dependientes del navegador sin tener que utilizar un navegador.Es un módulo de node.js que usa zombie.js para cargar la página de prueba e inspeccionar los resultados.He escrito sobre eso en mi blog.Así es como se ve la automatización:

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();
        }
    });
});

});

Miré la fecha de su pregunta y en aquel entonces había algunas buenas bibliotecas/marcos de prueba de JS.Hoy puedes encontrar mucho más y en diferentes enfoques como TDD, BDD, Assetion y con/sin soporte de corredores.

Hay muchos jugadores en este juego como Mocha, Chai, QUnit, Jasmine, etc...Puedes encontrar más información en este blog sobre JS/Mobile/pruebas web...

Otro marco de prueba JS que se puede ejecutar con Ant es Verificar por distintos modos.Hay un ejemplo de ejecución de CrossCheck a través de Ant en el archivo de compilación del proyecto.

CrossCheck intenta, con éxito limitado, emular un navegador, incluidas implementaciones de estilo simulado de XMLHttpRequest y tiempo de espera/intervalo.

Sin embargo, actualmente no maneja la carga de JavaScript desde una página web.Debe especificar los archivos javascript que desea cargar y probar.Si mantiene todo su JS separado de su HTML, podría funcionar para usted.

He escrito una tarea Ant que usa Fantasma JS, un navegador webkit sin cabeza, para ejecutar archivos de prueba html de QUnit dentro de un proceso de compilación Ant.También puede fallar la compilación si falla alguna prueba.

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

Esta es una buena evaluación de varias herramientas de prueba.

Herramientas de prueba unitaria de JavaScript para TDD

yo personalmente prefierohttps://code.google.com/p/js-test-driver/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top