Scriptia. Javascript y buenas prácticas en español



Scriptia / al margen

Saltar a Acerca de Scriptia

jShoulda y JsUnitTest, pruebas unitarias en JavaScript al estilo Shoulda

Hablábamos el otro día de QUnit, hoy hablaremos de JsUnitTest –otro sistema de testing– y de jShoulda, una capa de abstracción que un servidor ha moldeado con sus propias manos y a imagen y semejanza de Shoulda.

Principiemos hablando de JsUnitTest, un port sin dependencias del sistema de testing desarrollado para probar prototype y script.aculo.us.

¿Qué necesitamos?

  • jsunittest.js, la biblioteca de testing;
  • un documento HTML que la referencie.

Algo como esto bastará:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>Minimal JsUnitTest</title>
  <script src="/js/jsunittest.js" type="text/javascript"></script>
  <link rel="stylesheet" href="/css/unittest.css" type="text/css" media="screen"/>
</head>

<body>
  <h1>Minimal JsUnitTest</h1>

  <div id="testlog">
    Los resultados de las pruebas se muestran, por defecto
    en el elemento con id=testlog
  </div>

<script type="text/javascript">
  // aquí irá el código de nuestras pruebas,
  // también podemos hacer referencia a un script externo
</script>

</body>
</html>

Cómo escribir tests con JsUnitTest

Para definir y ejecutar las pruebas, creamos una instancia de Test.Unit.Runner:

new Test.Unit.Runner({});

En el objeto de configuración que pasamos como argumento, definimos como propiedades las pruebas a realizar:

new Test.Unit.Runner({
  testNombreDelTest : function() {
    this.assert(true);
  },
  testOtroTest : function() {
    this.assert(true);
  }
});

Los nombres de las propiedades correspondientes a pruebas deben comenzar por “test”. Si deseamos ejecutar funciones de preparación y limpieza antes y después de cada una de las pruebas, utilizamos las propiedades setup y teardown para definirlas:

new Test.Unit.Runner({
  setup : function() {
    this.foo = 1;
  },
  testNombreDelTest : function() {
    this.assert(true);
  },
  testFoo : function() {
    this.assertEqual(1, this.foo);
  }
});

Observa: tanto las funciones de preparación como las de prueba se ejecutan en el contexto de una instancia de Test.Unit.Testcase. Las posibles aserciones son métodos de dicha instancia (por eso usamos this). También podemos utilizar this para mantener variables que vayamos a utilizar en nuestras pruebas.

La mayor parte de los métodos asertivos aceptan tres parámetros: el valor esperado, el valor real y (opcionalmente) un mensaje que el sistema nos mostrará en caso de error.

He aquí una lista deliberadamente incompleta de los métodos de aserción:

  • assert
  • assertEqual
  • assertNotEqual
  • assertEnumEqual
  • assertEnumNotEqual
  • assertHashEqual
  • assertHashNotEqual
  • assertIdentical
  • assertNotIdentical
  • assertNull
  • assertNotNull
  • assertUndefined
  • assertNotUndefined

Comprueban lo que su nombre parece indicar. Un detalle importante: en JavaScript, dos arrays con el mismo contenido (o dos objetos-usados-como-hashes) no pueden compararse mediante igualdad. Por tanto, si quieres comparar dos arrays necesitarás utilizar assertEnumEqual. Y para comparar dos objetos, assertHashEqual.

Automatización

drnic, el humano detrás de JsUnitTest, es también padre de newjs, un gem (si no sabes qué es un gem, ignora esta sección hasta que lo averigües) pensada para facilitar el desarrollo de bibliotecas JavaScript. Sus virtudes:

  • incluye JsUnitTest;
  • simplifica la creación de nuevos tests;
  • automatiza la ejecución de los tests.

Sin entrar en detalles. O lo ves, o no lo ves:

$ newjs milib
      create
      create  config
      create  lib
      create  src
      create  script
      create  tasks
      create  test/assets
      create  test/unit
      create  test/functional
      create  test/assets/unittest.css
      create  test/assets/jsunittest.js
      # etcetera
  dependency  install_rubigen_scripts
      exists    script
      create    script/generate
      create    script/destroy
$ cd milib
$ script/generate unit_test basic
      exists  test/unit
      create  test/unit/basic_test.html
$ rake test_units
(in /Users/choan/Current/tirame/milib)

Started tests in Safari
.
Finished in 2 seconds.
1 tests, 1 assertions, 0 failures, 0 errors

Started tests in Firefox
.
Finished in 1 seconds.
1 tests, 1 assertions, 0 failures, 0 errors

Skipping Internet Explorer, not supported on this OS

Skipping Konqueror, not supported on this OS

Started tests in Opera
.
Finished in 3 seconds.
1 tests, 1 assertions, 0 failures, 0 errors

Sí, amigo mío, mediante la ejecución de una tarea rake hemos ejecutado las pruebas en cada uno de los navegadores disponibles en nuestro sistema y hemos recogido los resultados. Algo que Chuck Norris no es capaz de hacer.

jShoulda

Pero vayamos con jShoulda, que yo he venido aquí a hablar de mi libro.

jShoulda es una capa de abstracción para JsUnitTest que permite escribir nuestros tests al más puro estilo Shoulda. Algo así:

context('A context', {},
  should('run a test', function() {
    this.assert('Yay!');
  }),
)();

¿Y qué ventaja tiene esto? Para un test vulgar, ninguna, francamente. Pero si tus pruebas requieren de inicializaciones complejas, la cosa se pone chula.

context('A context', {
  setup: function() {
    this.foo = 1;
  }
  },
  should('run its setup function', function() {
    this.assertEqual(1, this.foo);
  }),
  context('which is a "nested" context', {
    setup: function() {
      this.foo +=1;
    }
    },
    should('run both setup functions', function() {
      this.assertEqual(2, this.foo);
    })
  )
)();

Para utilizar jShoulda necesitas… jshoulda.js. Y un documento HTML como el anterior, al que añadirás la referencia a la biblioteca.

Pero para probarlo no necesitas descargar nada. Pásate por la página del proyecto. Los resultados de pruebas que encontrarás en ella (suponiendo que la visites con JavaScript activado) corresponden al test de ejemplo ejecutado en vivo. Si quieres juguetear, doblecliquea en el código, modifícalo a tu gusto y pulsa el botón. Sugerencia: haz fallar las pruebas. Mola.

Si estás interesado en jShoulda y tu inglés no es ni mejor ni peor que el mío, lee el tutorial de jShoulda, suscríbete a la lista de correo y, si das con algún bug, arréglalo.

Taller de jQuery en The Cocktail el 29 de mayo

Los muchachos de The Cocktail me han invitado a impartir un taller de jQuery en The Cocktail Academy.

Será el jueves 29 de mayo de 2008, a partir de las las 19.30h en los locales de Salamanca, 17 (Madrid). Si piensas asistir (es gratis), inscríbete cuanto antes en el wiki de los talleres.

Una pista de por donde irán los tiros. Hablaremos de:

  • selección de elementos, filtrado, etc.;
  • eventos a fondo, incluyendo delegación de eventos y sus ventajas;
  • navegación por el DOM;
  • algún que otro truquito de lo más chachipiruli.

Y por supuesto, de algunas razones para usar (o no usar) jQuery.

Después del taller, estáis todos invitados a pagarme unas cañas.

Embellecedor de código javascript

¿Diste con un código que te gustaría estudiar y está compactado en una línea? Beautify Javascript reformatea cualquier cosa para convertirla en algo legible.

Visto en Sentido web.

Los locos locos eventos de teclado

En lo que hace a eventos, los navegadores suelen ir a su bola. Y en lo que hace a eventos de teclado, el caos es absoluto: hay quien notifica las teclas modificadores en keypress, hay quien no; cada navegador es un mundo en cuanto a códigos de tecla… y dos o tres pesadillas más.

En JavaScript Madness: Keyboard Events, Jan Wolter documenta para uso y disfrute público todas las divergencias que se va encontrando.

Un patrón de desarrollo de plugins para jQuery

Mike Alsup, autor de jQuery form plugin y otras delicias, nos explica cómo crear un plugin para jQuery que cumpla con las condiciones de: no contaminar el espacio de nombres, acepte opciones (y las extienda), mantenga los límites adecuados entre lo público y lo privado y saque provecho del plugin de metadatos. Ahí es nada: A Plugin Development Pattern.

jQuery UI y jQuery 1.2.1

Llega jQuery UI, una colección de componentes reusables y de alta calidad: jQuery UI: Interactions and Widgets.

Y también la versión 1.2.1 de jQuery, con algunas correcciones de bugs sobre la 1.2.

Chuleta de jQuery

Adrien Gibrat ha tenido a bien crear y compartir una chuletita de jQuery (PDF).

Herramientas de desarrollo web para Internet Explorer

John Hrvatin presenta en IE Blog una serie de herramientas que pueden ser útiles cuando la fase de desarrollo llega al temible punto denominado «consigue que funcione en Internet Explorer». Alguna son gratuitas, otras no. Échenle un vistazo a Web Development Tools for Internet Explorer.

Adiós a las fugas de memoria

¡Bendita sea la hora! Microsoft ha lanzado hace unos días un parche para Internet Explorer 6 (sobre Windows XP) que mejora la liberación de memoria de su motor JScript. Parece que por fin los de Redmond abandonan su excusa del «código mal escrito» y corrigen, aunque siete años tarde, uno de los problemas más puñeteros que este navegador traía de serie. La parte mala: no hay fix para Windows 2000. La parte peor: no hay más mejoras.

Internet Explorer y el elemento button

aNieto2k se pregunta por qué no utilizamos más el elemento button. Kevin Hale, en Rediscovering the Button Element y Alex Griffioen en How to make sexy buttons with CSS nos cuentan cómo pintar botones bonitos (bonitos según ellos, claro). Y yo me pregunto ¿es que nadie se ha dado cuenta de que button no funciona correctamente en Internet Explorer?

Tenía previsto escribir un artículo sobre el tema, pero otra vez se me han adelantado: con ustedes Button Hell, por Roman Radaschütz.

Acerca de Scriptia

Saltar a la caja de búsqueda

Scriptia forma parte del PDM de Choan C. Gálvez, desarrollador web residente en Barcelona. Scriptia pretende mejorar la calidad de la documentación acerca de javascript disponible en español.