Pruebas unitarias automatizadas con JavaScript

Intento incorporar algunas pruebas de unidades de JavaScript en mi proceso de compilación automatizado. Actualmente, JSUnit funciona bien con JUnit, pero parece ser abandono y carece de un 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 el DOH de Dojo es que requiere que use sus propias llamadas a función AJAX y controladores de eventos para trabajar con cualquier prueba de unidad AJAX.

0
agregado editado
Puntos de vista: 2
agregado el autor Jacques Bosch, fuente

14 Respuestas

Recientemente leí un artículo de Bruno usando JsUnit y creando un framework JsMock además de eso ... muy interesante. Estoy pensando en usar su trabajo para comenzar la prueba unitaria de mi código Javascript.

Simulacro de Javascript o prueba de unidad de Javascript fuera del entorno del navegador

0
agregado

Hay muchos marcos de prueba de unidades de JavaScript disponibles (jsUnit, scriptaculous, ...) pero jsUnit es el único que conozco que se puede usar con una versión automatizada.

Si está realizando una prueba de unidad "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
); }

And yes, JsUnit do handle timeouts : Simulating Time in jsUnit Tests

0
agregado

Look into YUITest

0
agregado

He publicado una pequeña biblioteca para verificar las pruebas de JavaScript dependientes del navegador sin tener que usar un navegador. Es un módulo node.js que usa zombie.js para cargar la página de prueba e inspeccionar los resultados. Escribí al respecto 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();
        }
    });
});

});
0
agregado

Miré en la fecha de su pregunta y en aquel entonces había algunas buenas pruebas de JS lib/framework. 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 ... Puede encontrar más información en este blog sobre pruebas de JS/Mobile/web ...

0
agregado

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

CrossCheck intenta, con un éxito limitado, emular un navegador, incluidas las implementaciones de estilo simulado de XMLHttpRequest y timeout/interval.

Sin embargo, actualmente no se encarga de cargar 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.

0
agregado

Estoy a punto de comenzar a hacer Javascript TDD en un nuevo proyecto en el que estoy trabajando. Mi plan actual es utilizar qunit 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 asegurar que las pruebas se ejecuten en todos los navegadores), usaré Selenium para cargar automáticamente el arnés de prueba en cada navegador, y lea el resultado. Estas pruebas se ejecutarán en cada checkin para controlar la fuente.

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

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


Herramientas de prueba:

0
agregado
sí, por favor compártelo. Gracias
agregado el autor melaos, fuente
Obtuve esta configuración, pero usando tecnologías ligeramente diferentes. Usé JS Test Driver para ejecutar las pruebas unitarias en cada navegador (en lugar de Selenium), usando el adaptador QUnit ( code.google.com/p/js-test-driver/wiki/QUnitAdapter ). Otra en mi empleador actual. Estoy usando el marco de prueba de Jasmine y ejecutando las pruebas en el nodo Jasmine ( github.com/mhevery/jasmine-node ) que evita el
agregado el autor Karl, fuente
casi el mejor uso de selenio. hombre, he perdido mucho tiempo con esa cosa. gruñir gruñir ...
agregado el autor the0ther, fuente
¿Alguna vez tienes esta configuración? ¿Como le fue?
agregado el autor El Yobo, fuente
Hola @ Karl. También encontré qunit como una herramienta útil, pero no sé exactamente qué probar. Tengo una lógica de juego escrita en JavaScript con combinaciones, animaciones. ¿Me pueden ayudar con algo de información? Gracias.
agregado el autor Anahit Ghazaryan, fuente

Im a big fan of js-test-driver

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

0
agregado
Me gusta por la integración de CI, pero creo que su mejor punto es que funciona con YUITest y QUnit.
agregado el autor AutomatedTester, fuente

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

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 IU normales (por ejemplo, implementar la aplicación en un servidor).

Para comenzar, tenemos un archivo base JavaScript que está incluido en todos nuestros archivos html de prueba. Esto maneja la configuración de la instancia de YUI, el corredor de prueba, el objeto YUI.Test.Suite y el Test.Case. Tiene un método al que se puede acceder a través de Selenium para ejecutar el banco de pruebas, verifica si el corredor de prueba aún se está ejecutando (los resultados no están disponibles hasta después de hacerlo) 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 de las cosas, utilizamos una prueba parametrizada. Ejecutamos nuestras pruebas en IE y FireFox en el método de datos, analizando los resultados de la prueba en una lista de matrices de objetos con cada matriz conteniendo el nombre del navegador, el nombre del archivo de prueba, el nombre de prueba, el resultado (pase, falla o ignora) y el mensaje.

La prueba real solo afirma el resultado de la prueba. Si no es igual a "aprobar", falla la prueba con el mensaje devuelto por el resultado de la Prueba YUI.

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

    List testResults = new ArrayList(); pageNames = new ArrayList(); 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 runJSTestsInBrowser(Browser aBrowser) { String yui_test_codebase = "file:///c://myapppath/yui/tests/"; String browser_bot = "this.browserbot.getCurrentWindow()" List testResults = new ArrayList(); 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.

0
agregado

Acabo de obtener Hudson CI para ejecutar JasmineBDD (sin cabeza), en al menos para pruebas puras de javascript.

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

Sin embargo, todavía no lo tengo para jugar bien con una gran biblioteca, como un prototipo.

0
agregado

Hay un nuevo proyecto que le permite ejecutar pruebas de qunit en un entorno Java (como hormiga) para que pueda integrarse por completo su suite de pruebas del lado del cliente con sus otras pruebas unitarias.

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

Lo he usado para probar los complementos jQuery, el código objx , el JavaScript OO personalizado y funciona para todo sin modificaciones.

0
agregado

El proyecto en el que estoy trabajando utiliza Js-Test-Driver hosting Jasmine en Chrome 10 con Jasmine-JSTD-Adapter , incluido el uso de Code Coverage pruebas incluidas en JS-Test-Driver. Si bien hay algunos problemas cada vez que cambiamos o actualizamos navegadores en el entorno de CI , las pruebas de jazmín se están ejecutando. sin problemas, solo con pequeños problemas con las pruebas ansincrónicas, pero hasta donde yo sé, se pueden solucionar con el uso de Jasmine Clock, pero aún no he tenido la oportunidad de parchearlos.

0
agregado

He escrito una tarea Ant que utiliza Phantom JS , un navegador webkit sin cabeza, para ejecutar archivos de prueba hnml html dentro de una hormiga proceso de construcción. También puede fallar la construcción si falla alguna prueba.

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

0
agregado

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

Herramientas de prueba de unidades de JavaScript para TDD

I personally prefer https://code.google.com/p/js-test-driver/

0
agregado