本篇博客主要就是针对现在日新月异的技术和快速开发,测试被很多人忽略,其实在开发中如何保证代码的质量以及逻辑的完整性,测试显得十分重要,本文就是负责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");
  });

});

karma和jasmine的测试(包括angular测试)的更多相关文章

  1. 使用PowerMockito和Mockito进行模拟测试,包括静态方法测试,私有方法测试等,以及方法执行的坑或者模拟不成功解决

    依赖:这个很重要,不同版本用法也有点区别: <dependency> <groupId>org.mockito</groupId> <artifactId&g ...

  2. angular测试-Karma + Jasmine配置

    首先讲一下大致的流程: 需要node环境,首先先要安装node,node不会?请自行搜索.版本>0.8 安装node完成之后先要测试下npm是否测试通过,如下图所示 首先看下目录结构 目录为:F ...

  3. 用Karma和Jasmine测试Angular应用

    TEST: Before you've written any of the code, you know how you want it to behave. You have a specific ...

  4. 基于Karma和Jasmine的AngularJS测试

    1:工程目录结构 y@y:karma-t01$ tree -L 3.├── client│   ├── app│   │   └── user│   ├── bower_components│   │ ...

  5. karma+requirejs+angular 测试

    http://karma-runner.github.io/0.8/plus/RequireJS.html karma 不是测试框架,只是一个运行测试框架的服务器 karma测试的原理是,将所有的文件 ...

  6. Karma和Jasmine自动化单元测试——本质上还是在要开一个浏览器来做测试

    1. Karma的介绍 Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma.Karma是一个让人感到非常神秘的 ...

  7. Angular测试遇到的小坑

    Angular测试遇到的小坑 Error: Expected to be running in 'ProxyZone', but it was not found 检查doneFn的写法是否正确,位置 ...

  8. Karma:1. 集成 Karma 和 Jasmine 进行单元测试

    关于 Karma 会是一个系列,讨论在各种环境下,使用 Karma 进行单元测试. 本文讨论 karma 集成 Jasmine 进行单元测试. 初始化 NPM 实现初始化 NPM 包管理,创建 pac ...

  9. 基于karma和jasmine的Angularjs 单元测试

    Angularjs 基于karma和jasmine的单元测试 目录: 1. 单元测试的配置 2. 实例文件目录解释 3. 测试controller     3.1 测试controller中变量值是否 ...

随机推荐

  1. adb常用命令(手机测试)

                                                   ADB安装与常用命令详解 一.ADB意义 adb的全称为Android Debug Bridge,就是起到 ...

  2. 第十六篇 Python之迭代器与生成器

    一.迭代器 一. 递归和迭代 生活实例说明什么是递归和迭代 A想去腾达大厦,问B怎么走路,B 说我不知道,我给你问问C,C也不知道,C又去问D,D知道,把路告诉了C,C又告诉B,B最后告诉A, 这就是 ...

  3. redux使用过程中遇到的两个致命的关键点

    一.在reducer中,返回的state必须是全新的对象,否则,redux不会执行listening方法,因为redux会认为state没有更新过,没必要重新渲染view. 出现问题的例子: cons ...

  4. Gym101981I Magic Potion(最大流)

    Problem I. Magic Potion There are n heroes and m monsters living in an island. The monsters became v ...

  5. Halcon17对硬件配置要求

     Halcon17对硬件配置要求 Halcon17已经发布出来了,很多朋友一定想安装这款机器视觉软件来学习,我们今天给大家讲解下,Halcon17对硬件配置的要求: Halcon17 For Wind ...

  6. c++调用Python基础功能

    c++调用Python首先安装Python,以win7为例,Python路径为:c:\Python35\,通过mingw编译c++代码.编写makefile文件,首先要添加包含路径:inc_path ...

  7. POJ 3076 / ZOJ 3122 Sudoku(DLX)

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  8. @section script{}的使用

    1,MVC视图中,JS代码被放在下面的Razor代码中(@section script{}) 2,这样做的好处是:在视图进行JS编码时是一个很好 的实践,在共享视图(_layout.cshtml),存 ...

  9. [C/C++] 智能指针学习

    转自:http://blog.csdn.net/xt_xiaotian/article/details/5714477 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存 ...

  10. JavaScript归并方法reduce()和reduceRight()

    ECMAScript 5还新增了两个归并数组的方法:reduce()和reduceRight().这两个方法都会迭代数组的所有项,然后构建一个最终返回的值.其中,reduce()方法从数组的第一项开始 ...