资讯专栏INFORMATION COLUMN

mocha+power-assert+istanbul测试库基础用法

ingood / 1296人阅读

摘要:块就是测试用例,表示一个多带带的测试,块可以包含多个断言块块就是断言,判断预期结果和执行结果是否一致失败的话会打印错误提示注意因为箭头函数不能够访问的上下文,所以在需要用到上下文的时候不能使用,否则报错。

前言

我的英文水平有点渣,所以就贴上原文给你们自己翻译了,还有github地址,如果发现有些中文文档的话也会顺便赠送飞机票

mocha
Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases. Hosted on GitHub.

Mocha是一个能在nodejs和浏览器环境运行的有着丰富功能的javascript测试框架,使异步测试变得简单有趣,Mocha测试持续运行,能获得灵活和精确的报告,当发生未知错误能映射到正确的测试案例.
Mocha地址
Mocha中文文档
是一个很出名的测试框架了,估计有接触过测试代码的人都知道的东西

安装

npm install --global mocha

运行终端

mocha

系统会自动搜索当前目录下的test.js文件运行

should
should is an expressive, readable, framework-agnostic assertion library. The main goals of this library are to be expressive and to be helpful. It keeps your test code clean, and your error messages helpful.

By default (when you require("should")) should extends the Object.prototype with a single non-enumerable getter that allows you to express how that object should behave. It also returns itself when required with require.

It is also possible to use should.js without getter (it will not even try to extend Object.prototype), just require("should/as-function"). Or if you already use version that auto add getter, you can call .noConflict function.

Results of (something).should getter and should(something) in most situations are the same

should是一个可表达性,可阅读性,与框架无关的断言库,这个库的主要目标是变得可表达和可帮助,它使你的测试代码整洁和有帮助的错误信息.
默认(当你引入should)会在对象原型上扩展一个多带带不可枚举的getter允许你去表达该对象应该的行为方式,当需要的时候它总是返回本身
它也可以在没有getter扩展的情况下使用(甚至不会尝试去扩展对象原型),只要引入(‘should/as-function’),或者如果你已经使用自动添加getter的版本,你能调用无冲突函数.
Results of (something).should getter 和 should(something) 在大多数情况下都是一样的
should.js地址
安装

npm install should --save-dev

断言库多种多样,这是比较出名的一款,但是个人感觉不好用,复杂的API,冗长的代码,推荐下面那一款

power-assert
Power Assert in JavaScript. Provides descriptive assertion messages through standard assert interface. No API is the best API.

power-assert在JS中通过标準的接口提供了描述性断言信息,没有API就是最好的API
power-assert地址
可以通过一行代码直观感受一下两个断言库的代码

should.js: (1).should.eql(10);
assert.js:  assert(1 === 10);
istanbul
Yet another JS code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests and browser tests. Built for scale.

另一个js代码覆盖工具,当运行的时候会通过模块加载钩子去计算语句,行,函和分支覆盖以明显地添加覆盖率,支持所有js覆盖使用案例包括单元测试,服务端函数式测试和浏览器测试,构建测试用例
istanbul地址

基本讲解

describe块就是测试套件,表示一组相关的测试,describe块里面可以包含多个describe块或者it块。
it块就是测试用例,表示一个多带带的测试,it块可以包含多个断言块
assert块就是断言,判断预期结果和执行结果是否一致,失败的话会打印错误提示
注意:因为箭头函数不能够访问mocha的上下文,所以在需要用到mocha上下文的时候不能使用,否则报错。

同步测试
const assert = require("assert");

describe("你成年了么?", () => {
  it("我已经不是3嵗小孩了!", () => {
    assert(3 > 18);
  });
});

打开终端运行命令

mocha

会得出如下结果

如果将代码换成assert(30 > 18)则如下

异步测试
const assert = require("assert");

function timer(ms) {
  return new Promise(resolve => setTimeout(() => resolve(3), ms));
}

describe("你成年了么?", () => {
  it("我已经不是3嵗小孩了!", async () => {
    const age = await timer(1000);
    assert(age > 18);
  });
});

钩子函数

mocha本身提供了多个钩子函数以供使用,官方摘抄如下:

run "mocha spec.js"
|
spawn child process
|
|--------------> inside child process
  process and apply options
  |
  run spec file/s
  |
  |--------------> per spec file
    suite callbacks (e.g., "describe")
    |
    "before" root-level pre-hook
    |
    "before" pre-hook
    |
    |--------------> per test
      "beforeEach" root-level pre-hook
      |
      "beforeEach" pre-hook
      |
      test callbacks (e.g., "it")
      |
      "afterEach" post-hook
      |
      "afterEach" root-level post-hook
    |<-------------- per test end
    |
    "after" post-hook
    |
    "after" root-level post-hooks
  |<-------------- per spec file end
|<-------------- inside child process end
const assert = require("assert");

let a = 1;

describe("你成年了么?", () => {
  before("beforeEach", () => console.log(`before: ${a}`));
  beforeEach("beforeEach", () => console.log(`beforeEach: ${a}`));
  afterEach("afterEach", () => console.log(`afterEach: ${a}`));
  after("afterEach", () => console.log(`after: ${a}`));

  it("我已经不是3嵗小孩了!", () => {
    a = 2;
    assert(30 > 18);
  });
});

流程控制only(),ship()

就如字面意思一样,可以用来控制测试用例只执行或者跳过某些用例而不是采用注释的方法来改变测试用例

const assert = require("assert");

describe("你成年了么?", () => {
  it.skip("我已经不是3嵗小孩了!", () => {
    assert(30 > 18);
  });
  it.only("我是3嵗小孩!", () => {
    assert(3 > 18);
  });
});


注意:流程控制不仅可以用在it块,也能用在describe块,例如:

const assert = require("assert");

describe("你成年了么?", () => {
  describe.skip("成年人", () => {
    it("我已经不是3嵗小孩了!", () => {
      assert(30 > 18);
    });
  });
  describe.only("未成年人", () => {
    it("我是3嵗小孩!", () => {
      assert(3 > 18);
    });
  });
});

多次测试retries()

有些时候不是一次测试就能达到要求的,mocha提供了retries()来设置重试次数,只要在超过次数并且都失败的情况下才会报错

const assert = require("assert");

describe("猜大小胜利的几率?", function() {
  it.only("我买大!", function() {
    this.retries(5);
    assert(Math.random() > 0.5);
  });
});

时间控制timeout()

如下所示:

const assert = require("assert");

function timer(ms) {
  return new Promise(resolve => setTimeout(() => resolve(3), ms));
}

describe("你成年了么?", function() {
  it("我已经不是3嵗小孩了!", async function() {
    this.timeout(500);
    const age = await timer(1000);
    assert(age > 18);
  });
});


注意:0是禁止超时,也可以用在钩子函数和describe块上

power-assert其他语法
assert(value, [message])
assert.ok(value, [message])
assert.equal(actual, expected, [message])
assert.notEqual(actual, expected, [message])
assert.strictEqual(actual, expected, [message])
assert.notStrictEqual(actual, expected, [message])
assert.deepEqual(actual, expected, [message])
assert.notDeepEqual(actual, expected, [message])
assert.deepStrictEqual(actual, expected, [message])
assert.notDeepStrictEqual(actual, expected, [message])

看起来种类繁多,其实都可以一个assert()实现,所以说No API is the best API。随便举个例子:

const assert = require("assert");

describe("全等比较?", function() {
  it("a和b全等么?", async function() {
    assert.deepStrictEqual(18, "18", "a和b不全等!");
  });
});

istanbul

我们用istanbul来做结尾吧,这是一个测试代码覆盖率的库,跟上面两个没什么关系。主要是以下四个维度来测试执行代码率

Statements   : 语句覆盖率
Branches : 分支覆盖率
Functions : 函数覆盖率
Lines : 行覆盖率

我们随便写一些加减乘除的测试代码

const a = 3,
  b = 18;

function add(a, b) {
  console.log(a + b);
}

function reduce() {
  console.log(a - b);
}

add(a, b);

然后运行

istanbul cover 你的js脚本名

![图片描述](attimg://article/content/picture/201810/07/151727srxavvairzrpyxvr.png)
然后当下目录还会生成一个coverage文件夹

具体作用我也没研究,但是里面的lcov-report是可以在浏览器打开的测试报告

结语

mocha作为常规测试库,power-assert是简约的断言库,搭配istanbul做代码覆盖率可以满足一个基本需求了,因为我本身不会用到这些东西只是简单了解基础用法,上面例子都是在编辑器终端运行,实际开发中会嵌入项目package.json做特殊处理,有兴趣的可自行研究。

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

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

相关文章

  • 前端单元测试初探

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

    isLishude 评论0 收藏0
  • 在Nodejs中贯彻单元测试

    摘要:原文链接在中贯彻单元测试在团队合作中,你写好了一个函数,供队友使用,跑去跟你的队友说,你传个值进去,他就会返回结果了。如果你也为社区贡献过,想更多人使用的话,加上单元测试吧,让你的值得别人信赖。 原文链接:BlueSun | 在Nodejs中贯彻单元测试 在团队合作中,你写好了一个函数,供队友使用,跑去跟你的队友说,你传个A值进去,他就会返回B结果了。过了一会,你队友跑过来说,我传个A...

    enali 评论0 收藏0
  • 聊一聊前端自动化测试

    摘要:在真正写了一段时间的基础组件和基础工具后,才发现自动化测试有很多好处。有了自动化测试,开发者会更加信任自己的代码。由于维护测试用例也是一大笔开销毕竟没有多少测试会专门帮前端写业务测试用例,而前端使用的流程自动化工具更是没有测试参与了。 本文转载自 天猫前端博客,更多精彩文章请进入天猫前端博客查看 前言 为何要测试 以前不喜欢写测试,主要是觉得编写和维护测试用例非常的浪费时间。在真正写了...

    wthee 评论0 收藏0
  • 前端单元测试 实现教程 mocha + mochawesome + istanbul + sinon

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

    AaronYuan 评论0 收藏0
  • 前端单元测试

    摘要:为保证代码的质量,单元测试必不可少。本文记录自己在学习单元测试过程中的一些总结。以一个项目为例,代码结构如下前端测试框架主要是与,这里我们选择,断言库有以及自带的。 为保证代码的质量,单元测试必不可少。本文记录自己在学习单元测试过程中的一些总结。 TDD与BDD的区别 TDD属于测试驱动开发,BDD属于行为驱动开发。个人理解其实就是TDD先写测试模块,再写主功能代码,然后能让测试模块通...

    liuyix 评论0 收藏0

发表评论

0条评论

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