与karma、angular的第一次亲密接触

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sisierda/article/details/53634583

  首先要了解什么是karma,karma干嘛用的,它的好朋友jasmine又是啥?这些文章可以帮助你:
  karma干嘛的?
  angular与karma1
  angular与karma2
  看了以上几篇文章之后,我们基本上就可以启动我们最简单的一个karma测试例子了。然后我们还要有webpack对吧:
  karma-webpack插件
  这些都配置好,我们的karma配置文件就成了这个样子:

// Karma configuration
// Generated on Sun Dec 04 2016 19:19:27 GMT+0800 (中国标准时间)

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: [
      'test/**/*.js'
    ],


    // list of files to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
        'test/**/*.js': ['webpack','coverage']
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress','coverage'],


    // 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,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

    webpack: {
        module: {
            debug: true,
            module: {
                loaders: [
                   // nothing here yet! We'll add more stuff in Part 2
                ]
            }
        }
    },
    webpackServer: {
        noInfo: true // prevent console spamming when running in Karma!
    },
    plugins: [
        'karma-chrome-launcher',
        'karma-webpack',
        'karma-jasmine',
        'karma-coverage'
    ],
    coverageReporter: {
      type : 'html',
      dir : 'coverage/'
    }
  })
}

  app.js中的内容

var angular = require('angular');

var mamApp = angular.module("mamApp",[
    require('angular-ui-router'),
    require('./modules/listsModule.js'),
    require('./modules/detailModule.js')
    ]);
mamApp.controller('mamAppModuleCtrl', function($scope,$http,$state,$stateParams) {
    var listType = $stateParams.listType;
    var state = $state.current.name;
    $scope.listType = listType;
    $scope.menuData = [
        {
            id:"appManage",
            name:"应用管理"
        }
    ];
});

  test文件夹里写了一个testIndex.js。

var angular = require('angular');
var mocks = require('angular-mocks');
var mamApp = require('../src/js/app.js');
describe("mamApp", function() {
    var scope;
    beforeEach(angular.mock.module('mamApp'));
    beforeEach(angular.mock.inject(function ($rootScope, $controller) {
        scope = $rootScope.$new();
        $controller('mamAppModuleCtrl', {$scope: scope});
    }));
    it("menuData", function() {
        expect(scope.menuData[0].id==="appManage").toBe(true);
    });
    it("listType", function() {
        scope.listType="white";
        expect(scope.listType=="white").toBe(true);
    });
});

  然后开跑,cmd里输入:karma start
  ok,没问题,顺利运行。控制台打出两个绿色的success。
  那我现在要测试listsModule这个子模块了,它是app的依赖模块,想当然的代码写成这样:
  新建一个文件:testListModule.js

var angular = require('angular');
var mocks = require('angular-mocks');
var mamApp = require('../src/js/app.js');
describe("listsModuleWhite", function() {
    var scope;
    beforeEach(angular.mock.module('listsModule'));
    beforeEach(angular.mock.inject(function ($rootScope,$http,$state,$stateParams,$controller) {
        scope = $rootScope.$new();
        $stateParams.listType="white";
        $controller('listsModuleCtrl', {$scope: scope,$http:$http,$state:$state,$stateParams:$stateParams});
    }));
    it("when listType is white scope.listType should be white", function() {
        expect(scope.listType==="white").toBe(true);
    });
    it("when listType is white btnsShow should be false", function() {
        expect(scope.btnsShow).toBe(false);
    });
    it("when listType is white scope.colNames[1].html should be 版本号", function() {
        expect(scope.colNames[1].html==="版本号").toBe(true);
    });
});

  运行起来报错。。。一个是报多次引用angular的错误,另外总是报找不到的stateprovider,经过错误分析应该改成这样:

describe("listsModuleWhite", function() {
    var scope;
    beforeEach(angular.mock.module('mamApp'));//注意这行
    beforeEach(angular.mock.module('listsModule'));
    beforeEach(angular.mock.inject(function ($rootScope,$http,$state,$stateParams,$controller) {
        scope = $rootScope.$new();
        $stateParams.listType="white";
        $controller('listsModuleCtrl', {$scope: scope,$http:$http,$state:$state,$stateParams:$stateParams});
    }));
    it("when listType is white scope.listType should be white", function() {
        expect(scope.listType==="white").toBe(true);
    });
    it("when listType is white btnsShow should be false", function() {
        expect(scope.btnsShow).toBe(false);
    });
    it("when listType is white scope.colNames[1].html should be 版本号", function() {
        expect(scope.colNames[1].html==="版本号").toBe(true);
    });
});

  注意这行:

beforeEach(angular.mock.module('mamApp'));

  把它加在子模块的实例化之前。就解决了哪些unknown provider的错误。
  那么好,我们继续写一个文件测试DetailModule,当然是模仿前一个写成这样:

describe("detailModuleWhite", function() {
    var scope;
    beforeEach(angular.mock.module('mamApp'));
    beforeEach(angular.mock.module('detailModule'));
    beforeEach(angular.mock.inject(function ($rootScope,$http,$state,$stateParams,$controller) {
        scope = $rootScope.$new();
        $stateParams.listType="white";
        $controller('detailModuleCtrl', {$scope: scope,$http:$http,$state:$state,$stateParams:$stateParams});
    }));
    it("when listType is white scope.listType should be white", function() {
        expect(scope.listType==="white").toBe(true);
    });
    it("when listType is white params should be ...", function() {
        expect(scope.params.deviceNum).toBe(0);
        expect(scope.params.backBtnName=="返回白名单列表").toBe(true);
    });

});

  然后又报错,说angular undefined。
  仔细分析了一下,各种方法都测了一遍,最后发现是代码执行顺序错误了。Detail这个文件应为名字开头是D,先于Index(开头是I)文件运行了。所以我就把“Index”文件改了个名字叫“1ndex”,这样代码又顺利运行了。
  然后仔细回想了一下,配置文件里,files配置的是一个array,而且是有顺序的。所以我把index文件名改回来,把karma.config.js的内容稍微改一行:

    files: [
      'test/index.js','test/modules/**/*.js'
    ],

除了index.js,其他要测试的文件都放到modules文件夹内。
  同时为了让coverage分析准确,把index.js的内容改为:

var angular = require('angular');
var mocks = require('angular-mocks');
var mamApp = require('../src/js/app.js');
实际的测试内容代码,放到一个新建的testMamApp.js文件内,再把这个文件放入modules文件夹内。弄完以后的结构如下:
test:.
│  Index.js
│
└─modules
        testDetailModule.js
        testListModule.js
        testMamApp.js
好了,这样karma就可以陪伴我们一起愉快的开发了。
![coverage效果](https://img-blog.csdn.net/20161214103626988?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2lzaWVyZGE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

猜你喜欢

转载自blog.csdn.net/sisierda/article/details/53634583