JavaScript TDD with Mocha

2014-04-30 02:05 by owenyang, 317 阅读, 0 评论, 收藏编辑

开发现状

当新的版本快要发布的时候,大家都忙于加班,加紧修复BUG1、BUG2。我想这就是很多公司开发的现状。 为了不至于让上线的版本挂掉挂掉,少不了就是 人肉测试。 在一个项目中,我们会做许许多多各种各样的测试,这些测试都必不可少的。测试是项目成功不可或缺的一部分。但 人肉测试 不在本博的讨论范围。

测试大体分为以下几类

  • 单元测试
  • 集成测试
  • 功能测试

测试驱动开发

TDD(Test-Driven Development) 从根本上改变了传统的开发模式,它要求你在写代码之前就写好测试,而不仅仅是待你写你代码以后的用作验证的目的。 TDD将测试提到了应用设计的阶段,在这期间你应该用你的测试理清你写代码时的思路,我们称作 Tasking.

以下是TDD开发时的基本要点

  1. Tasking (将项目需要拆分成小的task)
  2. Red (写测试代码,让其失败,变红)
  3. Green (写实现代码,让其通过,变绿)
  4. Refactor (重构,消失代码中的bad smell)
  5. Repeat (重复以上步骤)

这就是TDD开发过程中的基本过程,我们就在 “红-绿-红-绿” 中完成我们的软件开发。

JavaScript TDD

笔者将通过编写一个传统游戏的方式,来完成一个 JavaScript TDD 的实践。

4 digits 
是一个猜数字游戏。在国外称为公牛和母牛,在中国人们就叫它猜数字。游戏的目标是在八次内用尽可能短的时间猜出一个随机的四位数:

  • 顺序与大小都相同的用 A 表示
  • 大小相同,但顺序不同用 B 表示

比如 输入 1234 | 猜数 2156 | 结果 0A2B

这是曾经在文曲星上有过的游戏,网友做过一个GUI版的,大家可以看下截图:

当然,本文的重点是 JavaScript TDD, 不是去实现一个太过细节逻辑。我们就把需求稍微改写一下:

  • 四位数先给定
  • 仅做算法处理(比较所猜数字与给定数字)

开发准备

  • Node
  • Mocha

如果不知道 Node, 估计你暂时还不用写 JavaScript。所以,本篇文章可能还不太适合你。


摩卡是一个功能丰富的运行在 Node 和浏览器上的JavaScript测试框架。它允许你使用你任意喜欢的断言库。比如

  • should.js
  • chai
  • expect.js
  • better-assert

本次工程就选择 should.js吧,写TDD很优美,下面正式开发我们的TDD之旅。

工程建立

1 mkdir -p digits/{src,test}
2 cd digits
3 touch src/digits.js test/digitsSpec.js
4 npm init
5 npm install -g mocha
6 npm install should --save-dev

工程就是这样搭建完成了,我们可以来看一下目录结构( 我把node_modules目录隐藏了):

就这样,我们就可以直接运行

mocha

跑测试了。当然,我们什么代码都没有写,当时没有测试可以跑,所以结果会是一个 0 passing。那我们正式开始吧。

测试代码编写

先写出我们的第一个测试用例吧。 如果输入数字,或者所给数字的长度都不等于4,则返回-1。

 1 var should = require('should'),
2 Digits = require('../src/digits').Digits;
3
4 describe('Digits', function() {
5 // Digits.compare(inputNum, givenNum);
6 describe('#compare()', function() {
7 it('should return -1 when input and given number length isnt 4', function() {
8 Digits.compare('123', '').should.equal(-1);
9 Digits.compare('123', null).should.equal(-1);
10 Digits.compare('123', '1234').should.equal(-1);
11 Digits.compare(null, '1234').should.equal(-1);
12 });
13 });
14 });

嗯,代码看起来不错,我们尝试着 mocha 跑一下。啊哦,意料之中,变红了:

什么原因喃?原来我们根本没有写实现代码,你这不废话么?确实是这样,这就是TDD中的第一步,。接下来,我们就编写一些代码,让它变绿吧。

实现代码编写

我们定义一个简单的Digits的function吧,通过 exports.Digits = Digits; 将函数接口暴露出去。就像这样:

 1 function Digits() {}
2
3 Digits.compare = function(inputNum, givenNum) {
4 var len = 4;
5
6 if (inputNum === null ||
7 givenNum === null ||
8 inputNum.length !== len ||
9 givenNum.length !== len) {
10 return -1;
11 }
12 }
13
14 exports.Digits = Digits;

看吧,看起来也很不错的样子,那我们继续跑一下测试吧。啊哈,意料之中,变绿了:

repeat

由红变绿之后,这个task也就相当于是完成了。我们又可以按照这样的一个步骤,再写新的测试,然后再将它实现出来。到此为止,一个基本的 JavaScript TDD流程也就完了,趁着热乎劲儿。我们把这个compare 函数的其他测试也一并写了吧。代码如下:

digitsSepc.js

 1 var should = require('should'),
2 Digits = require('../src/digits').Digits;
3
4 describe('Digits', function() {
5 // Digits.compare(inputNum, givenNum);
6 describe('#compare()', function() {
7 it('should return -1 when input and given number length isnt 4', function() {
8 Digits.compare('123', '').should.equal(-1);
9 Digits.compare('123', null).should.equal(-1);
10 Digits.compare('123', '1234').should.equal(-1);
11 Digits.compare(null, '1234').should.equal(-1);
12 });
13
14 it('should return 4A0B when input numbers matched given numbers', function() {
15 Digits.compare('1234', '1234').should.equal('4A0B');
16 Digits.compare('5678', '5678').should.equal('4A0B');
17 });
18
19 it('should return 2A2B when 2 input numbers matched given numbers, and other 2 exist but not the right order', function() {
20 Digits.compare('2134', '1234').should.equal('2A2B');
21 Digits.compare('1324', '1234').should.equal('2A2B');
22 Digits.compare('3214', '1234').should.equal('2A2B');
23 Digits.compare('4231', '1234').should.equal('2A2B');
24 });
25
26 it('should return 2A0B when 2 input numbers matched given numbers, and other 2 was wrong numbers', function() {
27 Digits.compare('1256', '1234').should.equal('2A0B');
28 Digits.compare('7238', '1234').should.equal('2A0B');
29 Digits.compare('7834', '1234').should.equal('2A0B');
30 Digits.compare('1784', '1234').should.equal('2A0B');
31 });
32 });
33 });

digits.js

 1 function Digits() {}
2
3 Digits.compare = function(inputNum, givenNum) {
4 var len = 4,
5 aCount = 0,
6 bCount = 0;
7
8 if (inputNum === null ||
9 givenNum === null ||
10 inputNum.length !== len ||
11 givenNum.length !== len) {
12 return -1;
13 }
14
15 if (inputNum === givenNum) {
16 return '4A0B';
17 }
18
19 for (var i = 0; i < len; i++) {
20 if (inputNum[i] === givenNum[i]) {
21 aCount++;
22 } else if (givenNum.indexOf(inputNum[i]) !== -1) {
23 bCount++;
24 }
25 }
26
27 return aCount + 'A' + bCount + 'B';
28 }
29
30 exports.Digits = Digits;

最后再来跑一遍 mocha -R spec,结果如下(大功告成啦):

结语

大功告成了,此时的你其实可以洗洗睡了,不用再担心你的程序有问题啦。你的测试告诉你,你的程序都是绿色可行的。当然,如果你测试写有的问题就别当别说咯。 测试代码会有一些什么好处呢?

  • 测试代码在那里,可以保证你以后修改代码时,或者重构时不会对已有的功能产生影响。

这条是很重要的,也是相当重要的。如果没有测试代码的保证,你无从知道你自己所改的代码,对已有的代码会产生什么样的影响。与其每次上线时都得加班改BUG,为啥不先写好测试,上线时早些洗洗睡了呢?

  • 文章声明
  • 作者:Owen
  • 出处: http://www.cnblogs.com/owenyang
  • 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该博客同步发在 CSDN-博客
 
分类: Web Front-end
标签: JavaScriptTDDMochashould

Mocha JavaScript TDD的更多相关文章

  1. JavaScript TDD with Mocha

    开发现状 当新的版本快要发布的时候,大家都忙于加班,加紧修复BUG1.BUG2.我想这就是很多公司开发的现状. 为了不至于让上线的版本挂掉挂掉,少不了就是 人肉测试. 在一个项目中,我们会做许许多多各 ...

  2. JavaScript测试工具比较: QUnit, Jasmine, and Mocha

    1. QUnit A JavaScript Unit Testing framework. QUnit is a powerful, easy-to-use JavaScript unit testi ...

  3. JavaScript的TDD训练营环境搭建

    下周一准备去蹭听公司组织的javascript TDD训练营.以前只是零散的使用javascript,水平相当于小白,笨鸟先飞,提前把环境鼓捣一下. 步骤: 1.nodejs安装 到http://ww ...

  4. 关于JavaScript测试工具:QUnit, Jasmine, MoCha

    在进行前端开发过程中,在某些场景下,需要通过编写单元测试来提高代码质量.而JavaScript常用的单元测试框架有这几个:QUnit, Jasmine, MoCha.下面就基于这三个工具,简单做一比较 ...

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

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

  6. 测试框架Mocha

    NodeJS里最常用的测试框架估计就是mocha了.它支持多种node的assert libs, 同时支持异步和同步的测试,同时支持多种方式导出结果,也支持直接在browser上跑Javascript ...

  7. javascript单元测试框架mochajs详解(转载)

    章节目录 关于单元测试的想法 mocha单元测试框架简介 安装mocha 一个简单的例子 mocha支持的断言模块 同步代码测试 异步代码测试 promise代码测试 不建议使用箭头函数 钩子函数 钩 ...

  8. 前端单元测试框架-Mocha

    引言 随着前端工程化这一概念的产生,项目开发中前端的代码量可谓是'急剧上升',所以在这种情况下,我们如何才能保证代码的质量呢,对于框架,比如React.Vue,因为有自己的语法规则,及时每个开发人员的 ...

  9. 添加 node mocha 测试模块

    1.mocha  支持TDD 和 BDD两种测试风格 2.引用assert模块  此模块是node的原生模块,实现断言的功能,作用是声明预期的结果必须满足 3.mocha测试用例中可以使用第三方测试库 ...

随机推荐

  1. D - Cow Ski Area

    Description Farmer John's cousin, Farmer Ron, who lives in the mountains of Colorado, has recently t ...

  2. 他们控制的定义--让背景颜色变化ViewPager逐步幻灯片

    转载请注明出处.谢谢~ 今天想说一个简单但很好的效果达到.代码是绝对简单,达到绝对easy,就是你可能想不到而已. 不多说,上效果图. 第一个效果是仿最美应用的滑动颜色变化,第二个是我项目中要用的效果 ...

  3. 数组排序、递归——(Java学习笔记二)

    升序:      选择排序:         选定一个元素,一次和后面的元素相比较,如果选定的元素大雨后面的比较元素,就交换位置         先出现最小值,最后出现最大值. public stat ...

  4. SQL Prompt5 破解版+使用说明 [转]

    SQL脚本越写越多,总是觉得编写效率太过于低下,这和打字速度无关.在我个人编写SQL脚本时,至少会把SQL的格式排列成易于阅读的,因为其他人会阅读到你的SQL,无论是在程序中或是脚本文件中,良好的排版 ...

  5. 第21章 策略模式(Strategy Pattern)

    原文 第21章 策略模式(Strategy Pattern) 策略模式 导读:策略模式看完之后,大多数人都会感觉有点混了,包括我,感觉策略模式是一种OO思想的体现(纯属个人拙见). 概述:       ...

  6. 无废话WCF入门教程五[WCF的通信模式]

    一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...

  7. 2014鞍山直播比赛H称号HDU5077(DFS修剪+通过计)

    NAND Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Sub ...

  8. Tomcat剖析(一):一个简单的Web服务器

    Tomcat剖析(一):一个简单的Web服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三):连接器 ...

  9. Ajax得知(两)—— 一个简单的Ajax示例

    通过部分博客认识Ajax之后,我们通过一个简单的实例来消化消化理论知识,一睹Ajax的庐山真面目. 1.实例功能: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  10. Java数据结构与算法(1) - ch02有序表(OrderedArray)

    有序表需要掌握的插入方法,删除方法和二分法查找方法. 插入方法: 从前往后找到比要插入的值大的数组项,将该数组项及之后的项均后移一位(从最后一项起依次后移),最后将要插入的值插入当前数组项. 删除方法 ...