前端单元测试的摸索

前言

一开始让我学单元测试我是拒绝的,因为当初自己连功能都实现的磕磕巴巴的,写单元测试不是作死么?后来D2上某个嘉宾问在场谁有写单元测试,一大波举手,因此我觉得是时候去接触并深入一下单元测试了。

预备知识

学习一样新东西,我习惯先找到一本比较权威的书或者文档来看看原理看看概念再下手,正好之前有买过一本《编写可测试的Javascript》而且之前粗略的看了一半,因此现在想重头开始理清楚一下东西。

首先我们不直接深入主题,而且一步步慢慢学习。

可测试的代码更加容易测试,意味着它更加容易维护,易维护意味着它能让人更加容易理解,更加容易维护,从而使得测试更加容易。

这是一个良性循环。

可测试和可维护的代码

可测试意味着代码短小不复杂,有完整的注释,以及松耦合。

可维护意味着产品从一个人手里到另一个手里,可以修复和更改代码,而且不必完全理解所有的代码。有信心自己做的修改不会影响别的功能。

选择哪种方式?

TDD是测试驱动开发。就是测试先行。

BDD是行为驱动开发。基于TDD,使用通用语言定义测试和预期。

不要先写完测试然后写代码也不要先写完代码写测试。

而是写一段代码就开始写测试或者写一段测试开始写代码。

代码规模

让函数保持最小代码量。最常见的方法就是读写分离。

单元测试

尽可能让被测试代码与其他代码隔离。

正确的注释

正向测试:传入正常的数据,接受正常的数据反馈。

负向测试:传入非期望的函数或该函数不想要的参数进行测试,确保被测试的函数能够被正确处理。

代码覆盖率:指执行代码与非执行代码行数之间的百分比。通常用于展示对于特定测试,多少代码被测试到了。

正文

纯理论的东西总是很难令人接受,因此直接来几个实战。

这里我直接先测试一下阮一峰的mocha的demo例子.

直接按照该篇文章进行测试学习。

Mocha的基本用法

mocha命令后面紧跟测试脚本的路径和文件名,可以指定多个测试脚本。

Mocha默认运行test子目录里面的测试脚本.默认只执行test子目录下面第一层的测试用例,不会执行更下层的用例。加上–recursive参数可以执行子目录下的测试用例。

比较实用的参数:


--watch参数用来监视指定的测试脚本。只要测试脚本有变化,就会自动运行Mocha。

--bail参数指定只要有一个测试用例没有通过,就停止执行后面的测试用例。这对持续集成很有用。

--grep参数用于搜索测试用例的名称(即it块的第一个参数),然后只执行匹配的测试用例。
这个参数感觉对已经整个已经写好的测试用例不需要再单独建个文件而是直接搜索,很实用。
当然直接在用例之前加only也可以达到类似效果。

it.only('description', function() {
   test
});


用-t或--timeout参数,改变默认的超时设置。

在test目录下面,放置配置文件mocha.opts,把命令行参数写在里面.

Mocha在describe块之中,提供测试用例的四个钩子:before()、after()、beforeEach()和afterEach()。它们会在指定时间执行.

describe('hooks', function() {

  before(function() {
    // 在本区块的所有测试用例之前执行
  });

  after(function() {
    // 在本区块的所有测试用例之后执行
  });

  beforeEach(function() {
    // 在本区块的每个测试用例之前执行
  });

  afterEach(function() {
    // 在本区块的每个测试用例之后执行
  });

  // test cases
});

使用mocha init命令在指定目录生成初始化文件。可视化界面测试。

考虑工程化

上面阮一峰的mocha教程非常详细。不过既然是打算写单元测试,肯定需要考虑到工程化。因此先考虑一些辅助工具把东西划分清晰。

主要工具:
测试框架 mocha: http://mochajs.org/
全栈的断言库 chai: http://chaijs.com/
浏览器 phantomjs: http://phantomjs.org/

辅助工具

should.js

should 是一个表述性、可读性很强的测试无关的“断言”库。它是BDD风格的,用一个单例的不可枚举的属性访问器扩展了Object的prototype,允许你表述对象应该展示的行为。
node本身有自己的断言模块,但是should所具有的表述性和可读性让开发者没有理由拒绝这么棒的工具。
常用的断言库还有Chai和expectjs.

istanbul
测试覆盖率工具

supertest
这是一个用来测试http接口

Karma浏览器端的测试框架

然后我们要考虑以下几个问题:


1.依赖库的解决,比如我代码用jquery写的,该如何进行单元测试?
2.如何持续性测试?
3.如何快速的可视化测试?

最后采取的第一个版本方案是mocha+karma+should.js

这里是一个测试例子

在安装过程中你会出现一些奇怪的问题,记得把karma,mocha都安装在全局中。而且如果遇到奇怪的问题,你可以npm install -g karma-cli这个包。

接下来就是自由发挥时间,下一篇文章将根据这些内容来做实战。

总结

事实上单元测试看起来挺麻烦,事实上它真的很麻烦,麻烦的不只是它的各种高级的写法,更重要的是一些工具包的各种坑爹bug0-0.不过工欲善其事,必先利其器。因此我们花时间去捣鼓一个通用的测试环境还是比较值得的。

Table of Contents