brainbaking/content/wiki/code/javascript/testing.md

6.1 KiB

+++ title = "testing" draft = false tags = [ "code", "javascript", "testing" ] date = "2013-03-12" +++

Testing JS Code

Testen schrijven

Klassieke Unit testen

Frameworks gebruiken zoals jQuery's QUnit die het makkelijk maken modulair te testen:

test("dit zou dat moeten doen blabla", function() {
  equal(expected, actual);
  ok(someThingExpectedToBeTrue);
});

Mocking van bijvoorbeeld $ mogelijk via MockMe, een door Mockito geïnspireerde Javascript Object spy API. Iets van:

when(f)('in').thenReturn('out');
assertEqual('out', f('in'));

Vereist Prototype JS, en JsUnit om de assert functions te kunnen gebruiken

Gedrag testen met Jasmine

Inspiratie van de Ruby community gehaald, met name RSpec-based.

Frameworks gebruiken zoals Jasmine ((Niet afhankelijk van andere JS Frameworks, vereist geen DOM dus geen Envjs nodig serverside!)):

describe("Rekenmasjien", function() {
  it("should add one number", function() {
    var calc = new Calc(0);
    expect(calc.increase()).toEqual(1);
  });
});

Krachten:

  • Schrijf code door expectations (Matchers vbs) op te bouwen, in dezelfde trand als FESTAssert.
  • Bundel expectations in een suite ("beschrijvend")
  • Schrijf makkelijk extenties om eigen expectation functions op te bouwen als de standaard API niet volstaat
  • beforeEach() en afterEach() functions binnen suites
  • Snel disablen van testen via xit() (@Ignore zogezegd)
  • mocking en spying heel eenvoudig mogelijk: zie https://github.com/pivotal/jasmine/wiki/Spies
  • Plugins voor reporting, custom matching, ...

Zwakheden:

  • Async testen vereist waitsFor() ea. Zie onder
  • Vereist specRunner.html files, standaard altijd in een browser runnen. Genereer specRunners!

Betere matchers speciaal voor jQuery ea zijn beschikbaar: https://github.com/velesin/jasmine-jquery

Aynschrone code testen

Zie [async]({{< relref "async.md" >}})

Jasmine integreren met jsTestDriver

Zie http://skaug.no/ingvald/2010/10/javascript-unit-testing.html

Er is een Jasmine adapter beschikbaar: https://github.com/ibolmo/jasmine-jstd-adapter

Het kan ook handig zijn om een Junit XML Reporter te gebruiken om bijvoorbeeld voor Hudson het makkelijker te maken om de test output files te verwerken. Er zijn reeds enkele reporter plugins zoals deze beschikbaar, hier: https://github.com/larrymyers/jasmine-reporters

Integratie met Hudson, EnvJS en Rhino ea: zie eigen junit test runner: https://github.com/jefklak/jasmine-junit-runner

Andere JS Test frameworks

Interessante links:

  1. http://tddjs.com/
  2. Stack overflow: Looking for a better Javascript unit test tool

Testen automatiseren

Distributed testing in-browser

jsTestDriver

http://code.google.com/p/js-test-driver/

Wat doet dit?

  • Een jar dat een server opstart die een browser bestuurt en bepaalde JS files (uw testen en uw productiecode) automatisch inlaadt en uitvoert
  • Bevat een API met asserts
  • Reportgeneratie met plugins voor eclipse om ze JUnit-like te tonen
  • Integratie met build etc mogelijk
  • Integratie met Jasmine mogelijk: https://github.com/ibolmo/jasmine-jstd-adapter

jsTestDriver integreren met Hudson

Zie http://cjohansen.no/en/javascript/javascript_continuous_integration_with_hudson_and_jstestdriver

Het komt eigenlijk hierop neer: maak een nieuw target, voer extern dit commando uit:

java -jar test/JsTestDriver-1.2.2.jar <br/>
  --config jsTestDriver.conf <br/>
  --server http://localhost:4223 
  --tests all --testOutput . --reset

Dit neemt aan dat de server reeds gestart is, kan met een shell script op de Hudson server bak: java -jar test/JsTestDriver-1.2.2.jar --port 4223.

JsUnit Server

http://www.jsunit.net/documentation/index.html

Wat doet dit?

  • Een jar dat een Jetty Server opstart die een browser bestuurt en bepaalde HTML files inlaadt en uitvoert, waar testen in zitten
  • Afhankelijk van Prototype JS om asserts uit te voeren
  • Integratie met ant zeer eenvoudig

TestSwarm

Zie http:*swarm.jquery.org/ en https:*github.com/jquery/testswarm/wiki

Headless testen

Mogelijkheid 1: EnvJS

EnvJS is een gesimuleerde browser omgeving geschreven in JS. Zie http://www.envjs.com/

Voordeel: heel snel

Nadeel: Java ofzoiets nodig om JS te evalueren (Rhino of V8 in C++ van Google), plus kan onregelmatigheden vertonen met hevig gebruik maken van UI frameworks -> dit zou moeten werken allemaal, maar het blijft een gesimuleerde omgeving.

Zie https://github.com/jefklak/jasmine-junit-runner

Integreren met hudson als extern commando:

java -cp lib/envjs/js.jar:lib/envjs/jline.jar org.mozilla.javascript.tools.shell.Main -opt -1 -f lib/envjs/envjs.bootstrap.js -f test.js

test.js heeft dan maar 1 regel die naar de juiste specRunner.html gaat met window.location.

Mogelijkheid 2: Qt Webkit widget

Webkit is een opensource web renderer, en er is een implementatie in Qt beschikbaar (vereist libs geïnstalleerd te hebben). Zie http://trac.webkit.org/wiki/QtWebKit

Voordeel: gedrag volledig in een "echte" website rendered, in plaats van via een omweg. Aangezien het een Qt Widget is, hoeft het niet expliciet op het scherm gerendered te worden (dit pollt gewoon totdat bvb "Jasmine tests run" ofzoiets van tekst verschijnt, om dan de HTML te retourneren als resultaat.

Nadeel: Qt libs vereist, nog altijd niet volledig "headless", aparte widget spec runner in de achtergrond die draait.

Zie http://johnbintz.github.com/jasmine-headless-webkit/ (Implementatie in Ruby met nogal veel nadruk op gems ea... Handig?)

Phantom JS is een full stack headless browser implementatie gebaseerd op WebKit (C++/Python implementatie).