前端单元测试总结

1.为何须要单元测试html

  • 正确性:测试能够验证代码的正确性,在上线前作到内心有底
  • 自动化:固然手工也能够测试,经过console能够打印出内部信息,可是这是一次性的事情,下次测试还须要从头来过,效率不能获得保证。经过编写测试用例,能够作到一次编写,屡次运行
  • 解释性:测试用例用于测试接口、模块的重要性,那么在测试用例中就会涉及如何使用这些API。其余开发人员若是要使用这些API,那阅读测试用例是一种很好地途径,有时比文档说明更清晰
  • 驱动开发,指导设计:代码被测试的前提是代码自己的可测试性,那么要保证代码的可测试性,就须要在开发中注意API的设计,TDD将测试前移就是起到这么一个做用
  • 保证重构:互联网行业产品迭代速度很快,迭代后必然存在代码重构的过程,那怎么才能保证重构后代码的质量呢?有测试用例作后盾,就能够大胆的进行重构

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

2.1 测试框架node

目前,前端的测试框架不少,像QUnit、jasmine、mocha、jest、intern等框架,这些框架各有特色,简单描述下,感兴趣的能够具体研究:jquery

  • Qunit: 该框架诞生之初是为了jquery的单元测试,后来独立出来再也不依赖于jquery自己,可是其身上仍是脱离不开jquery的影子
  • jasmine: Behavior-Drive development(BDD)风格的测试框架,在业内较为流行,功能很全面,自带asssert、mock功能
  • mocha: node社区大神tj的做品,能够在node和browser端使用,具备很强的灵活性,能够选择本身喜欢的断言库,选择测试结果的report
  • intern: 看官方介绍该测试框架功能极其全面,彷佛囊括了业内跟测试相关的全部功能

2.2 断言库git

  • chai:应该是目前组流行的断言库了,支持TDD(assert)、BDD(expect、should)两个风格的断言库
    var chai = require('chai'); 
    
    var assert = chai.assert; // typef assert === 'object'
    chai.should(); // 对Obejct.prototype进行拓展
  •  should.js: TJ的另一个开源贡献
  • expect.js:BDD风格的另一个断言库,基于should.js,是mini版的BDD库
  • assert(node自带核心模块): 能够在node中使用的断言模块

 

2.3 mock库
先来讲说为何须要mock吧:须要测试的单元依赖于外部的模块,而这些依赖的模块具备一些特色,例如不能控制、实现成本较高、操做危险等缘由,不能直接使用依赖的模块,这样状况下就须要对其进行mock,也就是伪造依赖的模块。例如在使用XMLHttpRequest时,须要模拟http statusCode为404的状况,这种状况实际很难发生,必然要经过mock来实现测试。
github

  • sinon.js: 目前使用最多的mock库,将其分为spies、stub、fake XMLHttpRequest、Fake server、Fake time几种,根据不一样的场景进行选择。

2.4 test runnerapi

  • karma: 设置测试须要的框架、环境、源文件、测试文件等,配置完后,就能够轻松地执行测试。

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

  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原则函数

  • 测试代码时,只考虑测试,不考虑内部实现
  • 数据尽可能模拟现实,越靠近现实越好
  • 充分考虑数据的边界条件
  • 对重点、复杂、核心代码,重点测试
  • 利用AOP(beforeEach、afterEach),减小测试代码数量,避免无用功能
  • 测试、功能开发相结合,有利于设计和代码重构

4.2 TDD

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

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

4.3 BDD

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

相关文章
相关标签/搜索