欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

angularjs中的單元測(cè)試實(shí)例

 更新時(shí)間:2014年12月06日 10:44:35   投稿:junjie  
這篇文章主要介紹了angularjs中的單元測(cè)試實(shí)例,本文主要說(shuō)說(shuō)利用karma和jasmine來(lái)進(jìn)行ng模塊的單元測(cè)試,需要的朋友可以參考下

當(dāng)ng項(xiàng)目越來(lái)越大的時(shí)候,單元測(cè)試就要提上日程了,有的時(shí)候團(tuán)隊(duì)是以測(cè)試先行,有的是先實(shí)現(xiàn)功能,后面再測(cè)試功能模塊,這個(gè)各有利弊,今天主要說(shuō)說(shuō)利用karma和jasmine來(lái)進(jìn)行ng模塊的單元測(cè)試.

什么是Karma

karma是一個(gè)單元測(cè)試的運(yùn)行控制框架,提供以不同環(huán)境來(lái)運(yùn)行單元測(cè)試,比如chrome,firfox,phantomjs等,測(cè)試框架支持jasmine,mocha,qunit,是一個(gè)以nodejs為環(huán)境的npm模塊.

安裝測(cè)試相關(guān)的npm模塊建議使用----save-dev參數(shù),因?yàn)檫@是開(kāi)發(fā)相關(guān)的,一般的運(yùn)行karma的話(huà)只需要下面兩個(gè)npm命令

復(fù)制代碼 代碼如下:

npm install karma --save-dev
npm install karma-junit-reporter --save-dev

安裝karma的時(shí)候會(huì)自動(dòng)的安裝一些常用的模塊,參考karma代碼里的package.json文件的peerDependencies屬性

復(fù)制代碼 代碼如下:

 "peerDependencies": {
        "karma-jasmine": "~0.1.0",
        "karma-requirejs": "~0.2.0",
        "karma-coffee-preprocessor": "~0.1.0",
        "karma-html2js-preprocessor": "~0.1.0",
        "karma-chrome-launcher": "~0.1.0",
        "karma-firefox-launcher": "~0.1.0",
        "karma-phantomjs-launcher": "~0.1.0",
        "karma-script-launcher": "~0.1.0"
  }

然后一個(gè)典型的運(yùn)行框架通常都需要一個(gè)配置文件,在karma里可以是一個(gè)karma.conf.js,里面的代碼是一個(gè)nodejs風(fēng)格的,一個(gè)普通的例子如下:

復(fù)制代碼 代碼如下:

module.exports = function(config){
  config.set({
    // 下面files里的基礎(chǔ)目錄
    basePath : '../',
    // 測(cè)試環(huán)境需要加載的JS信息
    files : [
      'app/bower_components/angular/angular.js',
      'app/bower_components/angular-route/angular-route.js',
      'app/bower_components/angular-mocks/angular-mocks.js',
      'app/js/**/*.js',
      'test/unit/**/*.js'
    ],
    // 是否自動(dòng)監(jiān)聽(tīng)上面文件的改變自動(dòng)運(yùn)行測(cè)試
    autoWatch : true,
    // 應(yīng)用的測(cè)試框架
    frameworks: ['jasmine'],
    // 用什么環(huán)境測(cè)試代碼,這里是chrome`
    browsers : ['Chrome'],
    // 用到的插件,比如chrome瀏覽器與jasmine插件
    plugins : [
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-jasmine',
            'karma-junit-reporter'
            ],
    // 測(cè)試內(nèi)容的輸出以及導(dǎo)出用的模塊名
    reporters: ['progress', 'junit'],
    // 設(shè)置輸出測(cè)試內(nèi)容文件的信息
    junitReporter : {
      outputFile: 'test_out/unit.xml',
      suite: 'unit'
    }

  });
};

這里要注意的時(shí),上面的插件大部分都不需要單獨(dú)安裝,因?yàn)榘惭bkarma的時(shí)候已經(jīng)安裝了,這里只有karma-junit-reporter導(dǎo)出插件需要單獨(dú)安裝,想要了解更多的關(guān)于配置文件的信息可以,點(diǎn)擊這里

karma就講到這里,想了解更多關(guān)于它的信息可以,點(diǎn)擊這里

什么是jasmine

Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.

上面是jasmine官方文檔里對(duì)它的解釋,下面用中文簡(jiǎn)單的翻譯下

jasmine是一個(gè)行為驅(qū)動(dòng)開(kāi)發(fā)的測(cè)試框架,不依賴(lài)任何js框架以及dom,是一個(gè)非常干凈以及友好API的測(cè)試庫(kù).

下面簡(jiǎn)單的以一個(gè)例子來(lái)說(shuō)明它的用法

定義一個(gè)測(cè)試文件命令為test.js

復(fù)制代碼 代碼如下:

describe("A spec (with setup and tear-down)", function() {
  var foo;

  beforeEach(function() {
    foo = 0;
    foo += 1;
  });

  afterEach(function() {
    foo = 0;
  });

  it("is just a function, so it can contain any code", function() {
    expect(foo).toEqual(1);
  });

  it("can have more than one expectation", function() {
    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });
});

上面的例子來(lái)自于官網(wǎng),這里只說(shuō)下幾個(gè)重要的API,更多的用法請(qǐng),點(diǎn)擊這里

1.首先任何一個(gè)測(cè)試用例以describe函數(shù)來(lái)定義,它有兩參數(shù),第一個(gè)用來(lái)描述測(cè)試大體的中心內(nèi)容,第二個(gè)參數(shù)是一個(gè)函數(shù),里面寫(xiě)一些真實(shí)的測(cè)試代碼

2.it是用來(lái)定義單個(gè)具體測(cè)試任務(wù),也有兩個(gè)參數(shù),第一個(gè)用來(lái)描述測(cè)試內(nèi)容,第二個(gè)參數(shù)是一個(gè)函數(shù),里面存放一些測(cè)試方法

3.expect主要用來(lái)計(jì)算一個(gè)變量或者一個(gè)表達(dá)式的值,然后用來(lái)跟期望的值比較或者做一些其它的事件

4.beforeEach與afterEach主要是用來(lái)在執(zhí)行測(cè)試任務(wù)之前和之后做一些事情,上面的例子就是在執(zhí)行之前改變變量的值,然后在執(zhí)行完成之后重置變量的值

最后要說(shuō)的是,describe函數(shù)里的作用域跟普通JS一樣都是可以在里面的子函數(shù)里訪(fǎng)問(wèn)的,就像上面的it訪(fǎng)問(wèn)foo變量

想要運(yùn)行上面的測(cè)試?yán)涌梢酝ㄟ^(guò)karar來(lái)運(yùn)行,命令例子如下:

復(fù)制代碼 代碼如下:

karma start test/karma.conf.js

下面我們重點(diǎn)的說(shuō)說(shuō)ng里的控制器,指令,服務(wù)模塊的單元測(cè)試.

NG的單元測(cè)試

因?yàn)閚g本身框架的原因,模塊都是通過(guò)di來(lái)加載以及實(shí)例化的,所以為了方便配合jasmine來(lái)編寫(xiě)測(cè)試腳本,所以官方提供了angular-mock.js的一個(gè)測(cè)試工具類(lèi)來(lái)提供模塊定義,加載,注入等.

下面說(shuō)說(shuō)ng-mock里的一些常用方法

1.angular.mock.module 此方法同樣在window命名空間下,非常方便調(diào)用

module是用來(lái)配置inject方法注入的模塊信息,參數(shù)可以是字符串,函數(shù),對(duì)象,可以像下面這樣使用

復(fù)制代碼 代碼如下:

beforeEach(module('myApp.filters'));

beforeEach(module(function($provide) {
      $provide.value('version', 'TEST_VER');
}));

它一般用在beforeEach方法里,因?yàn)檫@個(gè)可以確保在執(zhí)行測(cè)試任務(wù)的時(shí)候,inject方法可以獲取到模塊配置

1.angular.mock.inject 此方法同樣在window命名空間下,非常方便調(diào)用

inject是用來(lái)注入上面配置好的ng模塊,方面在it的測(cè)試函數(shù)里調(diào)用,常見(jiàn)的調(diào)用例子如下:

復(fù)制代碼 代碼如下:

angular.module('myApplicationModule', [])
      .value('mode', 'app')
      .value('version', 'v1.0.1');


  describe('MyApp', function() {

    // You need to load modules that you want to test,
    // it loads only the "ng" module by default.
    beforeEach(module('myApplicationModule'));


    // inject() is used to inject arguments of all given functions
    it('should provide a version', inject(function(mode, version) {
      expect(version).toEqual('v1.0.1');
      expect(mode).toEqual('app');
    }));


    // The inject and module method can also be used inside of the it or beforeEach
    it('should override a version and test the new version is injected', function() {
      // module() takes functions or strings (module aliases)
      module(function($provide) {
        $provide.value('version', 'overridden'); // override version here
      });

      inject(function(version) {
        expect(version).toEqual('overridden');
      });
    });
  });

上面是官方提供的一些inject例子,代碼很好看懂,其實(shí)inject里面就是利用angular.inject方法創(chuàng)建的一個(gè)內(nèi)置的依賴(lài)注入實(shí)例,然后里面的模塊注入跟普通ng模塊里的依賴(lài)處理是一樣的

簡(jiǎn)單的介紹完ng-mock之后,下面我們分別以控制器,指令,過(guò)濾器來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的單元測(cè)試.

ng里控制器的單元測(cè)試

定義一個(gè)簡(jiǎn)單的控制器

復(fù)制代碼 代碼如下:

var myApp = angular.module('myApp',[]);

    myApp.controller('MyController', function($scope) {
      $scope.spices = [{"name":"pasilla", "spiciness":"mild"},
                       {"name":"jalapeno", "spiciness":"hot hot hot!"},
                       {"name":"habanero", "spiciness":"LAVA HOT!!"}];
      $scope.spice = "hello feenan!";
});

然后我們編寫(xiě)一個(gè)測(cè)試腳本

復(fù)制代碼 代碼如下:

describe('myController function', function() {

  describe('myController', function() {
    var $scope;

    beforeEach(module('myApp'));

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

    it('should create "spices" model with 3 spices', function() {
      expect($scope.spices.length).toBe(3);
    });

    it('should set the default value of spice', function() {
      expect($scope.spice).toBe('hello feenan!');
    });
  });

});

上面利用了$rootScope來(lái)創(chuàng)建子作用域,然后把這個(gè)參數(shù)傳進(jìn)控制器的構(gòu)建方法$controller里去,最終會(huì)執(zhí)行上面的控制器里的方法,然后我們檢查子作用域里的數(shù)組數(shù)量以及字符串變量是否跟期望的值相等.

想要了解更多關(guān)于ng里的控制器的信息,可以點(diǎn)擊這里

ng里指令的單元測(cè)試

定義一個(gè)簡(jiǎn)單的指令

復(fù)制代碼 代碼如下:

var app = angular.module('myApp', []);

app.directive('aGreatEye', function () {
    return {
        restrict: 'E',
        replace: true,
        template: '<h1>lidless, wreathed in flame, 1 times</h1>'
    };
});

然后我們編寫(xiě)一個(gè)簡(jiǎn)單的測(cè)試腳本

復(fù)制代碼 代碼如下:

describe('Unit testing great quotes', function() {
    var $compile;
    var $rootScope;

    // Load the myApp module, which contains the directive
    beforeEach(module('myApp'));

    // Store references to $rootScope and $compile
    // so they are available to all tests in this describe block
    beforeEach(inject(function(_$compile_, _$rootScope_){
      // The injector unwraps the underscores (_) from around the parameter names when matching
      $compile = _$compile_;
      $rootScope = _$rootScope_;
    }));

    it('Replaces the element with the appropriate content', function() {
        // Compile a piece of HTML containing the directive
        var element = $compile("<a-great-eye></a-great-eye>")($rootScope);
        // fire all the watches, so the scope expression 1 will be evaluated
        $rootScope.$digest();
        // Check that the compiled element contains the templated content
        expect(element.html()).toContain("lidless, wreathed in flame, 2 times");
    });
});

上面的例子來(lái)自于官方提供的,最終上面的指令將會(huì)這用在html里使用

復(fù)制代碼 代碼如下:

<a-great-eye></a-great-eye>

測(cè)試腳本里首先注入$compile與$rootScope兩個(gè)服務(wù),一個(gè)用來(lái)編譯html,一個(gè)用來(lái)創(chuàng)建作用域用,注意這里的_,默認(rèn)ng里注入的服務(wù)前后加上_時(shí),最后會(huì)被ng處理掉的,這兩個(gè)服務(wù)保存在內(nèi)部的兩個(gè)變量里,方便下面的測(cè)試用例能調(diào)用到

$compile方法傳入原指令html,然后在返回的函數(shù)里傳入$rootScope,這樣就完成了作用域與視圖的綁定,最后調(diào)用$rootScope.$digest來(lái)觸發(fā)所有監(jiān)聽(tīng),保證視圖里的模型內(nèi)容得到更新

然后獲取當(dāng)前指令對(duì)應(yīng)元素的html內(nèi)容與期望值進(jìn)行對(duì)比.

想要了解更多關(guān)于ng里的指令的信息,可以點(diǎn)擊這里

ng里的過(guò)濾器單元測(cè)試

定義一個(gè)簡(jiǎn)單的過(guò)濾器

復(fù)制代碼 代碼如下:

var app = angular.module('myApp', []);
app.filter('interpolate', ['version', function(version) {
    return function(text) {
      return String(text).replace(/\%VERSION\%/mg, version);
    };
  }]);

然后編寫(xiě)一個(gè)簡(jiǎn)單的測(cè)試腳本
復(fù)制代碼 代碼如下:

describe('filter', function() {
  beforeEach(module('myApp'));


  describe('interpolate', function() {

    beforeEach(module(function($provide) {
      $provide.value('version', 'TEST_VER');
    }));


    it('should replace VERSION', inject(function(interpolateFilter) {
      expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after');
    }));
  });
});

上面的代碼先配置過(guò)濾器模塊,然后定義一個(gè)version值,因?yàn)閕nterpolate依賴(lài)這個(gè)服務(wù),最后用inject注入interpolate過(guò)濾器,注意這里的過(guò)濾器后面得加上Filter后綴,最后傳入文本內(nèi)容到過(guò)濾器函數(shù)里執(zhí)行,與期望值進(jìn)行對(duì)比.

總結(jié)

利用測(cè)試來(lái)開(kāi)發(fā)NG有很多好處,可以保證模塊的穩(wěn)定性,還有一點(diǎn)就是能夠深入的了解ng的內(nèi)部運(yùn)行機(jī)制,所以建議用ng開(kāi)發(fā)的同學(xué)趕緊把測(cè)試補(bǔ)上吧!

相關(guān)文章

  • 詳解在A(yíng)ngular4中使用ng2-baidu-map的方法

    詳解在A(yíng)ngular4中使用ng2-baidu-map的方法

    這篇文章主要介紹了在A(yíng)ngular4中使用ng2-baidu-map的方法,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06
  • AngularJS 工作原理詳解

    AngularJS 工作原理詳解

    本文主要介紹AngularJS 工作原理,這里整理了相關(guān)資料及示例代碼,有興趣的小伙伴可以參考下
    2016-08-08
  • AngularJS初始化靜態(tài)模板詳解

    AngularJS初始化靜態(tài)模板詳解

    這篇文章主要為大家介紹了AngularJS初始化靜態(tài)模板,AngularJS初始化靜態(tài)模板有兩種方式,一是通過(guò)ng-app來(lái)自動(dòng)初始化模塊,也可以通過(guò)angular.bootstrap(document, [module])手動(dòng)啟動(dòng)應(yīng)用,感興趣的小伙伴們可以參考一下
    2016-01-01
  • angularjs性能優(yōu)化的方法

    angularjs性能優(yōu)化的方法

    這篇文章主要介紹了angularjs性能優(yōu)化的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • AngularJS服務(wù)service用法總結(jié)

    AngularJS服務(wù)service用法總結(jié)

    這篇文章主要介紹了AngularJS服務(wù)service用法,結(jié)合實(shí)例形式總結(jié)分析了服務(wù)Service的概念、功能及自定義服務(wù)的相關(guān)操作技巧,需要的朋友可以參考下
    2016-12-12
  • Angular7創(chuàng)建項(xiàng)目、組件、服務(wù)以及服務(wù)的使用

    Angular7創(chuàng)建項(xiàng)目、組件、服務(wù)以及服務(wù)的使用

    這篇文章主要介紹了Angular7創(chuàng)建項(xiàng)目、組件、服務(wù)以及服務(wù)的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • Angularjs 1.3 中的$parse實(shí)例代碼

    Angularjs 1.3 中的$parse實(shí)例代碼

    本文通過(guò)實(shí)例代碼給大家介紹了angularjs $parse的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-09-09
  • Angular7中創(chuàng)建組件/自定義指令/管道的方法實(shí)例詳解

    Angular7中創(chuàng)建組件/自定義指令/管道的方法實(shí)例詳解

    這篇文章主要介紹了在angular7中創(chuàng)建組件/自定義指令/管道的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-04-04
  • AngularJS實(shí)現(xiàn)多級(jí)下拉框

    AngularJS實(shí)現(xiàn)多級(jí)下拉框

    這篇文章主要為大家詳細(xì)介紹了AngularJS實(shí)現(xiàn)多級(jí)下拉框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • AngularJS ionic手勢(shì)事件的使用總結(jié)

    AngularJS ionic手勢(shì)事件的使用總結(jié)

    本篇文章主要介紹了AngularJS手勢(shì)事件的使用總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08

最新評(píng)論