九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
說說NG里的單元測(cè)試

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


什么是Karma

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

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

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

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

  "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è)普通的例子如下

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)聽上面文件的改變自動(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)開發(fā)的測(cè)試框架,不依賴任何js框架以及dom,是一個(gè)非常干凈以及友好API的測(cè)試庫(kù).

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

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

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);  });});

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

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

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

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

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

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

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

karma start test/karma.conf.js

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

NG的單元測(cè)試

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

下面說說ng-mock里的一些常用方法

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

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

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

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

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

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

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)置的依賴注入實(shí)例,然后里面的模塊注入跟普通ng模塊里的依賴處理是一樣的

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

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

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

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!";});

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

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

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

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

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

var app = angular.module('myApp', []);app.directive('aGreatEye', function () {    return {        restrict: 'E',        replace: true,        template: '<h1>lidless, wreathed in flame, {{1 + 1}} times</h1>'    };});

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

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 + 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");    });});

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

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

測(cè)試腳本里首先注入$compile$rootScope兩個(gè)服務(wù),一個(gè)用來編譯html,一個(gè)用來創(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來觸發(fā)所有監(jiān)聽,保證視圖里的模型內(nèi)容得到更新

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

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

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

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

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

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

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');    }));  });});

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

總結(jié)

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

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用超動(dòng)感HTML & JS開發(fā)WEB應(yīng)用! | AngularJS中文社區(qū)
Angularjs十大經(jīng)典面試題
Angular-UI Bootstrap組件實(shí)現(xiàn)警報(bào)
《Angular項(xiàng)目實(shí)戰(zhàn)》08 智慧工廠權(quán)限管理模塊寫字字帖
(六)使用angular.bootstrap完成模塊的手動(dòng)加載
javascript-使用Karma&Mocha.js對(duì)多個(gè)用例進(jìn)行單元測(cè)試
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服