14 August 2015

Karma를 통한 AngularJs unit test.

Prepare

$ mkdir karma-jasmine
$ cd karma-jasmine
$ touch ./js/object.js
$ touch ./js/tests
$ touch ./js/tests/object.test.js

Test Tools Install

$ npm install -g jasmine
$ npm install -g karma-cli
$ npm install -g phantomjs
$ npm install karma-jasmine@2_0 --save-dev
$ npm install karma-phantomjs-launcher --save-dev

Angular Install

$ bower install angular
$ bower install angular-mocks

html 없이도 AngularJs를 테스트 가능하게 해주는 angular-mocks 도 반드시 설치한다.

Config Karma

$ karma init karma.conf.js

settings

  • framework : jasmine
  • Require.js : no
  • capture browser : Chrome
  • source and test files : bower_components/angular/angular.js, bower_components/angular-mocks/angular-mocks.js, js/.js js/tests/.js
  • exclude : (none)
  • watch : yes

karma.conf.js 파일에 다음과 같이 설정 된다.

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
        'bower_components/angular/angular.js',
        'bower_components/angular-mocks/angular-mocks.js',
        'js/*.js',
        'js/tests/*.js'
    ],
    exclude: [],
    preprocessors: {},
    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['PhantomJS'],
    singleRun: false
  })
}

autoWatch 는 테스트 파일이나 소스가 변경되면 자동으로 다시 테스트 해주는 편리한 옵션. 켜두는 것을 추천.
singleRunbrowsers가 여러개 설정 되었을 때, 테스트를 병렬로 진행하지 않고 한번에 하나씩 진행한다.
나머지는 빤하므로 더이상의 자세한 설명은 생략한다.

Jasmine

Jasmin은 Mocha와 굉장히 비슷하다. describe, it 등 BDD 형식을 따르므로 기본 인터페이스는 거의 완전히 동일하다. 다만 assertion engine을 따로 쓰지는 않고 내장된 엔진을 사용한다.

Jasmine Github Page에 설명이 아주 심플하게 잘 되어 있으므로 참고한다.

Test Example(js/tests/main.spec.js)

다음은 기본적인 Angular scope내 객체에 대한 테스트 예이다.

'use strict';

describe('Controller: MainCtrl', function () {

  // load the controller's module
  beforeEach(module('myApp'));

  var MainCtrl,
    scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    MainCtrl = $controller('MainCtrl', {
      $scope: scope
    });
  }));

  it('should have no items to start', function () {
    expect(scope.todos.length).toBe(0);
  });
});

다음 함수들은 테스트용 Mock 객체를 만들어주는 ngMock 에서 제공하는 함수들이다. Jasmine이나 Mocha 테스트에서만 사용 가능하며, window 객체에 전역변수로 제공되므로 간단하게 사용할 수 있다.

  • module("Module Name") : 테스트할 모듈을 로딩한다.
  • inject(function(service1, service1, ...){} : 테스트에 필요한 dependency를 주입한다.
  • $controller(constructor, locals) : AngularJs 의 Controller 서비스. constructor에는 생성자 함수나 등록된 컨트롤러 이름을 String으로 넘길 수 있다. locals 에는 컨트롤러에 주입할 로컬 변수들을 {변수명 : 값} 쌍으로 넘긴다.

위의 코드를 보면 myApp module을 로딩한 후에 controller, rootScope 서비스를 인젝션 하고, controller 서비스를 이용해서 MainCtrl 컨트롤러의 $scope 변수로 rootScope 를 삽입하는것을 알 수 있다.

이후 rootScope를 통해서 MainCtrl 컨트롤러의 scope에 액세스할 수 있다.



blog comments powered by Disqus
처음으로