资讯专栏INFORMATION COLUMN

前端单元测试 实现教程 mocha + mochawesome + istanbul + sinon

AaronYuan / 3197人阅读

摘要:为什么要写单元测试减少提高代码质量,保证你的代码是可测试的放心重构当你每个方法都写了单元测试的时候,你每一个改动都会影响相应的单元测试,这样你不用费尽心思的考虑哪里会有影响,特别是复杂项目或非核心功能不易被测试到,从而导致的产生。

为什么要写单元测试

减少bug

提高代码质量,保证你的代码是可测试的

放心重构

当你每个方法都写了单元测试的时候,你每一个改动都会影响相应的单元测试,这样你不用费尽心思的考虑哪里会有影响,特别是复杂项目或非核心功能(不易被测试到),从而导致bug的产生。

当你的代码不可测试的时候,就得考虑你的代码是否需要重构的。好的代码应该是职责分明且单一,颗粒度小且易于测试。

当你重构时,特别是大范围的重构,你就有勇气和信心了。

那么单元测试需要有那些要素呢

测试框架

测试报表

测试覆盖率

断言

mock

测试框架选用 mocha 官方文档

安装

npm install mocha

package.json

"scripts": {
        "test": "mocha --recursive --require babel-core/register tests/Js/test"
    }

mocha默认会找到项目的根目录下的 test目录,但是很多人项目目录中单元测试目录并不是test,而是在/tests/Js/test中,在scripts中,后面加上单元测试路径,就可以修改默认地址

recursive参数代表查找 目录的所有子目录下的单元测试,否则只会查找当前目录下的单元测试

node中并不支持某些es6语法,需要通过babel编译,所以需要添加 --require babel-core/register

同时需要在项目根目录添加.babelrc文件

{
  "presets": [ "es2015" ]
}

现在在 tests/Js/test目录下创建一个文件 test.js

var assert = require("assert");
describe("Array", function() {
  describe("#indexOf()", function() {
    it("should return -1 when the value is not present", function() {
      assert.equal([1,2,3].indexOf(4), -1);
    });
  });
});

命令行中执行 npm run test 结果如下

以上我们知道了如何引入前端测试框架,es6语法问题,执行路径问题

有时候命令行的结果看着不明了,想要输出测试报告呢
这时候可以使用 mochawesome
安装

npm install --save-dev mochawesome

package.json

"scripts": {
        "test": "mocha --recursive --reporter mochawesome --require babel-core/register tests/Js/test"
    }

在scripts命令中,添加 --reporter mochawesome
执行命令

npm run test

结果如图,将会生成 html文件和json文件

"代码覆盖率"(code coverage)。它有四个测量维度。

行覆盖率(line coverage):是否每一行都执行了

函数覆盖率(function coverage):是否每个函数都调用了

分支覆盖率(branch coverage):是否每个if代码块都执行了

语句覆盖率(statement coverage):是否每个语句都执行了

那么如何知道每个js的覆盖率呢
这时候用到了 istanbul 和 babel-istanbul
安装

npm install istanbul
npm install babel-istanbul

package.json

"scripts": {
     "test:cover": "babel-node ./node_modules/.bin/babel-istanbul cover _mocha -- tests/Js/* -R spec --recursive
    }

istanbul他也是不支持一些es6语法的,所以也需要babel转译
使用cover参数结合mocha,--代表后面参数传递给mocha

执行命令

npm run test:cover

结果如图

Mocha本身不带断言库,所以必须先引入断言库。
我们这里使用 chai

npm install chai

chaijs有三种断言风格,详细查看官网

jquery作为大部分都在使用的库,那么如何对这类的代码进行单元测试呢
比如以下代码
hide-element.js

export const hideElement = ($element) => {
  $element.on("click", ".hide", function() {
    $(this).hide();
  });
};

首先node环境和浏览器环境是不一样的,所以我们跑这类的单元测试就需要模拟出浏览器环境
我们需要安装 jsdom

npm install jsdom

test.js 如下

const assert = require("chai").assert;
const { hideElement } = require("xxxx/hide-element.js");
describe("test:hide-element.js", function(done) {
  before(function() {
    let { JSDOM } = require("jsdom");
    let dom = new JSDOM(`
`,{ url: "http://127.0.0.1/", referrer: "http://127.0.0.1/", contentType: "text/html", userAgent: "Mellblomenator/9000", includeNodeLocations: true, }); global.window = dom.window; global.$ = require("jquery"); hideElement($("body")); }); it("click event", function() { $("body").find(".hide").trigger("click"); assert.equal($(".hide").css("display"), "none"); }); });

mocha 由 describe,it基本元素组成

mocha 有四个钩子函数 before,after,beforeEach,afterEach

因为node中引入依赖时会缓存模块,初始化jsdom环境时,最好在before中,防止污染jsdom环境,导致不同的单元测试之间互相影响

需要测试的代码中依赖了其他的模块时,为了测试需要测试的代码,而不去关心依赖的模块,这时候我们需要 sinon 去mock掉相关依赖

demo.js

import api from "api";
export const demo = (arg) => {
    if (arg == 1) {
      return api.get({
        params: params
      });
    }
    
    return "ok";
};

test.js

import { demo } from "xx/demo.js";
const assert = require("chai").assert;
const sinon = require("sinon");
import api from "api";

describe("demo", function() {
  it("demo(1)", function() {
    //mock api的get方法,并且指定返回值为 "N"
    let apiGet = sinon.stub(api, "get").returns("N");
    let expectedParams = {params: "yes"};
    let res = demo(1);
    //automate clean-up,防止影响其他单元测试
    apiGet.restore();
    //断言调用api.get 是传入的参数为 {params: "yes"}
    sinon.assert.calledWith(apiGet, expectedParams);
    
    assert.equal(res, "N");
  });
});

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93583.html

相关文章

  • 如何使用 mochasinon 集成单元测试--单元测试示例及分析(上)

    摘要:使用集成单元测试上项目地址安装依赖测试框架可视化报表覆盖率替换依赖断言命令命令命令执行单元测试,并打开测试报告页面和覆盖率页面执行生成单元测试覆盖率并打开执行单个单元测试文 使用 mocha 集成单元测试(上) 项目地址:https://github.com/Jay-tian/j... 安装依赖 yarn add jquery mocha mochawesome istanbu...

    Caicloud 评论0 收藏0
  • mocha、chai、sinonistanbul实现100%单元测试覆盖率

    摘要:加上测试覆盖率检查,就能够提供足够的信息,来断言代码的行为是否符合期望。测试的相关技术是程序的代码覆盖率工具,以土耳其最大城市伊斯坦布尔命名。 showImg(https://segmentfault.com/img/remote/1460000010260434); 敏捷软件开发中,最重要实践的就是测试驱动开发,在单元测试层面,我们试着实现一个重要的指标就是测试覆盖率。测试覆盖率衡量...

    Yuanf 评论0 收藏0
  • 【Node Hero】9. Node.js 单元测试

    摘要:基本上,测试金字塔描述你应该编写单元测试集成测试和端到端测试。集成测试要比端到端测试多,单元测试甚至要更多一些。应用程序单元测试编写单元测试,是为了看看给定的模块单元是否工作。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1754原文:https://blog.risingstack.com/node-hero-node-js-un...

    104828720 评论0 收藏0
  • 前端单元测试初探

    摘要:本文只讨论单测的范畴,对集成测试有兴趣的话,可以看下的集成测试代码。前端单测现状测试本质上就是假定一个输入,然后判断得到预期的输出。 原文发于我的博客:https://github.com/hwen/blogS... 要不要写单测? 关于这个 cnode 上就有个很有意思的讨论 做个调查,你的 Node 应用有写单测吗? 看完这个应该会有结论?如果没有,就回帖跟别人探讨下~ 测试 测试...

    isLishude 评论0 收藏0
  • ES6+mocha+istanbul,针对ES6语法的带覆盖率检查的mocha测试

    摘要:安装注意版本为为支持语法安装依赖包注意为了使支持语法,在加入注意为了使支持语法,在加入小猫快跳最终运行或都可以参考 安装 mocha, chai,mochawesome,istanbul npm install mocha chai mochawesome istanbul@1.0.0-alpha.2 --save-dev 注意1: istanbul 版本为 ^1.0.0-alpha....

    wuyangnju 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<