AngularJS #6 – Karma – pierwszy test

AngularJS



Kolejnym wpisem miało być rozszerzenie o filtrach, ale uznałem, że jest tam zbyt mało materiału, by robić z tego osobny element całego cyklu o AngularJS. Sam temat filtrów jest poza tym na tyle prosty, że nie warto poświęcać na niego zbyt wiele czasu. Znacznie bardziej należałoby się skupić na elemencie testowania aplikacji i dlatego też chciałbym Was wprowadzić w świat Jasmine i Karma.

Karma

Karma jest narzędziem, które pozwala uruchamiać testy kodu JavaScript pod różnymi przeglądarkami, a w zasadzie ich emulowanym środowiskiem. Karma nie jest pełnoprawnym frameworkiem do testowania, a jedynie rusztowaniem, na którego bazie zbudować możemy pełny stack testujący JavaScript. Karma zbudowana jest w oparciu o serwer Node.js oraz technologię Socket.io. Pozwala na wykonywanie testów w różnych środowiskach pracy (deweloperskim, testowym, produkcyjnym itd.), a ponadto wykonuje wszystkie testy w separacji od kodu właściwego. Pozwala także na wykonywanie testów pod różnymi przeglądarkami jednocześnie. W połączeniu z Istanbul, który to potrafi wygenerować i pokazać nam pokrycie naszego kodu testami, Karma stanowi pełnoprawne środowisko testowe, które ułatwia nam, a w zasadzie pozwala na szybkie i bezproblemowe testowanie kodu JavaScript.

Pełny opis instalacji oraz konfiguracji znajdziecie na oficjalnej stronie projektu. Znajduje się tam także film, który bardzo trafnie prezentuje możliwości jakie daje nam Karma.

Jasmine

Spośród kilku frameworków do testowania kodu JavaScript, miałem do tej pory okazję wykorzystywać właśnie Jasmine. Jasmine, to behavior-driven development framework, który pozwala na pisanie naszych testów w sposób bardzo opisowy, a ponadto świetnie integruje się ze środowiskiem Karma. Nie jest on zależny od żadnego frameworka JavaScript i nie wymaga także drzewa DOM do działania. Jasmine pozwala nie tylko na pisanie testów jednostkowych, ale również tak zwanych testów e2e. Kilkadziesiąt przykładów znajdziecie na stronie oficjalnej i w zasadzie nie pozostaje nic innego jak zacząć pisać testy!

Główny konkurent JasmineMocha jest nieco bardziej rozbudowany i dojrzały, ale “próg wejścia” jest także nieco większy. Jest jeszcze QUnit, który używany jest w projektach jQuery, jQuery UI oraz jQuery Mobile, ale nie cieszy się taką popularnością community jak pozostałe dwa.

Let’s write some code!

Nie będę tutaj opisywał jak skonfigurować sobie Karmę oraz Jasmine by działały razem, bo jest to świetnie opisane oraz pokazane na stronach oficjalnych obu narzędzi.

Przypuśćmy zatem, że chcemy przetestować działanie metody w naszym kontrolerze. Niech będzie to przykład metody, która po wykonaniu funkcji sayHello() zmienia wartość parametru name w $scope kontrolera APP.ApplicationCtrl na ‘World’.

'use strict';

var APP = angular.module('APP', []);

APP.ApplicationCtrl = function ($scope) {

    $scope.name = '';

    $scope.sayHello = function () {
        $scope.name = 'World';
    };

};

Klasa testowa wyglądać będzie następująco:

'use strict';

describe('APP.ApplicationCtrl', function () {

    var scope;

    // mockujemy nasz modul APP
    beforeEach(angular.mock.module('APP'));
    // mockujemy kontroler ApplicationCtrl
    // i przekazujemy do niego mock $scope utworzony na podstawie $rootScope
    beforeEach(angular.mock.inject(function ($rootScope, $controller) {
        // tworzymy pusty scope
        scope = $rootScope.$new();
        // tworzymy instancje kontrolera i przekazujemy do niego pusty $scope
        $controller('ApplicationCtrl', { $scope: scope });
    }));

    // .. i testujemy
    it('should set new value for $scope.name', function () {
        // having
        scope.name = '';

        // when
        expect(scope.name).toBe('');
        scope.sayHello();

        // then
        expect(scope.name).toBe('World');
    });

});

Wykonanie powyższego testu zwróci nam oczywiście pozytywny wynik. Tym oto prostym sposobem przetestowaliśmy banalną metodę naszego kontrolera.

Jasmine zawiera szereg predefiniowanych metod oraz asercji do testowania naszego kodu. Jesteśmy w stanie na przykład sprawdzić, czy dana metoda wykonała się w cyklu wykonywania innej z metod w naszym kontrolerze, a na dodatek sprawdzić, czy wykonała się określoną ilość razy. Jesteśmy w stanie porównywać całe kolekcje pod względem zawartości, czy emulować zapytania HTTP. Zachęcam do przyjrzenia się dokumentacji i własnych prób.

I na koniec jak zawsze http://egghead.io i prezentacja Karmy oraz Jasmine na równie prostym przykładzie.

[youtube_sc url=”https://www.youtube.com/watch?v=wFYID8eYQLs”]

  • Maciej

    Pomysł napisania polskiego tutorialu do AngularJS jest jak najbardziej dobry. Jednak wykonanie moim zdaniem pozostawia wiele do życzenia. Tak na dobrą sprawę w Twoim tutorialu nie ma nic. Parę linków do innych stron, parę zdań, które osobie dopiero zaczynającej zabawę z AngularJS nic nie mówią. Jeśli ktoś ma opanowany angielski na poziomie podstawowym, i wejdzie raz w link do filmików więcej do Twojej strony nie wróci. Bo po co? Po kolejny raz powtórzone stwierdzenie “www…”. A jeśli ktoś nie zna Angielskiego to i tam nie wróci na Twoją stronę bo nic tu nie ma takiego, co przykuło by uwagę amatora i początkującego. Omówienie tekstu w postaci paru zdań jest moim zdaniem bardzo słabym pomysłem. Jeśli chcesz stanowić polski odpowiednik angielskich tutoriali to chyba jednak trzeba z siebie dać coś więcej. Choćby np proces instalacji narzędzi itp. Nie po to chętny nauki wchodzi na Twoją stronę, żeby i tak i tak musieć szukać wszystkiego w innych miejscach.
    Pozdrawiam,
    Maciej

    • Dzięki za komentarz :) Mam świadomość, że wiele rzeczy można zrobić lepiej. Od dłuższego czasu nie pisałem z racji braku czasu, a sam kurs nie jest też dla osób dopiero zaczynających swoją przygodę z IT.

    • Mariusz Donigiewicz

      A wg. mnie tutorial jest OK.
      Niezbyt opasly w tresc wiec szybko mozna sie zoorientowac w technologii- daje ogolny poglad i tak jak checesz cos konkretnego napisac musisz spojrzec w dokumentacje ….
      Inna sprawa czy faktycznie pisanie tutoriali po polsku ma w ogole sens ..

    • Adrian Kalinowski

      Wg mnie spoko, zawsze to można poczytać coś w swoim języku od tego zacząć jako przyjemny start, pływając po rzeczce, aby potem rzucić się na głęboką wodę :)

    • enter

      Zrób coś z własnej inicjatywy to zjadą Cię jak psa :D Nie słuchaj. Jest dobrze.

  • Anik

    Witam, właśnie dobrze Maciej powiedział o procesie instalacji bo mam z nim problem czy mógłbyś krok po korku napisać jak to zainstalować?