關於本文:介紹通過karma與jsmine框架對angular開發的應用程序進行單元與E2E測試。
先決條件
- nodejs
- webstorm
創建項目
webstorm中創建空白web項目

創建html、js文件夾
在項目中創建2個文件夾分別用於存放項目中用到的html、js文件。
安裝框架
安裝前端框架
項目中的前端框架主要為angularjs相關的框架,為了安裝框架方便可安裝bower包管理器。
1) 安裝bower包管理器
在webstorm的terminal中執行腳本
npm install bower -save
2) 初始化bower.json文件
執行腳本生成bower.json文件,用於管理bower的依賴和配置。
bower init
3) 安裝angular等框架
除了項目要用到的angular框架外還需要安裝angular-mocks框架
bower install bootstrap -save
bower install angular -save
bower install angular-mocks -save
安裝服務器端框架
服務器依賴於nodejs,需要安裝nodejs的包,首先在根目錄下創建package.json文件。
1)安裝http-server模塊
npm install http-server -save
2)安裝其他模塊
- jasmine-core:javascript單元測試框架;
- karma:模擬javascript腳本在各種瀏覽器執行的工具;
- karma-chrome-launcher: 在chrome瀏覽器執行的工具;
- karma-jasmine: jasmine-core在karma中的適配器;
- karma-junit-reporter: 生成junit報告;
- protractor:E2E測試框架
啟動服務器
要啟動node服務器需要在package.json中配置script節點,dependencies中定義依賴包,在script配置start節點用於啟動服務器,test節點的內容會在后面講解。
"name": "angularjs-test",
"version": "0.0.1",
"dependencies": {
"bower": "^1.7.7",
"http-server": "^0.9.0",
"jasmine-core": "^2.4.1",
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
"karma-jasmine": "^0.3.8",
"karma-junit-reporter": "^0.4.1",
"protractor": "^3.2.1"
},
"scripts": {
"postinstall": "bower install",
"prestart": "npm install",
"start": "http-server -a localhost -p 8000 -c-1",
"pretest": "npm install",
"test": "karma start karma.conf.js",
"test-single-run": "karma start karma.conf.js --single-run"
}
配置后運行命令,啟動服務器,瀏覽器上輸入http://localhost:8000
npm start
開始單元測試
編寫功能代碼
在文件js中新建js文件index.js。在index.js中定義congroller,實現簡單累加方法add,代碼如下:
/**
* Created by stephen on 2016/3/24.
*/
(function (angular) {
angular.module('app', []).
controller('indexCtrl', function ($scope) {
$scope.add = function (a, b) {
if(a&&b)
return Number(a) + Number(b)
return 0;
}
});
})(window.angular);
在文件html中新建html文件index.html,加入兩個輸入框用戶獲取輸入,當輸入后綁定controller中的add方法實現計算器功能,代碼如下:
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<div ng-controller="indexCtrl">
<input type="text" ng-model="a" value="0">
+
<input type="text" ng-model="b" value="0">
=<span id='result'>{{add(a,b)}}</span>
</div>
</body>
</html>
<script src="/bower_components/angular/angular.min.js"></script>
<script src="/bower_components/angular-mocks/angular-mocks.js"></script>
<script src="/js/index.js"></script>
啟動服務器看到下圖效果

編寫測試代碼
在test文件夾中新建文件index-test.js用於編寫index.js的單元測試。
'use strict';
describe('app', function () {
beforeEach(module('app'));
describe('indexCtrl', function () {
it('add 測試', inject(function ($controller) {
var $scope = {};
//spec body
var indexCtrl = $controller('indexCtrl', {$scope: $scope});
expect(indexCtrl).toBeDefined();
expect($scope.add(2, 3)).toEqual(5);
}));
});
});
單元測試配置
初始化karma配置文件,用於配置karma,執行命令
karma init
在karma配置文件代碼中每個節點都有默認注釋請參看
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: './',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.min.js',
'bower_components/angular-mocks/angular-mocks.js',
'js/index.js',
'test/index-test.js'
],
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-junit-reporter'
],
junitReporter: {
outputFile: '/test_out/unit.xml',
suite: 'unit'
}
})
}
在package.json scripts 配置測試信息,指定karma文件地址
"test": "karma start karma.conf.js",
運行單元測試
運行命令,執行測試
npm test
運行結果如下,可以看到通過測試:

調試單元測試
除了運行測試外,很多時候需要調試測試,在karma彈出網頁中點擊debug,進入http://localhost:9876/debug.html頁面,就可以用chrome自帶的調試工具調試代碼了:


單元測試覆蓋率
如果需要對單元測試覆蓋率進行統計,可以安裝karma-coverage並配置karma文件。這樣在單元測試完成后,會生成測試覆蓋率報告文檔。
npm install karma-coverage -save
在karma.conf.js文件中加入節點
// 新增節點用於配置輸出文件夾
coverageReporter: {
type: 'html',
dir: 'coverage'
},
// 新增節點用於配置需要測試的文件地址(這里是controller地址)
preprocessors: {'js/*.js': ['coverage']}
// 新增元素'karma-coverage'
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-junit-reporter',
'karma-coverage',
],
// 新增元素 coverage
reporters: ['progress', 'coverage'],
運行單元測試后在目錄中生成coverage文件夾,點擊index.html可以查看測試覆蓋率。

E2E測試
e2e或者端到端(end-to-end)或者UI測試是一種測試方法,它用來測試一個應用從頭到尾的流程是否和設計時候所想的一樣。簡而言之,它從一個用戶的角度出發,認為整個系統都是一個黑箱,只有UI會暴露給用戶。
配置E2E測試
新建文件夾e2e-test新建protractor.conf.js文件,用於配置protractor框架,代碼如下。
exports.config = {
allScriptsTimeout: 11000,
baseUrl: 'http://localhost:8000/app/',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
framework: 'jasmine',
// Spec patterns are relative to the configuration file location passed
// to protractor (in this example conf.js).
// They may include glob patterns.
specs: ['*.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
},
defaultTimeoutInterval: 30000
};
配置package.json scripts腳本節點
"preupdate-webdriver": "npm install",
"update-webdriver": "webdriver-manager update",
"preprotractor": "npm run update-webdriver",
"protractor": "protractor e2e-test/protractor.conf.js"
編寫e2e測試腳本
設計測試用例:文本框a的值錄入1,文本框b錄入2,期望結果3
describe('index.html', function() {
beforeEach(function() {
browser.get('http://localhost:8000/html');
});
it('get index html', function() {
var a = element(by.model('a'));
var b = element(by.model('b'));
a.sendKeys(1);
b.sendKeys(2);
var result = element(by.id('result'));
expect(result.getText()).toEqual('3');
});
});
執行測試查看測試結果
需要執行命名,查看是否更新webdriver(什么是webdriver http://sentsin.com/web/658.html),
手動安裝protractor至全局
npm i -g protractor
注:安裝或更新webdriver需要翻牆,請在webstrom中設置代理地址。
在webstrom中切換至Terminal窗口,在Terminal窗口通過以下方式設置代理:
set PROXY=http://localhost:1080
set HTTP_PROXY=%PROXY%
set HTTPS_PROXY=%PROXY%
代理設置成功后,運行以下命令
npm run update-webdriver
執行e2e測試,這是會彈出瀏覽器,自動點擊瀏覽器,錄入腳本輸入完成自動化e2e測試,其本質還是調用selenium測試。
npm run protractor

參考資料
[1] 官方測試demo https://github.com/angular/angular-seed
[2] protractor 官方文檔 http://angular.github.io/protractor/#/tutorial
[3] 自動化E2E測試 http://sentsin.com/web/658.html
[4] karma官方文檔 https://karma-runner.github.io/latest/intro/configuration.html
[5] angular單元測試官方文檔 https://docs.angularjs.org/guide/unit-testing
