unitarias - test unitarios javascript
Pruebas unitarias automatizadas con JavaScript (14)
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.
Acabo de conseguir Hudson CI para ejecutar JasmineBDD (sin cabeza), al menos para pruebas de unidad de JavaScript puro.
(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.
El proyecto en el que estoy trabajando usa js-test-driver aloja Jasmine en Chrome 10 con Jasmine-JSTD-Adapter incluido el uso de las pruebas de Cobertura de código 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 ejecutan sin problemas con solo problemas menores con las pruebas ansincrónicas, pero hasta donde sé, se pueden solucionar utilizando el reloj Jasmine, pero no lo he logrado. Tuve la oportunidad de parchearlos todavía.
Esta es una buena evaluación de varias herramientas de prueba.
Herramientas de prueba de unidad de JavaScript para TDD
Personalmente prefiero https://code.google.com/p/js-test-driver/
Estoy a punto de comenzar a hacer Javascript TDD en un nuevo proyecto en el que estoy trabajando. Mi plan actual es usar qunit para hacer 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 para garantizar que las pruebas se ejecuten en todos los navegadores), Selenium para cargar automáticamente el arnés de prueba en cada navegador y leer el resultado. Estas pruebas se ejecutarán en cada checkin para controlar la fuente.
También 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:
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 realizando 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<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 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
);
}
Y sí, JsUnit maneja tiempos de espera: simulando tiempo en pruebas jsUnit
Hay un nuevo proyecto que le permite ejecutar pruebas de qunit en un entorno Java (como hormiga) 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 probar unidades jQuery plugins, código objx , JavaScript OO personalizado y funciona para todo sin modificaciones.
He escrito una tarea Ant que utiliza Phantom JS , un navegador webkit sin cabeza, para ejecutar archivos de prueba hnml QUnit dentro de un proceso de compilación Ant. También puede fallar la construcción si falla alguna prueba.
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. He escrito sobre esto 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é 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 ... Puedes encontrar más información en this blog sobre JS / Mobile / web testing ...
Mire en YUITest
Otro marco de prueba 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.
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
Soy un gran fan de js-test-driver
Funciona bien en un entorno de CI y es capaz de capturar navegadores reales para realizar pruebas entre navegadores.