Karma测试(Karma + AngularJS + RequireJS)

1. 简介

Karma是一种用于自动化测试的工具。
本文共包含4个例子: Karma -> Karma + AngularJS -> Karma + RequireJS -> Karma + AngularJS + RequireJS。
代码均已上传至我的Github,下载完成后至相应目录下执行 karma start 即可开始单元测试。

2. 使用karma搭建一个简单的测试demo

  1. 初始化项目

    1
    npm init
  2. 安装必要的依赖

    1
    2
    npm install karma --save-dev
    npm install jasmine-core --save-dev
  3. 初始化karam测试配置

    1
    karma init

    这里全部回车,按照默认选项即可
    karma init执行完成后会生成配置文件karma.conf.js。这个文件实质上就是一个js。
    在该文件的config.set({...})中有一个key为files的参数,其用于指定当开始执行测试时,我们需要浏览器载入的js文件。

  4. 在根目录下创建index.js和test.js,其中index.js包含一个反转字符串的函数reverseString(),我们将使用test.js对其进行测试test.js中的内容:

    1
    2
    3
    4
    5
    6
    7
    8
    describe("karma demo - it is a simple test", function(){
    it("testing function reverseString - test case 1", function(){
    expect(reverseString("123")).toBe("321");
    });

    it("testing function reverseString - test case 2", function(){
    expect(reverseString("121")).toBe("121");
    });

    });

  5. 修改karma.conf.jsconfig.set({..})里的files, 将这两个文件引入测试浏览器中(Karma通过files数组指定测试过程中需要使用的js文件):

    1
    2
    3
    4
    files: [
    'index.js',
    'test.js'
    ],

在根目录执行karma start即可开始执行测试
本部分代码可参考1_karma_begin

3. karma + AngularJS

  1. 重复上一节中的1~3, 并安装Angular相关依赖:(注意 - angularangular-mocks 版本号要一致)

    1
    2
    npm install angular --save-dev
    npm install angular-mocks --save-dev
  2. 新建scripts文件夹,加入app.js和appSpec.js
    app.js:

    1
    2
    3
    4
    5
    6
    var app = angular.module('myApp', []);
    app.controller('myController', function($scope){
    $scope.reverseString = function(str){
    return str.split('').reverse().join('');
    }
    });

    appSpec.js:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    describe("karma demo - it is a demo combine AngularJS", function(){
    var scope = null;

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

    it("testing - test case 1", function(){
    expect(scope.reverseString("123")).toBe("321");
    });
    });
  3. 修改karma.conf.js:

    1
    2
    3
    4
    5
    6
    7
    8
    ...
    files: [
    'node_modules/angular/angular.js',
    'node_modules/angular-mocks/angular-mocks.js',
    'scripts/app.js',
    'scripts/appSpec.js'
    ],
    ...

在根目录执行karma start即可开始执行测试
本部分代码可参考2_karma_angularjs

4. karma + RequireJS

  1. 初始化项目

    1
    npm init
  2. 安装必要的依赖

    1
    2
    3
    4
    npm install karma --save-dev
    npm install jasmine-core --save-dev
    npm install requirejs --save-dev
    npm install karma-requirejs --save-dev
  3. 初始化karam测试配置

    1
    karma init

    在这两个问题中选择yes
    Do you want to use Require.js ? - yes - 在测试中使用RequireJS
    Do you wanna generate a bootstrap file for RequireJS? - yes - 生成一个RequireJS的配置文件
    初始化完成后可以看到根目录下多了karma.conf.js和test-main.js两个文件,且在karma.conf.js的config.set({...})中的files数组中已写入了test-main.js,也就是说开始测试后会自动执行test-main.js

  4. karma.conf.js
    在karma.conf.js中可看到这么一段代码:

    1
    2
    3
    4
    5
    ...
    files: [
    'test-main.js',
    ],
    ...

    这里的files指定了浏览器执行测试工作时需要载入的js文件,这里指定了 test-main.js 后浏览器在开始测试时会以 <script>.../test-main.js</script> 的形式载入 test-main.js,如图所示。

  5. test-main.js
    test-main.js中产生代码为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    var allTestFiles = []
    var TEST_REGEXP = /(spec|test)\.js$/i

    // Get a list of all the test files to include
    Object.keys(window.__karma__.files).forEach(function (file) {
    if (TEST_REGEXP.test(file)) {
    // Normalize paths to RequireJS module names.
    // If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
    // then do not normalize the paths
    var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '')
    allTestFiles.push(normalizedTestModule)
    }
    })

    require.config({
    // Karma serves files under /base, which is the basePath from your config file
    baseUrl: '/base',

    // dynamically load all test files
    deps: allTestFiles,

    // we have to kickoff jasmine, as it is asynchronous
    callback: window.__karma__.start
    })

    可以看到(第3行),系统会遍历 window.__karma__.files ,自动将含有匹配TEST_REGEXP的js文件当做测试脚本(第20行)。
    这里的 window.__karma__.files 就是浏览器在执行测试时会载入的所有js文件的集合。
    window.__karma__.files中包含了上一小节中 karma.conf.jsfiles 数组中指定的文件。
    requre.config({...})中的baseUrl是karma默认的根目录,对应项目工程中的根目录 ‘/‘

  6. 增加测试文件
    创建文件夹scripts,在其中增加待测试文件src.js和测试文件srcSpec.js
    src.js:

    1
    2
    3
    4
    5
    6
    7
    define('src', function(){
    var testObj = {};
    testObj.returnTrue = function(){
    return true;
    }
    return testObj;
    });

    srcSpec.js:

    1
    2
    3
    4
    5
    6
    7
    define(['src'], function(srcObj){
    describe("karma demo - it is a demo combine requireJS", function(){
    it("testing - test case 1", function(){
    expect(srcObj.returnTrue).toBe(true);
    });
    });
    });
  7. 加载要测试的js文件
    这时执行karma start,提示执行了0个测试用例-需要把代码加入karma.conf.jsconfig.set({..})files数组,否则测试浏览器不知道要加载这些js文件。
    karma.conf.js中的files修改为:

    1
    2
    3
    4
    files: [
    {pattern: 'scripts/*.js', included: false},
    'test-main.js'
    ],

    这里的 included: false 代表是否在浏览器中采用 <script></script> 标签的方式加入该js文件。
    在使用RequireJS的情况下,应该将其设为 false ,避免测试浏览器将其采用 <script></script> 的方式引入这些JS文件。
    继续报错 - 404,找不到/base/src.js - 在 test-main.js 里观察 window.__karma__.files ,如图所示,我们可以看到引入的 src.js 实际路径为 /base/srcipts/src.js

    在test-main.js的requre.config({...})中的baseUrl对应的是工程中的根目录‘/‘,所以我们应该将src.js/srcSpec.js中的 define('src', ... 改为 define('scripts/src', ... (当然,也可以在test-main.js的require.config通过paths手动指定: paths: {'src': 'scripts/src'} )。

    在根目录执行karma start即可开始执行测试
    本部分代码可参考3_karma_requirejs

5. Karma + AngularJS + RequireJS

  1. 初始化项目

    1
    npm init
  2. 安装必要的依赖

    1
    2
    3
    4
    5
    6
    npm install karma --save-dev
    npm install jasmine-core --save-dev
    npm install requirejs --save-dev
    npm install karma-requirejs --save-dev
    npm install angular --save-dev
    npm install angular-mocks --save-dev
  3. 初始化karam测试配置 - 参照上一节

  4. 新建scripts文件夹,在scripts文件夹其中增加myApp.js/myController.js/myAngularSpec.js:
    myApp.js:

    1
    2
    3
    4
    define('myApp', ['angular'], function(){
    var app = angular.module('myApp', []);
    return app;
    });

    myController.js:

    1
    2
    3
    4
    5
    6
    7
    define('myController', ['myApp'], function(app){
    app.controller('myController', function($scope){
    $scope.reverseString = function(str){
    return str.split('').reverse().join('');
    }
    });
    });

    mySpec.js:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    define(['myController'], function(){
    describe("karma demo - it is a demo combine AngularJS", function(){
    var scope = null;

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

    it("testing - test case 1", function(){
    expect(scope.reverseString("123")).toBe("321");
    });
    });
    });
  5. karma.conf.js 中引入这些js:

    1
    2
    3
    4
    5
    6
    files: [
    'node_modules/angular/angular.js',
    'node_modules/angular-mocks/angular-mocks.js',
    {pattern: 'scripts/*.js', included: false},
    'test-main.js'
    ],
  6. test-main.jsrequire.config 中指定路径 paths :

    1
    2
    3
    4
    5
    6
    7
    ...
    paths: {
    'myApp': 'scripts/myApp',
    'myController': 'scripts/myController',
    'angular': 'node_modules/angular/angular'
    },
    ...

在根目录执行karma start即可开始执行测试
本部分代码可参考4_karma_angularjs_requirejs

本文首发于http://www.miaoyunze.com/,转载请注明出处