[Из песочницы] Unit-тестирование вашего Ionic-приложения

Это вольный перевод статьи mcgivery.com/unit-testing-ionic-app на тему тестирования мобильных приложений Ionic используя karma test runner и Jasmine test framework.

О фреймворке ionic на хабре уже были статьи. Но ни в одной не нашел хоть чуть чуть о тестировании всего этого. Поэтому решил разместить здесь свой перевод статьи, которая мне однажды очень помогла. Надеюсь, что кому-нибудь она также будет полезна для старта написания тестов под ionic-приложение.

Создание демо-проекта Ionic


Вначале создадим демо-приложение. Я использую один из шаблонов приложения Ionic — tabs. Что бы создать демо-приложение выполните.

ionic start ionic-testing tabs
cd ionic-testing

Подготовка проекта к тестированию


Для тестов нам понадобятся несколько npm-модулей и angular-mocks. Все устанавливается через пакетный менеджеры npm и bower:

npm install karma karma-jasmine karma-phantomjs-launcher --save-dev
npm install -g karma-cli
npm install 
bower install angular-mocks --save-dev


Теперь создаем папку для теста и инициализируем конфигурационный файл для karma.

mkdir tests
cd tests
karma init my.conf.js


Ответим на все вопросы да. В my.conf.js добавим пути к js-файлам проекта и файлам тестов, также добавим PhantomJS в список используемых браузеров.

// list of files / patterns to load in the browser
files: [
  '../www/lib/angular/angular.js',
  '../www/js/*.js',
  '../www/lib/angular-mocks/angular-mocks.js',
  '**/*tests.js'
],

// Use the PhantomJS browser instead of Chrome
browsers: ['PhantomJS'],


Для удобства запуска тестов, добавим gulp-таск test.

// это пропишем в секции импорта
var KarmaServer = require('karma').Server;

// ... другие gulp-таски

// gulp-task для запуска теста
gulp.task('test', function(done) {
    new KarmaServer({
        configFile: __dirname + '/tests/my.conf.js',
        singleRun: true,
    }, done).start();
});


Теперь для запуска тестов мы можем использовать команду gulp test (если мы не укажем параметр singleRun, то тест будет запускаться каждый раз когда изменятся файлы указанные в my.conf.js).

Unit-тестирование контроллеров


Начнем с написания теста для контроллера AccountCtrl уже включенного в стандартный Tabs-проект. Создадим в папке tests новый файл Controllers/controllers.tests.js.

describe('Controllers', function(){
    var scope;

    // load the controller's module
    beforeEach(module('starter.controllers'));

    beforeEach(inject(function($rootScope, $controller) {
        scope = $rootScope.$new();
        $controller('AccountCtrl', {$scope: scope});
    }));

    // tests start here
    it('should have enabled friends to be true', function(){
        expect(scope.settings.enableFriends).toEqual(true);
    });
});


Этот тест проверяет включено ли значение scope.settings.enableFriends в контроллере AccountCtrl. Функция beforeEach будет запущено перед выполнением теста. Она получает информацию о модуле angular, который мы тестируем.

Для написания теста используется Jasmine. Это фреймворк для тестирования JavaScript-кода. С синтаксисом вы можете ознакомиться на официальном сайте.

Что бы запустить тест выполните gulp task

Unit-тестирование сервисов


Второй unit-тест будет тестировать Chats сервис (в оригинале написано Friends, но в новой версии приложения tabs он был переименован). Создайте файл в директории tests Services/services.tests.js.

describe('Chats Unit Tests', function() {
    var Chats;

    beforeEach(module('starter.services'));
    beforeEach(inject(function(_Chats_) {
        Chats = _Chats_;
    }));

    it('can get an instance of my factory', inject(function(Chats) {
        expect(Chats).toBeDefined();
    }));

    it('has 5 charts', inject(function(Chats) {
        expect(Chats.all().length).toEqual(5);
    }));

    it('has Max as friend with id 1', inject(function(Chats) {
        var oneFriend = {
            id: 1,
            name: "Max Lynx",
            notes: 'Odd obsession with everything',
            face: ''
        };

        expect(Chats.get(1).name).toEqual(oneFriend.name);
    }))
})


Мы видим все тот же beforeEach выполняющий те же действия, что и в тесте контроллера, только здесь вместо контроллера инициализируется сервис Chats. Мы вызываем метод Chats.all() для проверки числа объектов (должно быть 5).

В дополнение мы получаем один объект по его id и проверяем свойство name.

Запуск тестов происходит также gulp test.

P.S. это моя первая статья на Хабре, да и вообще первый материал, если я что-то не верно описал или есть более простые и лучшие решения, буду рад комментариям!

© Habrahabr.ru