Prueba de JavaScript con PhantomJS

No creo que deba convencerte de que probar tu código JavaScript es una buena idea. Pero, a veces puede resultar tedioso probar el código JavaScript que requiere un DOM. Esto significa que necesita probar su código en el navegador y no puede usar el terminal, ¿verdad? Mal, en realidad: entrar en PhantomJS.


¿Qué es exactamente PhantomJS? Bueno, aquí hay un anuncio del sitio web de PhantomJS:

PhantomJS es un WebKit sin cabeza con API de JavaScript.

Como usted sabe, Webkit es el motor de diseño que utilizan Chrome, Safari y algunos otros navegadores de nicho. Así que PhantomJS es un navegador, pero un navegador sin cabeza. Esto significa que las páginas web renderizadas nunca se muestran realmente. Esto puede sonar extraño para ti; para que pueda pensar en él como un navegador programable para el terminal. Veremos un ejemplo simple en un minuto, pero primero necesitamos instalar PhantomJS.


Instalando PhantomJS

Instalar PhantomJS es en realidad bastante simple: es solo un binario único que descarga y mantiene en la ruta de su terminal. En la página de descarga de PhantomJS, elija su sistema operativo y descargue el paquete correcto. Luego mueva el archivo binario del paquete descargado a un directorio dentro de la ruta de su terminal (me gusta poner este tipo de cosas en ~ / bin).

Si estás en Mac OS X, hay una forma más sencilla de instalar PhantomJS (y este es en realidad el método que utilicé). Solo usa Homebrew, así:

actualización de brew && brew install phantomjs

Ahora debería tener instalado PhantomJS. Puedes revisar tu instalación ejecutando esto:

phantomjs --version

Estoy viendo 1.7.0; tú?


Un pequeño ejemplo

Empecemos con un pequeño ejemplo..

simple.js
console.log ("podemos cerrar sesión"); función add (a, b) return a + b;  conslole.log ("También podemos ejecutar JS regular:", add (1, 2)); phantom.exit ();

Continúe y ejecute este código emitiendo el siguiente comando:

phantomjs simple.js

Debería ver la salida de los dos console.log líneas en su ventana de terminal.

Claro, esto es simple, pero es un buen punto: PhantomJS puede ejecutar JavaScript como un navegador. Sin embargo, este ejemplo no tiene ningún código específico de PhantomJS ... bueno, aparte de la última línea. Esa es una línea importante para cada script PhantomJS porque sale del script. Esto podría no tener sentido aquí, pero recuerde que JavaScript no siempre se ejecuta linealmente. Por ejemplo, es posible que desee poner el salida() llamar en una función de devolución de llamada.

Veamos un ejemplo más complejo..


Cargando paginas

Usando la API de PhantomJS, podemos cargar cualquier URL y trabajar con la página desde dos perspectivas:

  • como JavaScript en la página.
  • como usuario mirando la pagina.

Comencemos eligiendo cargar una página. Cree un nuevo archivo de script y agregue el siguiente código:

script.js
var page = require ('página web'). create (); page.open ('http://net.tutsplus.com', función (es) console.log (s); phantom.exit (););

Comenzamos cargando PhantomJS ' página web Módulo y creación de un objeto de página web. Entonces llamamos al abierto Método, pasándole una URL y una función de devolución de llamada; Es dentro de esta función de devolución de llamada que podemos interactuar con la página real. En el ejemplo anterior, simplemente registramos el estado de la solicitud, proporcionado por el parámetro de la función de devolución de llamada. Si ejecuta este script (con phantomjs script.js), debe obtener el "éxito" impreso en el terminal.

Pero hagamos esto más interesante cargando una página y ejecutando algo de JavaScript en ella. Comenzamos con el código anterior, pero luego hacemos una llamada a página.evaluar:

page.open ('http://net.tutsplus.com', function () var title = page.evaluate (function () var posts = document.getElementsByClassName ("post"); posts [0] .style. backgroundColor = "# 000000"; return document.title;); page.clipRect = top: 0, left: 0, width: 600, height: 700; page.render (title + ".png"); phantom .salida(); );

PhantomJS es un navegador, pero un navegador sin cabeza.

La función a la que pasamos página.evaluar Se ejecuta como JavaScript en la página web cargada. En este caso, encontramos todos los elementos con el enviar clase; Luego, configuramos el fondo del primer post en negro. Finalmente, devolvemos el titulo del documento. Esta es una buena característica, devolviendo un valor de nuestro evaluar devolución de llamada y asignándolo a una variable (en este caso, título).

Entonces, establecemos la clipRect en la pagina; Estas son las dimensiones para la captura de pantalla que tomamos con el hacer método. Como puedes ver, configuramos el parte superior y izquierda valores para establecer el punto de partida, y también establecemos una anchura y altura. Finalmente, llamamos page.render, pasándole un nombre para el archivo título variable). Entonces, terminamos llamando phantom.exit ().

Continúa y ejecuta este script, y deberías tener una imagen que se parece a esto:

Puede ver las dos caras de la moneda de PhantomJS aquí: podemos ejecutar JavaScript desde dentro de la página, y también ejecutar desde el exterior, en la propia instancia de la página..

Esto ha sido divertido, pero no increíblemente útil. Centrémonos en usar PhantomJS al probar nuestro JavaScript relacionado con DOM.


Pruebas con PhantomJS

Yeoman usa PhantomJS en su procedimiento de prueba, y es virtualmente sin problemas.

Para una gran cantidad de código JavaScript, puede realizar pruebas sin necesidad de un DOM, pero hay ocasiones en que sus pruebas necesitan trabajar con elementos HTML. Si eres como yo y prefieres ejecutar pruebas en la línea de comandos, aquí es donde PhantomJS entra en juego..

Por supuesto, PhantomJS no es una biblioteca de prueba, pero muchas de las otras bibliotecas de prueba populares pueden ejecutarse sobre PhantomJS. Como puede ver en la página wiki de PhantomJS en las pruebas sin cabeza, los corredores de prueba de PhantomJS están disponibles para casi todas las bibliotecas de pruebas que desee utilizar. Veamos cómo usar PhantomJS con Jasmine y Mocha.

Primero, Jasmine y un descargo de responsabilidad: en este momento no hay un buen corredor de PhantomJS para Jasmine. Si usas Windows y Visual Studio, deberías revisar Chutzpah, y los desarrolladores de Rails deberían probar con guard-jasmine. Pero aparte de eso, el soporte de Jasmine + PhantomJS es escaso.

Por esta razón, te recomiendo que uses Mocha para las pruebas relacionadas con DOM.

SIN EMBARGO.

Es posible que ya tenga un proyecto con Jasmine y desee utilizarlo con PhantomJS. Un proyecto, phantom-jasmine, requiere un poco de trabajo para configurar, pero debería hacer el truco..

Vamos a empezar con un conjunto de pruebas de JasmineJS. Descargue el código para este tutorial (enlace en la parte superior), y revise el iniciador de jazmín carpeta. Verás que tenemos una sola. tests.js Archivo que crea un elemento DOM, establece algunas propiedades y lo agrega al cuerpo. Luego, realizamos algunas pruebas de Jasmine para asegurarnos de que el proceso funcionó correctamente. Aquí está el contenido de ese archivo:

tests.js
describe ("DOM Tests", function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Hola!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); (" está en el DOM ", function () expect (myEl) .not.toBeNull ();); it ("es un elemento secundario del cuerpo", function () expect (myEl.parentElement) .toBe (document.body);); it ("tiene el texto correcto", function () expect (myEl.innerHTML ) .toEqual ("Hola!");); ("tiene el fondo correcto", función () esperar (myEl.style.background) .toEqual ("rgb (204, 204, 204)"); ););

los SpecRunner.html archivo es bastante stock; la única diferencia es que moví las etiquetas de secuencia de comandos al cuerpo para garantizar que el DOM se carga completamente antes de que se ejecuten nuestras pruebas. Puede abrir el archivo en un navegador y ver que todas las pruebas pasan bien..

Transicionemos este proyecto a PhantomJS. En primer lugar, clona el proyecto phantom-jasmine:

git clone git: //github.com/jcarver989/phantom-jasmine.git

Este proyecto no está tan organizado como podría ser, pero hay dos partes importantes que necesita de él:

  • el corredor PhantomJS (que hace que Jasmine use un DOM PhantomJS).
  • El reportero de la consola Jasmine (que da la salida de la consola).

Ambos archivos residen en el lib carpeta; copiarlos en iniciador de jazmín / lib. Ahora necesitamos abrir nuestro SpecRunner.html archivar y ajustar el

Observe que tenemos dos reporteros para nuestras pruebas: un reportero de HTML y un reportero de consola. Esto significa SpecRunner.html y sus pruebas pueden ejecutarse tanto en el navegador como en la consola. Eso es práctico. Desafortunadamente, necesitamos tener eso console_reporter variable porque se usa dentro del archivo CoffeeScript que estamos a punto de ejecutar.

Entonces, ¿cómo hacemos para ejecutar estas pruebas en la consola? Suponiendo que estás en el iniciador de jazmín carpeta en el terminal, aquí está el comando:

phantomjs lib / run \ _jasmine \ _test.coffee ./SpecRunner.html

Estamos ejecutando el corre \ _jasmine \ _test.coffee Guión con PhantomJS y pasando nuestro SpecRunner.html Archivo como parámetro. Debería ver algo como esto:

Por supuesto, si una prueba falla, verá algo como lo siguiente:

Si planea usar esto a menudo, podría ser una buena idea mudarse corre \ _jasmine \ _test.coffee a otra ubicación (como ~ / bin / run \ _jasmine \ _test.coffee) y crea un alias de terminal para todo el comando. Así es como lo harías en un shell Bash:

alias phantom-jasmine = "phantomjs /path/to/run\_jasmine\_test.coffee"

Solo tira eso en tu .Bashrc o .bash_profile expediente. Ahora, solo puede ejecutar:

phantom-jasmine SpecRunner.html

Ahora sus pruebas de Jasmine funcionan bien en el terminal a través de PhantomJS. Puedes ver el código final en el jazmín total carpeta en la descarga.


PhantomJS y Mocha

Afortunadamente, es mucho más fácil integrar Mocha y PhantomJS con mocha-phantomjs. Es súper fácil de instalar si tiene instalado NPM (que debería):

npm instalar -g mocha-phantomjs

Este comando instala un mocha-phantomjs Binario que usaremos para ejecutar nuestras pruebas..

En un tutorial anterior, te mostré cómo usar Mocha en el terminal, pero harás las cosas de manera diferente cuando lo uses para probar el código DOM. Al igual que con Jasmine, comenzaremos con un reportero de prueba HTML que puede ejecutarse en el navegador. La belleza de esto es que podremos ejecutar ese mismo archivo en el terminal para los resultados de las pruebas de consola con PhantomJS; como pudimos con Jasmine.

Entonces, vamos a construir un proyecto simple. Cree un directorio de proyecto y muévase en él. Comenzaremos con un paquete.json expediente:

"name": "project", "version": "0.0.1", "devDependencies": "mocha": "*", "chai": "*"

Mocha es el marco de prueba y usaremos Chai como nuestra biblioteca de afirmaciones. Los instalamos ejecutando NPM.

Llamaremos a nuestro archivo de prueba test / tests.js, Y aquí están sus pruebas:

describe ("DOM Tests", function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Hola!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); (" está en el DOM ", function () expect (myEl) .to.not.equal (null); ); it ("es un elemento secundario del cuerpo", function () expect (myEl.parentElement) .to.equal (document.body);); it ("tiene el texto correcto", function ()  expect (myEl.innerHTML) .to.equal ("Hi there!");); ("tiene el fondo correcto", function () expect (myEl.style.background) .to.equal ("rgb ( 204, 204, 204) ");););

Son muy similares a las pruebas de Jasmine, pero la sintaxis de la afirmación de Chai es un poco diferente (así que, no solo copie sus pruebas de Jasmine).

La última pieza del rompecabezas es la. TestRunner.html expediente:

   Pruebas     

Hay varios factores importantes aquí. Primero, observe que esto es lo suficientemente completo como para ejecutarse en un navegador; tenemos el CSS y JavaScript de los módulos de nodo que instalamos. Luego, note la etiqueta de script en línea. Esto determina si PhantomJS está cargado, y si es así, ejecuta la funcionalidad PhantomJS. De lo contrario, se queda con la funcionalidad Mocha en bruto. Puedes probar esto en el navegador y verlo funcionar..

Para ejecutarlo en la consola, simplemente ejecuta esto:

mocha-phantomjs TestRunner.html

Voila! Ahora estás ejecutando pruebas en la consola, y todo gracias a PhantomJS.


PhantomJS y Yeoman

Apuesto a que no sabías que el popular Yeoman usa PhantomJS en su procedimiento de prueba, y que es vitablemente impensable. Veamos un ejemplo rápido. Asumiré que tienes Yeoman todo configurado.

Crea un nuevo directorio de proyecto, ejecuta yeoman init Dentro de él, y responda 'No' a todas las opciones. Abre el prueba / index.html y encontrará una etiqueta de script en la parte inferior con un comentario que le indica que la reemplace con sus propias especificaciones. Ignore por completo ese buen consejo y ponga esto dentro del eso bloquear:

var el = document.createElement ("div"); expect (el.tagName) .to.equal ("DIV");

Ahora corre prueba de yeoman, y verás que la prueba funciona bien. Ahora abierto prueba / index.html archivo en el navegador. ¡Funciona! Perfecto!

Por supuesto, hay mucho más que puede hacer con Yeoman, así que consulte la documentación para obtener más información..


Conclusión

Utilice las bibliotecas que amplían PhantomJS para simplificar sus pruebas.

Si está utilizando PhantomJS por sí solo, no hay ninguna razón para aprender sobre PhantomJS; solo puede saber que existe y usar las bibliotecas que amplían PhantomJS para simplificar sus pruebas.

Espero que este tutorial te haya animado a mirar PhantomJS. Recomiendo comenzar con los archivos de ejemplo y la documentación que ofrece PhantomJS; realmente te abrirán los ojos a lo que puedes hacer con PhantomJS: todo desde la automatización de páginas hasta el rastreo de redes.

Asi que, puede ¿Piensas en un proyecto que PhantomJS mejoraría? Vamos a escucharlo en los comentarios.!