前端测试一直是前端项目开发过程中机器重要的一个环节,高效的测试方法可以减少我们进行代码自测的时间,提高我们的开发效率,如果你的代码涉及的测试用例较多,而且项目需要长期维护,这时可以考虑使用一下自动化测试了。
  一、前端自动化测试
  前端自动化测试一般是指是在预设条件下运行前端页面或逻辑模块,评估运行结果。预设条件应包括正常条件和异常条件,以达到自动运行测试过程、减少或避免人工干预测试的目的。在前端自动化测试中,我们通常是通过不同的工具来解决不同场景下不同的问题的。测试类型来看,主要分为BDD(Bebavior Driven Developement,行为驱动测试)和TDD(Testing Driven Developement,测试驱动开发)。BDD可以让项目成员(甚至是不懂编程的)使用自然描述语言来描述系统功能和业务逻辑,从而根据这些描述步骤进行系统自动化的测试;TDD则要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速实际开发过程
  BDD和TDD均有各自的适用场景,BDD一般更偏向于系统功能和业务逻辑的自动化测试设计,而TDD在快速开发并测试功能模块的过程中则更加高效,以快速完成开发为目的。下面我们看下BDD和TDD具体的特点:
  BDD的特点: - 从业务逻辑的角度定义具体的输入与预期输出,以及可衡量的目标; - 尽可能覆盖所有的测试用例情况; - 描述一系列可执行的行为,根据业务的分析来定义预期输出。例如,expect, should, assert; - 设定关键的测试通过节点输出提示,便于测试人员理解; - 大程度的交付出符合用户期望的产品,避免输出不一致带来的问题。
  TDD的特点: - 需求分析,快速编写对应的输入输出测试脚本; - 实现代码让测试为成功; - 重构,然后重复测试,终让程序符合所有要求。
  二、单元测试解决方案
  前端而言,单元测试的实现工具比较多。主要有mocha,jasmine和qunit。我们先来看看使用mocha是怎样实现单元测试的。
  · mocha
  mocha的特点是简单可扩展、支持浏览器和Node、支持同步和异步、支持连续用例测试。测试集,以函数describe(string, function)封装;测试用例,以it(string, function)函数封装,它包含2个参数;断言,以assert语句表示,返回true或false。另外,mocha在完成异步测试用例时通过done()来标记。
  $ npm install mocha
  $ mkdir test
  $ $EDITOR test/test.js # or open with your favorite editor
  测试用例:
  var assert = require('assert');
  describe('Array', function() {
  describe('#indexOf()', function() {
  it('should return -1 when the value is not present', function() {
  assert.equal(-1, [1,2,3].indexOf(4));
  });
  });
  });
  输出为:
  $ ./node_modules/mocha/bin/mocha
  Array
  #indexOf()
  ? should return -1 when the value is not present
  1 passing (9ms)
  同时,mocha支持异步和Promise。
  describe('#find()', function() {
  it('respond with matching records', function(done) {
  db.find({type: 'User'}, function(err, res) {
  if (err) return done(err);
  res.should.have.length(3);
  done();
  });
  });
  });
  });
  · jasmine
  jasmine是一个BTT的框架,不依赖其它框架。测试集以函数describe(string, function)封装;测试用例,以it(string, function)函数封装,它也包含2个参数;断言,以expect语句表示,返回true或false;断言的比较操作时,将Expectation传入的实际值和Matcher传入的期望值比较,另外任何Matcher都能通过在expect调用Matcher前加上not来实现一个否定的断言(expect(a).not().toBe(false);)
  describe("A suite is just a function", function() {
  var a;
  it("and so is a spec", function() {
  a = true;
  expect(a).toBe(true);
  expect(a).not().toBe(false);
  });
  });
  jasmine也支持异步测试用例。
describe("long asynchronous specs", function() {
beforeEach(function(done) {
done();
}, 1000);
it("takes a long time", function(done) {
setTimeout(function() {
done();
}, 9000);
}, 10000);
afterEach(function(done) {
done();
}, 1000);
});
  · qunit
  qunit是一个可基于jquery的简单测试框架,主要运行在浏览器端。它通过QUnit.test定义一个测试集,一个测试集中通过回调函数里面多个断言判断来实现多个测试用例,使用起来非常简单。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>QUnit Example</title>
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.0.1.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="https://code.jquery.com/qunit/qunit-2.0.1.js"></script>
<script>
QUnit.test( "hello test", function( assert ) {
assert.ok( 1 == "1", "Passed!" );
assert.equal( null, false, "null, false; equal fails" );
});
</script>
</body>
</html>
  qunit也支持异步测试用例,异步完成时通过done()来结束。
  QUnit.test( "assert.async() test", function( assert ) {
  var done = assert.async();
  var input = $( "#test-input" ).focus();
  setTimeout(function() {
  assert.equal( document.activeElement, input[0], "Input was focused" );
  done();
  });
  });
  小结一下,单元测试工具的主要组成部分其实是类似的,主要包括测试集、测试用例、断言和断言比较等。它可以用来快速测试单元模块的主要功能,有助于辅助我们快速开发。