Sezon ogórkowy w pełni, dlatego i wpisy troszkę rzadziej niż zwykle, ale że u mnie w mieszkaniu remont to i urlop spędzam w domu i mogę nadrobić trochę zaległości… A w dzisiejszym wpisie temat, który często traktowany jest po macoszemu czyli testowanie JavaScript. O zaletach i konieczności testowania napisano już wiele, a jako profesjonalni programiści musimy wiedzieć, że dotyczy to nie tylko “backendu” ale i warstwy interfejsu użytkownika. Na całe szczęście, dzięki dostępnym narzędziom testowanie JavaScript nie jest wcale takie trudne!

Testy jednostkowe - jak to się robi w JavaScript

Zanim jednak przejdę do opisu frameworków, napisze kilka słów dla osób dla których testowanie JavaScript to kompletna nowość. Otóż, generalnie pisanie testów jednostkowych w JavaScript jest dość podobne do pisania takich testów w każdym innym języku. Spójrzmy na najbardziej podstawowy przykład ze strony projektu QUnit (omówienie tego frameworka w dalszej części wpisu):

QUnit.test('hello test', function(assert) {
    assert.ok(1 == '1', 'Passed!');
});

Jak widać, w przypadku QUnit udostępniana jest funkcja test, która jako drugi parametr przyjmuje funkcję wywołania zwrotnego. Do tego, funkcji tej przekazywany jest obiekt asercji, który możemy wykorzystać do przeprowadzenia testu (w powyższym przykładzie użyto funkcji ok ale dostępne są też inne funkcje asercji takie jak na przykład popularna equals).

Teraz aby wykonać test, wystarczy umieścić go w kodzie HTML. Jeśli otworzymy taką stronę w przeglądarce, test wykona się i naszym oczom ukaże się wynik testu:

QUnit - przykładowy wynik testu

Oczywiście to tylko “podstawowe podstawy” i opisywane frameworki mają dużo większe możliwości, jednak ogólna zasada pisania testów jednostkowych w JavaScript jest podobna we wszystkich narzędziach.

QUnit

Framework QUnitSkoro powyżej przytoczyłem już przykład związany z QUnit, to myślę że najlepiej będzie zacząć od opisu tego narzędzia. Za tym frameworkiem stoi zespół, który zajmuje się też rozwijaniem biblioteki jQuery. Od czasu jego utworzenia, framework ten rozwinął się na tyle, że stanowi teraz odrębne środowisko testowania inie wymaga do działania biblioteki jQuery.

Z założenia, środowisko QUnit zapewniaminimalistyczne API, które pozwala na pisanie testów jednostkowych w prosty sposób. Podstawowe cechy frameworka QUnit:

  • minimalistyczne i jednocześnie proste w użyciu API dzięki czemu jest jednym z najbardziej przyjaznych frameworków
  • możliwość testowania asynchronicznego
  • wsparcie dla uruchamiania testów w ramach Continous Integration
  • niezależność od jQuery i innych bibliotek
  • asercje zbudowane są na podstawie specyfikacji CommonJS Unit Testing (instalując bibliotekę SpecIt, mamy możliwość zamiany na notację typu “fluent”)
  • dostosowanie do testowania regresyjnego

Jasmine

Framework JasmineKolejnym popularnym środowiskiem wspierającym testowanie w języku JavaScript jest framework Jasmine. Jak piszą jego twórcy, nie zależy on od żadnego innego frameworka, nie jest też uzależniony od elementów DOM. Ponadto jest on stworzony do testowania każdego kodu JavaScript, a więc zarówno tego uruchamianego w przeglądarce jak i na serwerze, za pomocą na przykład node.js. Jest on skoncentrowany na testowaniu zachowania (Behaviour Driven). Wyróżnia się on składnią pisania testów, która jest dużo bardziej “fluent”. Zresztą spójrzmy na przykład:

describe('A suite', function() {
  it('contains spec with an expectation', function() {
    expect(true).toBe(true);
  });
});

Jak widać, API tego środowiska dość mocno różni się od tego dostępnego w QUnit. Stara się on przypominać język naturalny co moim zdaniem może powodować większą barierę wejścia, jednak po jego opanowaniu teoretycznie testy powinny być dużo bardziej zrozumiałe. Generalnie wydaje się, że jest to ostatnio dość modne podejście do budowania API…

Jasmine jest też, w porównaniu z QUnit, bardziej rozbudowanym frameworkiem, który zawiera wbudowane konstrukcje do obsługi “stubb’ów” i “mock’ów” (w przypadku QUnit, należy zastosować zewnętrzną bibliotekę by móc z nich skorzystać).

Mocha

Framework MochaOstatnim z omawianych dziś środowisk testowania jest Mocha. Framework ten w swojej filozofii jest dużo bardziejpodobny do Jasmine niż do QUnit. Tutaj również skoncentrowano się na testowaniu BDD oraz zastosowano notację typu “fluent”. Dużym plusem tego środowiska jest możliwość zastosowania dowolnej biblioteki odpowiedzialnej za budowanie asercji - jak podano na stronie projektu, znanymi bibliotekami, które bardzo dobrze współpracują z tym frameworkiem są: should.js, expect.js, chai oraz better-assert.

Poniżej lista najważniejszych cech środowiska Mocha:

  • dowolność wyboru biblioteki asercji
  • bardzo dobre i łatwe wsparcie dla testów asynchronicznych
  • oznaczanie wolno działających testów
  • możliwość ustawiania time-out’ów dla testów (również asynchronicznych)
  • raportowanie pokrycia testami
  • bardzo dobra integracja z node.js

I wiele innych - wszystkie funkcje wypisane zostały na stronie projektu, zresztą nic dziwnego skoro, tak jak tam napisano, jest to “feature-rich framework” :)

Testowanie JavaScript - podsumowanie

Oczywiście dzisiejszy wpis to tylko “liźnięcie” tematu testów jednostkowych w języku JavaScript. Ten krótki przegląd dostępnych narzędzi pokazuje jednak, że jest to zagadnienie dobrze wspierane przez frameworki i cały czas się rozwija. Zamiast więc tworzyć własne środowisko testowania, możemy skupić się na tworzeniu testów. Oczywiście dostępnych narzędzi jest dużo więcej, niektóre z nich możemy wykorzystywać łącznie, dlatego myślę, że każdy jest w stanie znaleźć framework odpowiedni do swoich potrzeb.

P.S. W kolejnych wpisach możecie znaleźć kurs testowania w Jasmine. Poniżej linki do poszczególnych odcinków “kursu”: