karma和jasmine的測試(包括angular測試)


 本篇博客主要就是針對現在日新月異的技術和快速開發,測試被很多人忽略,其實在開發中如何保證代碼的質量以及邏輯的完整性,測試顯得十分重要,本文就是負責karma+jasmine來測試。

1.搭建測試的環境
首先需要確保電腦裝有node,低版本的node,在下載karma和jasmine會出現問題,建議低版本下載的包的版本如下:

{
"name": "karma-jsmin",
"version": "1.0.0",
"description": "",
"main": "karma.conf.js",
"directories": {
"test": "test"
},
"dependencies": {
"jasmine-core": "^2.5.2",
"karma": "^0.12.33",
"karma-chrome-launcher": "^2.0.0",
"karma-jasmine": "^1.1.0"
},
"devDependencies": {},
"scripts": {
"test": "node node_modules/karma/bin/karma start"
},
"author": "",
"license": "ISC"
}

將上述的包復制到你要下載的package.json文件中,使用npm install下載,其中script中的test是快捷方式,這里在命令窗口輸入npm run test,默認就會執行test對應后面的node node_modules/karma/bin/karma start,可以自定義自己的快捷方式。運行npm run test,看看是否報錯,如果報錯,去往這個網址照着修改 http://www.tuicool.com/articles/ZNbiqeI。
在高版本的node一般不會出現問題,下載jasmine-core,karma,karma-chrome-launcher,karma-coverage(測試代碼覆蓋率),karma-jasmine,這個時候如果你下載了全局的karma,則在你的文件夾下打開命令窗口輸入karma init,就會出現一個配置信息,一路回車就會生成一個karma.conf.js的文件,里面的解釋如下:

// Karma configuration
// Generated on Thu Apr 20 2017 10:43:31 GMT+0800 (中國標准時間)

module.exports = function(config) {
config.set({
/**
*如果所有文件處於同樣的路徑,則可以在這里配置基礎的路徑,用在files,exclude屬性上
*例如 dest/one.js 和 dest/one-test.js 這里配置dest/
*后面的files就可以寫成['one.js','one-test.js']*/
basePath: '',

/**
* 測試框架
* 可用的框架:jasmine,mocha...
*/
frameworks: ['jasmine'],

// 需要測試的文件
files: [

// 'need/app.js',
// 'test/app-test.js'
'angular/angular.js',
'angular/angular-mocks.js',
'ng-js/filter.js',
'ng-test-js/filter-test.js'
],

/**
* 排除的文件列表
*/
exclude: ['karma.conf.js'],

//預處理程序,
// preprocessors: {
// 'test/**/*.js': ['webpack', 'coverage'] //新增 coverage為覆蓋率測試
// },
preprocessors: {
'ng-js/demo1.js':'coverage'

},

/**
* 使用測試結果報告者
* 可能的值: "dots", "progress"
* 可用的報告者:https://npmjs.org/browse/keyword/karma-reporter
*/
reporters: ['progress','coverage'],

//在coverage目錄下生成html文件,用來監測這個測試項目的功能是否完全
coverageReporter:{
type:'html',
dir:'coverage/'
},

// 測試執行會打開一個頁面,就是這個頁面的端口,可以隨意設置
port: 9876,

//啟用或禁用輸出報告或者日志中的顏色
// 測試命令執行的時候,出錯誤或者測試不通過顯示不同的顏色,否則只有白色,
colors: true,

/**
* 日志等級
* 可能的值:
* config.LOG_DISABLE //不輸出信息
* config.LOG_ERROR //只輸出錯誤信息
* config.LOG_WARN //只輸出警告信息
* config.LOG_INFO //輸出全部信息
* config.LOG_DEBUG //輸出調試信息
*/
logLevel: config.LOG_INFO,

// 是否自動監測測試文件的改動並及時重新測試
autoWatch: true,

// 測試執行打開的頁面,可以使用火狐,ie,Opera等瀏覽器
browsers: ['Chrome'],

/**
* 開啟或禁用持續集成模式
* 設置為true, Karma將打開瀏覽器,執行測試並最后退出
*/

singleRun: false
});
};

 
如果沒有下在全局的karma,則為了方便執行,在你的package.json里面script里面寫入如下的兩個屬性:

"scripts": {
"test": "node node_modules/karma/bin/karma start",
"init": "node node_modules/karma/bin/karma init"
},

其中test是測試時候執行的,init是生成karma.conf.js配置文件執行的,此時執行npm run init 就會生成karma.conf.js文件配置,一路回車就行。你的文件夾的目錄最好是下面這樣的,
js文件是你寫的js代碼(待測試),test文件夾是你針對js文件夾里面每個文件寫的測試代碼。
2.下面就來寫第一個測試代碼吧,在js下面創建one.js,里面的是一個函數,如下:

function add(x,y){
  return x+y;
}

然后在你的test文件夾下面創建one-test.js文件,里面的測試代碼如下:
describe("測試加法", function () {//describe就是對這次測試的整體描述,如:加法測試
   it("3+5=8", function () {//it是對個測試的描述,如:3+5應該等於8
     expect(add(3, 5)).toEqual(8);//期待add(3,5)的結果等於8
   });
});
寫好上述代碼之后,並且在你的karma.conf.js的files里面引入:

files: [
  "js/one.js",
  "test/one-test.js"
],

 ,然后執行npm  run test,命令行不出現紅色,並且會自動彈出瀏覽器代表執行成功。打開瀏覽器的debug,按下F12查看,可以看到console里面輸出:
SUCCESS 測試加法 3+5=8
Skipped 0 tests
3.如何測試angular代碼
首先在你的karma.conf.js文件中的files里面引入相應版本的angular和angular-mocks.js(重要)
3.1測試controller:
在js里面創建ng-demo.js:代碼如下

var app = angular.module('demoApp', []);
//在測試之前要先引入angular以及對應版本的angular-mock
app.controller('test1Ctrl',function($scope){
  $scope.name = "app"

  $scope.num = 0;
  $scope.incrementNum = function () {
    $scope.num++;
  }
})

然后在你的test文件夾創建ng-demo-test.js,代碼如下:

/*beforeEach 用來做測試前的准備工作,
inject利用angular的依賴注入,將需要的模塊,服務插入作用域。真正的測試代碼在it函數里,*/


describe('第一個angular測試',function(){
  var scope;

  //beforeEach 表示在運行所有測試前的准備工作。
  //這里生成demoApp 的module

  beforeEach(module('demoApp'));//模擬我們的demoApp模塊並注入我們自己的依賴

  beforeEach(inject(function($rootScope,$controller){//inject解決依賴關系注入到一個函數。
    //模擬生成scope, $rootScope是angular中的頂級scope,angular中每個controller中的
    //scope都是rootScope new出來的

    scope = $rootScope.$new();//把全局scope等於new出來的scope
    //模擬生成controller並且注入已創建的空的 scope
    $controller('test1Ctrl', {$scope: scope});//把這個全局的scope和測試的angular的controller里面的$scope連通
  }))

  it("scope里面的 name 為 app", function () {
    expect(scope.name).toEqual('bpp');
  })

  it('incrementNum執行后,scope內的num變成1',function(){
    scope.incrementNum()//執行scope內的incrementNum函數
  expect(scope.num).toEqual(1);
})

})

在你的karma.conf.js的files引入這個兩個文件,執行npm  run test即可;
3.2測試directive

var app = angular.module('demoApp', [])
  .directive("unorderedList", function () {
    return function (scope, element, attrs) {
    var data = scope[attrs["unorderedList"]];

    if (angular.isArray(data)) {
      var listElem = angular.element("<ul>");
      element.append(listElem);
      for (var i = 0; i < data.length; i++) {
        listElem.append(angular.element('<li>').text(data[i].name));
      }
    }
  }
})

測試代碼如下:

describe('directive的測試',function(){
  var scope={},
  compileServer;

  beforeEach(module("demoApp"));

  //我們需要一個叫做$compile的服務來完成實際的編譯
  beforeEach(inject(function ($rootScope, $compile) {
    compileService = $compile;

    //模擬scope里面的數據
    scope.data = [
    { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },
    { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },
    { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 }];
  }));

  it("創建列表的元素", function () {
    /*在要被測試的scope中,一個directive需要被compiled(也就是下面代碼中的$compile(tpl)(scope);這句話在做的事情)*/
    var elem = compileService("<div unordered-list='data'></div>")(scope);//$compile(html)(scope);
    //我們將這個元素編譯到一個作用域,它現在就可以被測試了

    // var elem = compileFn(scope);

    expect(elem.children("ul").length).toEqual(1);
    expect(elem.find("li").length).toEqual(3);

    expect(elem.find("li").eq(0).text()).toEqual("Apples");
    expect(elem.find("li").eq(1).text()).toEqual("Bananas");
    expect(elem.find("li").eq(2).text()).toEqual("Pears");
  });
})

3.3測試filter

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

  app.filter("labelCase", function () {
    return function (value) {
      return value.toUpperCase()
    };
  })

測試代碼:

describe("Filter的測試", function () {

  var filterInstance;

  beforeEach(module("demoApp"));//模塊

  beforeEach(inject(function (labelCaseFilter) {
  //引入需要測試的filter
    filterInstance = labelCaseFilter;
  }));


  it("test phrase經過過濾器后變成 TEST PHRASE", function () {
    var result = filterInstance("test phrase");
    expect(result).toEqual("TEST PHRASE");
  });

});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM