前端单元测试总结

###1.为什么需要单元测试

###2.前端相关的单元测试技术

####2.1 测试框架

目前,前端的测试框架很多,像QUnit、jasmine、mocha、jest、intern等框架,这些框架各有特点,简单描述下,感兴趣的可以具体研究:

####2.2 断言库

var chai = require('chai');

var assert = chai.assert; // typef assert === 'object'
chai.should(); // 对Obejct.prototype进行拓展

####2.3 mock库 先来说说为什么需要mock吧:需要测试的单元依赖于外部的模块,而这些依赖的模块具有一些特点,例如不能控制、实现成本较高、操作危险等原因,不能直接使用依赖的模块,这样情况下就需要对其进行mock,也就是伪造依赖的模块。例如在使用XMLHttpRequest时,需要模拟http statusCode为404的情况,这种情况实际很难发生,必然要通过mock来实现测试。

####2.4 test runner

###3.单元测试技术的实现原理

  1. 测试框架:判断内部是否存在异常,存在则console出对应的text信息
  2. 断言库:当actual值与expect值不一样时,就抛出异常,供外部测试框架检测到,这就是为什么有些测试框架可以自由选择断言库的原因,只要可以抛出异常,外部测试框架就可以工作。
  3. mock函数:创建一个新的函数,用这个函数来取代原来的函数,同时在这个新函数上添加一些额外的属性,例如called、calledWithArguments等信息
function describe (text, fn) {
    try {
        fn.apply(...);
    } catch(e) {
        assert(text)
    }
}

function fn () {
    while (...) {
        beforeEach();
        it(text, function () {
            assert();
        });
        afterEach();
    }
}

function it(text, fn) {
	...
	fn(text)
	...
}

function assert (expect, actual) {
    if (expect not equla actual ) {
        throw new Error(text);
    }
}
function fn () {
	...
}

function spy(cb) {
	var proxy = function () {
		...
	}
	proxy.called = false;
	proxy.returnValue = '...';
	...
	return proxy;
}

var proxy = spy(fn); // 得到一个mock函数

###4.如何写单元测试用例

####4.1原则

####4.2 TDD

一句话简单来说,就是先写测试,后写功能实现。TDD的目的是通过测试用例来指引实际的功能开发,让开发人员首先站在全局的视角来看待需求。具体定义可以查看维基;

就个人而言,TDD不是一个技术,而是一种开发的指导思想。在目前互联网的开发环境下,业务开发很难做到TDD开发,一是因为需要更多时间编写单元测试用例;二是要求非常了解业务需求;三是要求开发人员有很强的代码设计能力。但是当我们写组件、工具方法、类库的时候,TDD就可以得到很好地使用。

####4.3 BDD

行为驱动开发要求更多人员参与到软件的开发中来,鼓励开发者、QA、相关业务人员相互协作。BDD是由商业价值来驱动,通过用户接口(例如GUI)理解应用程序。详见维基.