引言

随着前端工程化这一概念的产生,项目开发中前端的代码量可谓是‘急剧上升’,所以在这种情况下,我们如何才能保证代码的质量呢,对于框架,比如React、Vue,因为有自己的语法规则,及时每个开发人员的编码风格规范各不相同,但最终的产出都大同小异,代码质量差距不是很大;但对于一些基础类库或方法的开发,我们就要谨慎又谨慎,代码质量一定要高,尽量避免出现Bug。

那我们如何做到产出高质量代码呢?单元测试才是正解,俗话说‘跳过单元测试和不仔细过冒烟就交由QA测试的,就是在耍流氓’(这句话是我自己编的);Mocha是针对Javascript的单元测试工具,下面我们就来看看如何使用它

概念

Mocha: Javascript测试框架

chai:断言库,需配合Mocha使用

最简单的用法

步骤一:安装

假设我们是在已有项目中进行单元测试

安装Mocha

/*全局安装*/
$ npm install --global mocha   /*局部安装*/
$ npm install --save-dev mocha

安装chai

/*局部安装*/
$ npm install --save-dev chai

全局与局部的区别:若是局部安装,依赖就会写入package.json的dependencies或devDependencies中,这样当别人从你的Github上克隆代码时,就不需要注意‘依赖包全不全啊’?‘还需不要安装其他依赖啊?’等等这类的问题,因为'npm install'会将所有依赖下载到本地

步骤二:编写Js源文件与测试文件

源文件

// add.js
1 function add(x, y) {
return x + y;
} module.exports = add;

测试文件

 // add.test.js
1 var add = require('./add.js');
var expect = require('chai').expect; describe('加法函数的测试', function() {
it('1 加 1 应该等于 2', function() {
expect(add(1, 1)).to.be.equal(2);
});
it('1 加 -1 应该等于 0', function() {
expect(add(1, -1)).to.be.equal(0);
});
});

步骤三:运行测试文件

$ mocha add.test.js

运行截图:

以上就是Mocha最简单的使用方式,细不细很简单啊O(∩_∩)O哈哈~,下面我们再看点进阶的

进阶之路

进阶一:describe和it是什么?

describe:"测试组",也称测试块,表示我要进行一系列测试,相当于一个group

it:"测试项",也称测试用例,表示这是"一系列测试"中的一项,相当于item,如何测试?测试逻辑?都是在it的回调函数中实现的

进阶二:什么?describe也有"生命周期"?

每个测试块(describe)有4个周期,分别是:

 describe('test', function() {
// 在本测试块的所有测试用例之前执行且仅执行一次
before(function() { });
// 在本测试块的所有测试用例之后执行且仅执行一次
after(function() { }); // 在测试块的每个测试用例之前执行(有几个测试用例it,就执行几次)
beforeEach(function() { });
// 在测试块的每个测试用例之后执行(同上)
afterEach(function() { }); // 测试用例
it('test item1', function () { })
});

进阶三:在进阶二中周期代码是ES6风格,需要安装babel模块转码

这里分两种情况:1.全局安装   2.局部安装

如果是全局方式安装的babel,那么我们也要使用全局的Mocha来调用babel-core模块

$ npm install -g babel-core babel-preset-es2015
$ mocha --compilers js:babel-core/register

但如果是局部方式安装的babel,那么我们就要使用局部的Mocha来调用babel-core模块

$ npm install --save-dev babel-core babel-preset-es2015
$ ../node_modules/mocha/bin/mocha --compilers js:babel-core/register

为什么呢?因为Mocha是根据自身的路径来寻找babel模块的,所以要全局对应全局,局部对应局部

这里少了很重要的一步:在测试之前,需要配置babel转码规则,在项目根目录,记住‘一定要是根目录’,新建.babelrc文件,这个文件是供babel使用的

// .babelrc
{
"presets": [ "es2015" ] //这里制定使用es2015规则转码
}

进阶四:测试还可以是异步的?

异步测试与普通测试有什么不同:测试用例的回调函数中多了一个参数done

 var add = require('../src/add.js');
var expect = require('chai').expect; describe('加法函数的测试', function() {
// 异步测试
it('1 加 1 应该等于 2', function(done) {
var clock = setTimeout(function () {
expect(add(1, 1)).to.be.equal(2);
done(); // 通知Mocha测试结束
},1000);
}); // 同步测试
it('1 加 0 应该等于 1', function() {
expect(add(1, 0)).to.be.equal(1);
});
});

异步测试需要注意一点:必须手动调用done,否则该异步测试就会失败,见下方代码与运行截图:

代码:

 var add = require('../src/add.js');
var expect = require('chai').expect; describe('加法函数的测试', function() {
// 异步测试
it('1 加 1 应该等于 2', function(done) {
var clock = setTimeout(function () {
expect(add(1, 1)).to.be.equal(2);
//done();我们不主动调用done,看看会发生什么?
},1000);
}); // 同步测试
it('1 加 0 应该等于 1', function() {
expect(add(1, 0)).to.be.equal(1);
});
});

运行截图:

从运行结果不难看出,测试用例1失败了,而且Mocha提示我们:如果是异步测试或钩子,那么一定要确保done方法被调用,否则测试就会失败,但并不会影响其他用例

那么,异步测试有哪些应用场景呢?那就是测试数据接口,我们可以这样:

 it('异步请求测试', function() {
return fetch('https://api.github.com')
.then(function(res) {
return res.json();
}).then(function(json) {
expect(json).to.be.an('object'); // 测试接口返回的是否为对象类型的数据,也就是json格式
});
});

进阶五:如果我们想只执行某个测试用例呢?或者除了某个用例,其他的都执行

Mocha有两个用例管理api:only和skip

1.如果只想执行某个用例,我们就用only方式调用它:

 var add = require('../src/add.js');
var expect = require('chai').expect; describe('加法函数的测试', function() {
// 一个测试组中不是只能有一个only,可以有多个only方式执行的用例
it.only('1 加 1 应该等于 2', function() {
expect(add(1, 1)).to.be.equal(2);
}); it.only('1 加 0 应该等于 1', function() {
expect(add(1, 0)).to.be.equal(1);
}); // 但如果组内已经有了only,那么非only方式执行的用例就一定不会被执行,切记
it('1 加 -1 应该等于 0', function() {
expect(add(1, -1)).to.be.equal(0);
}); });

运行截图:

可以看出,第三个用例并没有被执行

2.如果想跳过某个用例,我们就用skip方式调用它:

 var add = require('../src/add.js');
var expect = require('chai').expect; describe('加法函数的测试', function() { it('1 加 1 应该等于 2', function() {
expect(add(1, 1)).to.be.equal(2);
}); // 同理,skip方式执行的用例在同一组内也可以有多个
it.skip('1 加 0 应该等于 1', function() {
expect(add(1, 0)).to.be.equal(1);
}); it.skip('1 加 -1 应该等于 0', function() {
expect(add(1, -1)).to.be.equal(0);
}); });

运行截图:

第2,3个用例被跳过了

结语

以上就是Mocha测试框架的简单介绍,测试api不只有文中的to.be.equal,文中只是"千牛一毛",还有很多api以及更高级的使用特性,详细可参照官方网站:http://mochajs.org/

本文章内容参照了阮一峰老师的文章《测试框架 Mocha 实例教程》,感兴趣的同学可以看一下

前端单元测试框架-Mocha的更多相关文章

  1. 前端测试框架对比(js单元测试框架对比)

    前端测试框架对比(js单元测试框架对比) 本文主要目的在于横评业界主流的几款前端框架,顺带说下相关的一些内容. 测试分类 通常应用会有 单元测试(Unit tests) 和 功能测试(Function ...

  2. Mocha 单元测试框架简介

    前言: mocha是JavaScript的一种单元测试框架,既可以在浏览器环境下运行,也可以在Node.js环境下运行. 使用mocha,我们就只需要专注于编写单元测试本身,然后,让mocha去自动运 ...

  3. 在WebStorm中集成Karma+jasmine进行前端单元测试

    在WebStorm中集成Karma+jasmine进行前端单元测试 前言 好久没有写博了,主要还是太懒=.=,有点时间都去带娃.看书了,今天给大家分享一个原创的小东西,如果大家对TDD或者BDD有兴趣 ...

  4. Javascript单元测试框架比较Qunit VS Jasmine

    Javascript单元测试框架比较Qunit VS Jasmine 工欲行其事必先利其器,好的单元测试框架是TDD成功的一半.Javascript优秀的测试框架很多, 包括Jasmine,Qunit ...

  5. 推荐一个好用的E2E前端测试框架cypress

    Cypress 是一个E2E的前端自动化测试框架,同样是基于BDD的思想设计的,话不多说,上demo https://github.com/Spillage/cypress-demo PS, 还有一个 ...

  6. js单元测试框架

    js单元测试框架 前端测试框架对比(js单元测试框架对比) 本文主要目的在于横评业界主流的几款前端框架,顺带说下相关的一些内容. 测试分类 通常应用会有 单元测试(Unit tests) 和 功能测试 ...

  7. javascript单元测试框架mochajs详解

    关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...

  8. Github+yeoman+gulp-angular初始化搭建angularjs前端项目框架

    在上篇文章里面我们说到了Github账号的申请与配置 那么当你有了Github账号并创建了一个自己的Github项目之后,首要的当然是搭建自己的项目框架啦! 本人对自己的定位是web前端狗,常用开发框 ...

  9. 前端测试框架Jest系列教程 -- 简介

    写在前面: 随着互联网日新月异的发展,用户对于页面的美观度,流畅度以及各方面的体验有了更高的要求,我们的网页不再是简单的承载文字,图片等简单的信息传递给用户,我们需要的是更加美观的页面展示,更快的浏览 ...

随机推荐

  1. Java泛型知识点:泛型类、泛型接口和泛型方法

    有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类. 泛型类 容器类应该算得上最具重用性的类库之一.先来看一个没有泛型的情况下的容器类如何定义: public class Cont ...

  2. 天方夜谈·数据结构·Queue

    "我在想Y的时候不能想X....." 什么叫做Queue(队列)?"队列是项的集合,对于每一项x和y,如果x在y之前离开对头,那么x一定在y之前进入队列--Sesh·Ve ...

  3. oracle linux 6.5 安装 oracle 12cR2数据库(2)-DBCA建库

    援引:http://www.cnblogs.com/kerrycode/p/3386917.html  by 潇湘隐者 Oracle 12C引入了CDB与PDB的新特性,在ORACLE 12C数据库引 ...

  4. 窝上课不听,how to learn C language easily(1)

    C language 学习心得 附:为啥起这么霸气侧漏,招大神们鄙视的标题,正如我在<C language>随笔的介绍中写的,这是一个写个妹纸们看的C language的文章.没错!!写这 ...

  5. 使用Dotfuscator加密混淆程序以及如何脱壳反编译

    混淆演示 首先介绍如何使用Dotfuscator对.net程序加密码混淆/加壳 C#或vb.net编写的应用程序或DLL. 这里随便创建了一个C#的命令行控制台程序.程序很简单,对当前的时间进行了AE ...

  6. github上传文件

    说来也惭愧,我是最近开始用github,小白一个,昨天研究了一个下午.终于可以上传了,所以今天写点,一来分享是自己的一些经验,二来也是做个记录,万一哪天又不记得了:) 废话不多说,直接来,这次主要介绍 ...

  7. [刷题]算法竞赛入门经典(第2版) 6-7/UVa804 - Petri Net Simulation

    题意:模拟Petri网的执行.虽然没听说过Petri网,但是题目描述的很清晰. 代码:(Accepted,0.210s) //UVa804 - Petri Net Simulation //Accep ...

  8. jQuery之筛选操作

    jQuery之筛选操作 筛选操作分三大类:过滤,查找,串联 eq(),first(),last(),hasClass(),filter(),is() html代码 jQuery代码 效果如下: map ...

  9. SUSE 11下安装DPDK

    SUSE下安装与centos下安装有稍许不同: # cd  dpdk-1.8.0 # grep -rn Werror . |grep -iE "Makefile|mk" |awk ...

  10. APICloud框架——总结一下最近开发APP遇到的一些问题

    距离上一次发文都过去十天了, 下班回来懒的就想睡觉, 今天520一个重要的节日, 恩爱已经秀完, 该干点事情了!! 总结一下最近开发遇到的一些问题, 以及解决方案 纯css三角形 /* 没有哪个方向的 ...