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