• angularJS+requireJS并集成karma测试实践


    最近在为下一个项目做前端技术选型,Angular是必须要用的(BOSS指定,个人感觉也不错,开发效率会很高)。由于需要加载的JS很多,所以打算看看angular和requirejs一起用会怎么样。在git上有一个模板加《angular-requirejs-seed》,这个对angular和requirejs结合有很好的指导。但是他把karma的单元测试js放在项目中了,我更喜欢放在test目录下。

    由于为linux下没有截图工具,就手打了。求Linux下好用的截图工具分享。要用karma测试首先使用karma init命令生成测试文件karma.conf.js。

    在项目下输入命令karma init  

      Which testing framework do you want to use? jasmine  

      Do you want to use Require.js?  yes            注意:按上下键就可以选择

      Do you want to capture any browsers automatically?   Chrome  注意,可以选多个

      What is the location of your source and test files?  app/**/**/*.js  enter键  app/app.js  enter键  app/require-config.js  enter键 test/**/*Spec.js    这里的路径更加实际项目情况来确定。可以多个路径。

      Should any of the files included by the previous patterns be excluded ? enter键跳过。

      Do you wanna  generate a bootstrap file for RequireJS? yes

      Do you want karma to watch all the files and run the tests on change? yes

     在这些步骤完成之后,会在根目录生成叫做karma.conf.js和test-main.js的两个文件。由于习惯,我喜欢将karma.conf.js放入test目录下,这时需要将karma.conf.js的basePath改为"..";这里的test-main.js文件就是karma在测试的代替app下的require-config.js的文件,所以test-main.js文件和require-config的内容几乎完全一样,只是由于位置不一样,所以在test-main中增加一个baseUrl.

     1 var allTestFiles = [];
     2 var TEST_REGEXP = /(spec|test).js$/i;
     3 
     4 Object.keys(window.__karma__.files).forEach(function(file) {
     5   if (TEST_REGEXP.test(file)) {
     6     // Normalize paths to RequireJS module names.
     7     allTestFiles.push(file);
     8   }
     9 });
    10 
    11 require.config({
    12   // Karma serves files under /base, which is the basePath from your config file
    13   baseUrl: '/base/app',
    14   paths: {
    15     angular: 'bower_components/angular/angular',
    16     angularRoute: 'bower_components/angular-route/angular-route',
    17     angularMocks: 'bower_components/angular-mocks/angular-mocks',
    18     angularCookies:'bower_components/angular-cookies/angular-cookies',
    19     angularResource:'bower_components/angular-resource/angular-resource'
    20   },
    21   shim: {
    22     'angular' : {'exports' : 'angular'},
    23     'angularRoute': ['angular'],
    24     'angularCookies': ['angular'],
    25     'angularResource': ['angular'],
    26     'angularMocks': {
    27       deps:['angular'],
    28       'exports':'angular.mock'
    29     }
    30   },
    31   priority: [
    32     "angular"
    33   ],
    34   // dynamically load all test files
    35   deps: allTestFiles,
    36 
    37   // we have to kickoff jasmine, as it is asynchronous
    38   callback: window.__karma__.start
    39 });
    40 require([
    41     'angular',
    42     'app'
    43   ], function(angular, app) {
    44     var $html = angular.element(document.getElementsByTagName('html')[0]);
    45     angular.element().ready(function() {
    46       // bootstrap the app manually
    47       angular.bootstrap(document, ['cxriaApp']);
    48     });
    49   }
    50 );
    test-main.js
     1 'use strict';
     2 
     3 if(window.__karma__) {
     4     var allTestFiles = [];
     5     var TEST_REGEXP = /spec.js$/;
     6 
     7     var pathToModule = function(path) {
     8         return path.replace(/^/base/app//, '').replace(/.js$/, '');
     9     };
    10 
    11     Object.keys(window.__karma__.files).forEach(function(file) {
    12         if (TEST_REGEXP.test(file)) {
    13             // Normalize paths to RequireJS module names.
    14             allTestFiles.push(pathToModule(file));
    15         }
    16     });
    17 }
    18 
    19 require.config({
    20     paths: {
    21         angular: 'bower_components/angular/angular',
    22         angularRoute: 'bower_components/angular-route/angular-route',
    23         angularMocks: 'bower_components/angular-mocks/angular-mocks',
    24     angularCookies:'bower_components/angular-cookies/angular-cookies',
    25     angularResource:'bower_components/angular-resource/angular-resource',
    26     uiBootstrap:'bower_components/angular-bootstrap/ui-bootstrap'
    27     },
    28     shim: {
    29         'angular' : {'exports' : 'angular'},
    30         'angularRoute': ['angular'],
    31         'angularCookies': ['angular'],
    32         'angularResource': ['angular'],
    33         'angularMocks': {
    34             deps:['angular'],
    35             'exports':'angular.mock'
    36         }
    37     },
    38     priority: [
    39         "angular"
    40     ],
    41     deps: window.__karma__ ? allTestFiles : [],
    42     callback: window.__karma__ ? window.__karma__.start : null,
    43     baseUrl: window.__karma__ ? '../app' : ''
    44 });
    45 
    46 require([
    47     'angular',
    48     'app'
    49     ], function(angular, app) {
    50         var $html = angular.element(document.getElementsByTagName('html')[0]);
    51         angular.element().ready(function() {
    52             // bootstrap the app manually
    53             angular.bootstrap(document, ['cxriaApp']);
    54         });
    55     }
    56 );
    require-config

    下面是为测试路由的代码:

     1 /**
     2  * Created by taox on 15-6-19.
     3  */
     4 'use strict';
     5 
     6 define([
     7   'angular',
     8   'angularMocks',
     9   'app'
    10 ], function() {
    11   describe('Routes test', function() {
    12     var location,route,rootScope;
    13     beforeEach(module('cxriaApp'));
    14     beforeEach(inject(function(_$location_,_$route_,_$rootScope_){
    15       location = _$location_;
    16       route = _$route_;
    17       rootScope = _$rootScope_;
    18     }));
    19     describe('index route', function(){
    20       var httpbackend;
    21       beforeEach(inject(function($httpBackend){
    22         httpbackend = $httpBackend;
    23       }));
    24       it('should load the homepage on successful load of /.', inject(function() {
    25         httpbackend.expectGET('./partials/home/home.html').respond('200','main HTML');
    26         location.path('/');
    27         rootScope.$digest();
    28         expect(route.current.controller).toBe('HomeCtrl');
    29       }));
    30       it('should redirect to the homepage on non-existent route',function(){
    31         httpbackend.expectGET('./partials/home/home.html').respond('200','main HTML');
    32         location.path('/non-existent-path');
    33         rootScope.$digest();
    34         expect(route.current.controller).toBe('HomeCtrl');
    35       });
    36       it('should redirect to room page on successful load of /room/1',function(){
    37         httpbackend.expectGET('./partials/room/room.html').respond('200','main HTML');
    38         location.path('/room/1');
    39         rootScope.$digest();
    40         expect(route.current.controller).toBe('RoomCtrl');
    41       })
    42     });
    43   });
    44 
    45 });
    RouteSpec

    对于karma再测试angular的指令时,为现在遇到一个很蛋疼的问题,那就时在当指令使用templateUrl时,需要karma-ng-html2js-preprocessor才能测试,这时需要修改karma.conf.js.

    1.在files中增加模板的地址如:'app/directives/chatroom/*.html',

    2.在plugins中增加''karma-ng-html2js-preprocessor',

    3.在preprocessors中增加'app/directives/chatroom/*.html':['ng-html2js']

    在这3步完成后,下面是我的测试文件,也通过测试了。

     1 /**
     2  * Created by taox on 15-6-30.
     3  */
     4 describe('Unit:Directives',function(){
     5   var scope,compile;
     6 
     7   beforeEach(module('chatroomDirective'));
     8   beforeEach(module('directives/chatroom/chatroom.html'));
     9   beforeEach(inject(function($compile,$rootScope){
    10     compile = $compile;
    11     scope = $rootScope;
    12   }));
    13 
    14   it('should content words 发送',function(){
    15     var ele = angular.element('<chatroom></chatroom>');
    16     var chatroom = compile(ele)(scope);
    17     scope.$digest();
    18     expect(chatroom.html()).toContain('发送');
    19   });
    20 });
    chatroomDirectiveSpec

    但是如果我在模板中绑定了ng-controller,则会报错。有人知道怎么将controller绑定到模板上吗?如果有知道的,求在http://www.cnblogs.com/towersxu/p/4600298.html 上面留言。下面是为尝试将controller绑定到模板上的方法:

    /**
     * Created by taox on 15-6-30.
     */
    describe('Unit:Directives',function(){
      var scope,compile,chatroomCtrl;
    
      beforeEach(module('chatroomDirective'));
      beforeEach(module('directives/chatroom/chatroom.html'));
      beforeEach(inject(function($compile,$controller,$rootScope){
        compile = $compile;
        scope = $rootScope.$new();
        chatroomCtrl = $controller('chatroomCtrl',{$scope:scope,$routeParams:{roomId:'1'}});
      }));
    
      it('should display words 发送',function(){
        var ele = angular.element('<chatroom></chatroom>');
        var chatroom = compile(ele)(scope);
        scope.$digest();
        expect(chatroom.html()).toContain('发送');
      });
    });
    

      错误提示为:Unknown provider:$routeParamsProvider<- $routeParams <-chatroomCtrl.我在测试controller的时候就不会出现这个错误。

  • 相关阅读:
    大二下第十三周学习笔记
    对C++多态的一次小分析
    vs2015中用汇编(转)
    挖个坑
    ListCtrl
    获得进程完整路径的第二种方法
    The Meeting Place Cannot Be Changed(二分+eps精度)
    CodeForces 494A
    Anya and Ghosts CodeForces
    寒假给自己立个flag
  • 原文地址:https://www.cnblogs.com/towersxu/p/4600298.html
Copyright © 2020-2023  润新知