Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

Mocha学习笔记

28
Dec
2015

Mocha学习笔记

By Alex
/ in JavaScript
/ tags 学习笔记
0 Comments
简介

Mocha是一个JavaScript领域优秀的单元测试框架,可以在Node.js或者浏览器环境下运行。Mocha让异步测试变得简单而有趣,它支持灵活的、精确的测试报告,可以把未捕获异常映射到特定的测试用例中。

执行下面的命令添加为当前工程的依赖:

Shell
1
npm install --save-dev mocha
测试风格

所谓测试风格,是指测试用例的组织方式。流行的单元测是风格包括:

  1. TDD,测试驱动开发。关注所有功能是否正确实现,每个功能点都具备对应的测试用例
  2. BDD,行为驱动开发。关注应用程序的整体行为是否正确

mocha使用基于JavaScript的DSL语言扩展,对两种测试风格进行支持。

TDD风格的用于主要使用suite、test来组织测试代码。suite表示一个测试套件,可以形成多层级的结构,具体到一个测试用例时,使用test。TDD风格提供了 setup 、 teardown 两个钩子方法,分别在进入/退出suite时执行。代码示例:

JavaScript
1
2
3
4
5
6
7
8
9
10
suite( 'Array', function () {
    setup( function () {
    } );
    suite( '#indexOf()', function () {
        // 一个测试用例
        test( 'should return -1 when not present', function () {
            assert.equal( -1, [ 1, 2, 3 ].indexOf( 4 ) );
        } );
    } );
} ); 

BDD风格的用例主要使用describe、it来组织厕所代码。describe表示一个测试套件,可以形成多层级的结构,具体到一个测试用例时,使用it。BDD风格提供了 before  、 after 、 beforeEach 、 afterEach 四个钩子方法,用于测试用例的准备、清理工作。前两个方法分别在进入/退出describe时执行,后两个方法则在每一个测试用例执行前/后执行。代码示例:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 配合使用BDD风格的断言库shound.js
var should = require( 'should' );
describe( 'Array', function () {
    // 在所有测试开始前的准备工作
    before( function () {
    } );
    // 嵌套的describe
    describe( '#indexOf()', function () {
        // 一个测试用例
        it( 'should return -1 when not present', function () {
            [ 1, 2, 3 ].indexOf( 4 ).should.equal( -1 );
        } );
    } );
} );
断言库

Mocha支持与多个断言库配合,除了Node.js自带的assert模块以外,你还可以使用should.js、better-assert等库。

should.js

该断言库扩展了Object.prototype对象,为其添加了一个不可枚举的getter,这样你就可以使用任意对象的should属性来进行断言操作了。should.js支持现代浏览器以及IE8+版本。执行下面的命令添加为当前工程的依赖:

Shell
1
npm install should --save-dev
用法
JavaScript
1
2
3
4
5
6
// 将should作为属性使用
var should = require('should');
(5).should.be.exactly(5).and.be.a.Number();
// 将should作为函数使用
var should = require('should/as-function');
should(10).be.exactly(5).and.be.a.Number();
示例
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var user = {
    name: 'tj', pets: [ 'tobi', 'loki', 'jane', 'bandit' ]
};
 
user.should.have.property( 'name', 'tj' );
user.should.have.property( 'pets' ).with.lengthOf( 4 );
 
(5).should.be.exactly( 5 ).and.be.a.Number();
 
should( null ).not.be.ok();
 
should( 10 ).be.exactly( 10 );
 
someAsyncTask( foo, function ( err, result ) {
    should.not.exist( err );
    should.exist( result );
    result.bar.should.equal( foo );
} );

可以看到,这种BDD风格的与语法非常接近自然语言。

should.js的每个断言,其返回值是被包装过的对象,支持链式的断言调用。属性: an, .of, .a, .and, .be, .have, .with, .is, .which 可以随意出现在链条中,但是仅仅增强可读性,不具有任何作用。

几乎全部断言返回相同的对象,除了.length、.property等少数例外,它们把断言对象转移到原对象的属性上。 

更多用法参考should.js API。

用法
异步代码

对异步代码进行单元测试非常简单,你只需要为it提供带有一个入参的回调函数,在其中执行异步操作即可。当异步操作执行完毕,你需要调用Mocha为前述回调传递的done,通知Mocha异步操作已经完毕:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
describe( 'User', function () {
    describe( '#save()', function () {
        it( 'should save without error', function ( done ) {
            // 在这里进行异步操作
            var user = new User( 'Luna' );
            user.save( function ( err ) {
                // 异步操作的回调函数
                // 在这里调用done通知Mocha异步操作已经完成
                if ( err ) done( err );
                else done();
            } );
        } );
    } );
} );

你可能注意到,done函数接受一个error作为入参,如果你的异步操作的回调函数也是这种风格,上述代码可以简化为:

JavaScript
1
2
3
4
5
6
7
8
describe( 'User', function () {
    describe( '#save()', function () {
        it( 'should save without error', function ( done ) {
            var user = new User( 'Luna' );
            user.save( done );
        } );
    } );
} );
结合Promise

对于返回Promise的函数,可以这样断言:

JavaScript
1
2
3
// find必须返回Promise
// eventually创建一个在Promise.then中执行的断言
return db.find({ type: 'User' }).should.eventually.have.length(3);
箭头函数

由于箭头函数使用词法的this绑定,导致它没有办法正常访问Mocha的上下文,因此不推荐使用。

钩子方法

前面的章节中已经介绍过钩子,需要了解的是,钩子也可以是异步的:

JavaScript
1
2
3
4
5
6
beforeEach( function ( done ) {
    db.clear( function ( err ) {
        if ( err ) return done( err );
        db.save( [ tobi, loki, jane ], done );
    } );
} );

钩子方法可以定义在任何describe的外部,称为根级别钩子, 这种钩子会在任意用例的前后执行。

重试

你可以指定让失败的测试重复指定的次数,通常用于端到端测试,在单元测试中一般不使用。

JavaScript
1
2
3
4
describe( 'retries', function () {
    // 最多重复所有测试用例4次
    this.retries( 4 );
} );
测试耗时

很多报告方式支持显式测试消耗的时间,连同标记一个用例“执行缓慢”。是否缓慢的阈值在测试套件中指定: 

JavaScript
1
2
3
4
describe( 'retries', function () {
    // 10秒被认为执行缓慢
     this.slow(10000);
} );
超时控制

你可以在测试套件、测试用例级别设置测试用例执行的超时时间,内部嵌套的套件、用例会继承该设置:

JavaScript
1
2
3
describe('a suite of tests', function() {
    this.timeout( 500 );
}

在钩子中也可以进行超时控制,调用 this.timeout(0)  可以禁用超时控制。

命令

 Mocha提供了一个命令行工具,调用格式为:

Shell
1
mocha [debug] [options] [files]
常用选项
选项 说明
-R, --reporter 指定使用的报告器
-b, --bail 在第一个失败后退出
-S, --sort 排序测试文件
-d, --debug 启用Node.js的 --debug选项
-g, --grep 仅运行匹配正则式的测试文件
-f, --fgrep 仅运行匹配文件名的测试文件
-i, --invert 反转上面两个选项的效果
-r, --require

导入一个模块

如果你在.js扩展名的文件中编写ES6,需要:

Shell
1
npm install --save-dev babel-register

然后使用 mocha --require babel-register  选项调用。--compilers选项仅仅在使用其它扩展名编写ES6时才需要

--compilers

以<ext>:<module>的形式指定脚本编译器。

-s, --slow 判定执行缓慢的阈值
-t, --timeout 测试用例执行超时的阈值
-u, --ui 指定用户接口(测试风格),可选值:bdd tdd qunit exports
-w, --watch 监控当前目录的文件变动,一旦变化即测试
--check-leaks 检测全局变量泄漏
--globals 允许指定的全局变量,逗号分隔
--full-trace 打印完整调用栈
--es_staging 启用说用staged特性
--prof 记录统计性的剖析信息
--recursive 包含子目录中的测试文件
--reporters 显示可用的报告器
--retries 失败用例重试次数
--use_strict 启用严格模式

 

← Framework7学习笔记(一):基础
使用Tern增强Eclipse的JS代码提示 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • ExtJS 4的容器机制
  • 浅析ExtJS新特性
  • 基于Chrome Developer Tools的JavaScript开发与调试
  • 基于AngularJS开发Web应用
  • ExtJS 4中的选取器控件

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • Bazel学习笔记 38 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • NaCl学习笔记 32 people like this
  • PhoneGap学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
  • Three.js学习笔记 24 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2