2008-09-18 31 views
58

Estoy tratando de 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.Pruebas unitarias automatizadas con JavaScript

¿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.

+1

pregunta relacionada: http://stackoverflow.com/questions/300855/looking-for-a-better-javascript-unit-test-tool –

Respuesta

19

Hay muchos Javascript marco de prueba de unidad por ahí (jsUnit, scriptaculous, ...) pero jsUnit es el único que conozco que puede ser utilizado con una construcción automatizado.

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

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

Y sí, JsUnit qué manejar los tiempos de espera: Simulating Time in jsUnit Tests

0

Otro marco de pruebas de JS que puede ser 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.

Actualmente no se 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.

24

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 la prueba unitaria. 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 ejecutan en todos los navegadores), usaré 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 voy a utilizar JSCoverage para obtener el 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

sí, por favor compártelo. gracias – melaos

+0

¿Alguna vez se creó esta configuración? ¿Como le fue? –

+4

Obtuve esta configuración, pero usando tecnologías ligeramente diferentes. Utilicé JS Test Driver para ejecutar las pruebas unitarias en cada navegador (en lugar de Selenium), usando el Adaptador QUnit (http://code.google.com/p/js-test-driver/wiki/QUnitAdapter). Otra en mi empleador actual. Estoy utilizando el marco de prueba de Jasmine y estoy ejecutando las pruebas en el nodo de jazmín (http://github.com/mhevery/jasmine-node), lo que evita el retraso de usar un navegador. Uso mi propio pequeño proyecto ruby ​​(http://github.com/karl/loris) para ejecutar las pruebas en cada cambio. – Karl

13

Im un gran fan de js-test-driver

Funciona bien en un entorno de CI y es capaz de capturar los navegadores actuales para las pruebas de cross-browser.

+1

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

2

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

Al igual que en el ejemplo que utiliza qUnit, estamos ejecutando las pruebas con 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 javascript base que se incluye 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, 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 la prueba, el resultado (pase, falla o ignora) y el mensaje.

La prueba real solo confirma 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 sea útil.

4

Acabo de got Hudson CI to run JasmineBDD (sin cabeza), al menos para pruebas puras de javascript.

(Hudson ejecutar Java mediante el intérprete, corriendo Envjs, corriendo JasmineBDD.)

no tengo que jugar bien, con una gran biblioteca sin embargo, aunque, como prototipo.

1

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

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

Lo he utilizado para poner a prueba la unidad de plugins jQuery, objx código de encargo, OO JavaScript y funciona para todo, sin excepciones.

1

El proyecto que estoy trabajando sobre los usos de alojamiento Js-Test-DriverJasmine en Chrome 10 con Jasmine-JSTD-Adapter incluso haciendo uso de Code Coverage pruebas incluidas en el JS-piloto de pruebas. Si bien hay algunos problemas cada vez que cambiamos o actualizamos navegadores en el CI environment, las pruebas de jazmín se ejecutan bastante bien con solo problemas menores con las pruebas ansincrónicas, pero hasta donde sé, se pueden solucionar usando el Reloj Jasmine, pero no lo he logrado. Tuve la oportunidad de parchearlos todavía.

1

He publicado un little library 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 al respecto on my blog. Esto es lo que se ve como 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(); 
     } 
    }); 
}); 

}); 
1

que se veía en su fecha de pregunta y entonces había unos cuantos buena JS prueba lib/marco. Hoy puede 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, jazmín, etc ... Puede encontrar más información en algunos this blog sobre JS prueba/móvil/web ...

Cuestiones relacionadas