W dobie zmian, jakie zachodzą w światku programistycznym, nieodzowną potrzebą staje się znajomość JavaScriptu jako podstawowej platformy do wytwarzania oprogramowania. JavaScript może wydawać się trochę chaotyczną technologią (przez niektórych wykorzystywaną tylko do dodawania przyjemnego look’n’feel w aplikacji czy manipulowania DOM-em). Jednak jeśli dokładniej się jej przyjrzymy, można łatwo zauważyć, że jest ona rozwiniętą, dojrzałą platformą do wytwarzania oprogramowania w sposób, jaki znamy z platformy .NET, Java, czy innej.

Chciałbym skupić się na jednym z frameworków JavaScriptowych, służącym do pisania aplikacji w oparciu o BDD (Behaviour Driven Development). Frameworkiem tym jest Jasmine. Z czego składa się Jasmine?

Po pierwsze z założeń i ich zestawów (suites and specs).

  • Spec (specyfikacja) to funkcja JavaScriptowa. Definiujemy je poprzez wywołanie funkcji it() z podaniem opisu oraz funkcji, którą ma wywołać. Oczekiwanie (expectation) na temat zachowania aplikacji można wyrazić poprzez wywołanie funkcji  expect() wraz jednym z warunków dopasowania (matcher).
it('powinno zinkrementować zmienną', function () {
  var foo = 0; // definiujemy warunki początkowe
  foo++; // wykonujemy działania naszej aplikacji
  expect(foo).toEqual(1); // Jest poprawne, ponieważ foo == 1
});
  • Suite (zestaw specyfikacji) – zbiór specyfikacji zgrupowanych przy pomocy funkcji describe(), założenia są wykonywane w takiej kolejności w jakiej zostały zdefiniowane.
describe('Kalkulator', function () {
  var licznik = 0;

  it('może dodać liczbę', function () {
    licznik = licznik + 2; // licznik był uprzednio 0
    expect(licznik).toEqual(2);
  });

  it('może pomnożyć liczbę', function () {
    licznik = licznik * 5; // licznik był uprzednio 2
    expect(licznik).toEqual(10);
  });
});

Specyfikacje mogą być wyłączone poprzez wywołanie xit() zamiast  it(). To samo tyczy się zestawów założeń – xdescribe() zamiast describe().
Każdy z zestawów może zawierać sekcję poprzedzającą (beforeEach()) i następującej (afterEach()) po każdym specu.

describe('jakiś zestaw', function () {
  var zmienna = 1;
  afterEach(function () {
    zmienna = 0;
  });

  it(powinno równać się 1', function () {
    expect(zmienna).toEqual(1);
  });

  it('powinno równać się 0 po wykonaniu', function () {
    expect(zmienna).toEqual(0);
  });
});

Jasmine posiada kilka predefiniowanych warunków dopasowania:
expect(x).toEqual(y); porównuje obiekty lub typy proste x i y oraz przechodzi jeśli są sobie równe
expect(x).toBe(y); porównuje obiekty lub typy proste x i y oraz przechodzi jeśli to ten sam obiekt
expect(x).toMatch(pattern); porównuje x do stringa lub wyrażenia regularnego pattern oraz przechodzi jeśli istnieje dopasowanie
expect(x).toBeDefined(); przechodzi jeśli x nie jest undefined
expect(x).toBeUndefined(); przechodzi jeśli x jest undefined
expect(x).toBeNull(); przechodzi jeśli x to null
expect(x).toBeTruthy(); przechodzi jeśli x ewaluuje do prawdy
expect(x).toBeFalsy(); przechodzi jeśli x ewaluuje do fałszu
expect(x).toContain(y); przechodzi jeśli tablica lub string x zawierają y
expect(x).toBeLessThan(y); przechodzi jeśli x jest mniejsze niż y
expect(x).toBeGreaterThan(y); przechodzi jeśli x jest większe niż y
expect(function(){fn();}).toThrow(e); przechodzi jeśli funkcja fn rzuca wyjątkiem e podczas wywołania
Każdy z warunków dopasowania może zostać odwrócony poprzez poprzedzenie go negacją (not).
expect(x).not.toEqual(y); porównuje obiekty lub typy proste x i y oraz przechodzi jeśli nie są sobie równe

Można też dodawać własne kryteria dopasowania:

toBeSquare: function(expected) {
  return this.actual < expected * expected;
};

Aby dodać nasz warunek do zestawu należy wywołać this.addMatchers() w bloku before lub it:

beforeEach(function() {
  this.addMatchers({
    toBeSquare: function(expected) {
      return this.actual < expected * expected;
    }
  });
});

Reasumując – Jasmine to jedno z wielu narzędzi, które pozwala nam pisać dobry kod w JavaScripcie (testowalny i przetestowany). Przy obecnych trendach związanych z wytwarzaniem oprogramowania, warto zapoznawać się z tego typu narzędziami, jako że ułatwiają nam pracę i poprawiają jakość tego, co kodujemy.