代码测试:项目妥当的有力保证

懒散,是促使人类科技生长的重要因素。我们离别刀耕火种的时期,恰是由于人们不断地经由过程发现东西和优化精简手动的流程来完成效力的提拔,让人们能专注于本身专业的范畴,其他的事变交给机械去处置惩罚。

而同样在前端的范畴,我们也是从蛮荒的时期走向现在的繁华兴旺,种种框架百花齐放,前端也不再是局限于静态页面,形状越发接近于传统运用的开辟,功用的庞杂度呈指数级的提拔。有能够一个库要同时满足多个项目运用,版本的迭代也会致使功用的变化,假如每次到这个时刻,就要让我从新测试一遍代码,那我还能不能准时放工了……

所以我们须要在开辟之前,就肯定这个框架/库的运用划定规矩,经由过程这个划定规矩去写我们的测试用例,如许我们开辟完以后,跑一遍测试用例,让机械庖代我们人工手动地去测试代码,就能够晓得我们的框架在种种环境和运用状况下会否报错,而不再须要一一项目去考证。

固然并非只要我有这类主意,大神们早就想到了,因而测试框架应运而生。
就笔者相识,现在前端范畴比较盛行的单元测试框架有 mochaJasmine 等等。。

当务之急,我们看看怎样上手测试,这里我们以mocha举例子。
起首要在项目中装置mocha

npm install mocha --save-dev

在项目标根目录建立 test 文件夹 并建立文件 index.js。现在要测试 Array.prototype.indexOf

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))
    })
  })
})

在命令行中实行

mocha

假如看到如许的效果,祝贺你,你的代码已经由过程了测试(诙谐)

Array
    #indexOf()
      ✓ should return -1 when the value is not present


  1 passing (13ms)

以上是一个简朴例子,能够有许多同砚照样会一脸懵逼,说好的讲测试框架,你给引入一个assert的是什么鬼?
这我就要解释一下了,这个是nodejs中内置的断言模块

何谓断言?

在顺序设计中,断言(assertion)是一种放在顺序中的一阶逻辑(如一个效果为真或是假的逻辑推断式),目标是为了标示与考证顺序开辟者预期的效果-当顺序运转到断言的位置时,对应的断言应当为真。若断言不为真时,顺序会中断运转,并给出毛病音讯。 — 摘自维基百科

测试框架的职责,只是帮你对项目中林林总总的测试来举行一个计划,轻易对测试来举行拆分整顿,并在测试中增加一些形貌来轻易人眼鉴别,实际上,输入参数到函数中实行,终究输出什么效果才经由过程测试,是须要我们去“通知”测试框架的。而断言,恰好满足我们这类行动的语义,也是最天然的。

一般来说运用默许的断言模块已足以应对多种状况,固然假如你对这类语法运用示意很不爽的时刻,也能够在测试框架中挑选运用其他断言库, 比方 should.js , chai 这里就不再过量地赘述。

怎样测试异步代码

你能够在回调中实行done

var assert = require('assert')

describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function(done) {
      setTimeout(function() {
        var value = 1;
        if (value) done(assert.equal(-1, [1, 2, 3].indexOf(4)))
        else done()
      }, 30)
    })
  })
})

promise

it('should xxx', function(done) {
  return new Promise(function(resolve, reject){}).then(done)
})

支撑 async await

it('should return -1 when the value is not present', async function(done) {
  let a = await func();
  if (a) done()
  else done(new Error("xxx"))
})

须要注重的是,在运用mocha api的时刻并不首倡 箭头函数的写法,由于如许你会拿不到当前实行的context, 当前context下内置了比方 timeOut 等等的一些api,详情请翻阅文档,这里就不做过量睁开了。

测试环境

是时刻在浏览器跑一下了!

没错,停止到现在,我们一向都是在nodejs的环境下实行代码,至于浏览器的实行环境有若干差别,人人不言自明,简简朴单在node上面跑一下测试时不具有普适性,不可靠的,我们须要在浏览器环境都跑一遍。

什么?你想翻开控制台粘帖代码实行?为了挽救你于无尽的加班测试中,是时刻引荐你接入运用karma了。

karma 是一套测试实行管理东西,能够设置须要测试的浏览器环境,以及测试前的一系列准备工作等,须要时还能够接入测试覆蓋率的报告天生。

为了下降同砚们设置karma的门坎,这里我换用了断言库should.js

npm install should --save-dev

断言写法替代以下

// assert.equal([1,2,3].indexOf(4), -1)
[1,2,3].indexOf(4).should.equal(-1)

起首我们须要装置karma

npm install karma-cli -g
npm install karma --save-dev

进到项目中初始化karma

karma init

接下来你会收到一连串的讯问

Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> mocha

Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no

Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
>

What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
> node_modules/should/should.js
> test/*.js

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
> 

Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes

设置完成后,项目标根目录会涌现一个 karma.conf.js 文件,我很想睁开,然则假如继承讲下去预计讲到天亮,所以想深切相识每一个设置项的作用能够翻阅karma文档

// Karma configuration
// Generated on Fri Aug 04 2017 20:53:38 GMT+0800 (CST)

module.exports = function(config) {
  let configuration = {

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],


    // list of files / patterns to load in the browser
    files: [
      'node_modules/should/should.js',
      'js/*.js',
      'quz/*.js',
      'test/*.js'
    ],


    // list of files to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'quz/*.js': 'coverage',
      'js/*.js': 'coverage'
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress', 'coverage', 'coveralls'],
    coverageReporter: {
      type : 'lcov',
      dir : 'coverage/'
    },

    // web server port
    port: 9876,
    plugins: [
      'karma-mocha',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-coverage',
      'karma-coveralls'
    ],

    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['ChromeHeadless', 'FirefoxHeadless'],

    customLaunchers: {
      Chrome_travis_ci: {
        base: "ChromeHeadless",
        flags: ["--no-sandbox"]
      },
      FirefoxHeadless: { 
        base: "Firefox", 
        flags: ["-headless"]
      }
    },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: process.env.TRAVIS,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  }
  if (process.env.TRAVIS) {
    configuration.browsers = ["Chrome_travis_ci", 'FirefoxHeadless'];
  }
  config.set(configuration)
}

接下来我们跑一发

karma start

你的黑窗口会有如许的日记

02 02 2018 18:10:26.181:WARN [karma]: No captured browser, open http://localhost:9876/
02 02 2018 18:10:26.193:INFO [karma]: Karma v2.0.0 server started at http://0.0.0.0:9876/
02 02 2018 18:10:26.194:INFO [launcher]: Launching browser Chrome with unlimited concurrency
02 02 2018 18:10:26.199:INFO [launcher]: Starting browser Chrome
02 02 2018 18:10:27.346:INFO [Chrome 63.0.3239 (Mac OS X 10.13.2)]: Connected on socket lv0dmScnbh5jC2NgAAAA withid 45333497
Chrome 63.0.3239 (Mac OS X 10.13.2): Executed 1 of 1 SUCCESS (0.003 secs / 0.001 secs)

这时刻你的电脑会自动开启浏览器,而且常驻在桌面,karma一旦观察到你的代码发作更改,就会从新跑一次测试用例,今后离别繁复的测试环节,用心写代码。perfect!

完了么?并没有!你还能够更懒,把当前测试流程接入CI,成为布置环境前的一个环节,固然这已超出了本文应当议论的局限。

长路漫漫,本文仅限于人人作为相识测试的开篇,实际上隐蔽了许多的细节,真正的环境,实在遇到的题目比这个要庞杂很多,然则假如懂得了测试的道理,置信智慧的你遇到再难的题目也能想到处理的方法。

学海无涯,共勉之。

    原文作者:elliott_hu
    原文地址: https://segmentfault.com/a/1190000013106373
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞