大前端的自动化工厂(5)—— 基于Karma+Mocha+Chai的单元测试和接口测试

一. 前端自动化测试

大多数前端开发者对测试相关的知识是比较缺乏的,一来是开发节奏很快,来不及写,另一方面团队里也配备了“人肉测试机”,完全没必要自己来。但随着项目体量的增大,许多人维护同一份代码,经常会出现有些函数莫名其妙地结果不对了,或者某个接口的入参变了,又或者哪位大哥把后端返回的数据结构给改了。每天工作的时间里被拉来拉去帮人定位问题,结果花了很多时间却发现大部分都是别人的锅。每当遇到项目上线,那就更热闹了,跟着其他“人肉测试机”大家一起点点点......

很多团队都有个通病,凡是出了问题,先往前端身上推,然后前端各种检测排查,到最后是谁的锅,谁呵呵一笑然后领走就完了,如果你也曾因此心里印下了不计其数的草泥马的马蹄印,那我强烈建议你学习【前端自动化测试】相关的知识,或许你不会经常用到它,但在组内互怼和甩锅的环节绝对能助你一臂之力。当然总有一天,你会发现测试的价值远不止这样。它对大型项目提供的可靠性保障是人力无法比拟的

前端很流行这样一句话:如果你觉得单元测试没什么用,只能说明你做的项目不够大。

二. 工具简介

2.1 Karma

官方网址:https://karma-runner.github.io/2.0/index.html

Karma为前端自动化测试提供了跨浏览器测试的能力,可以自动在Chrome,Firefox,IE等主流浏览器依次跑完测试用例,同时也支持headless浏览器(入phantomJs)中运行测试用例。webpack+babel可以主动为想要适配的浏览器提供转码和垫片补丁引入能力,而Karma可以为最终的结果提供验证能力。Karma的配置方式可以阅读《webpack4.0各个击破(9)——Karma篇》进行了解。

2.2 Mocha

Mocha是前端自动化测试框架,测试框架需要解决兼容不同风格断言库测试用例分组同步异步测试架构生命周期钩子等框架级的能力。

  • Mocha的基本语法
describe('我现在要测某一个页面的几个功能',function(){
    describe('现在要测XX功能',function(){
        it('某个变量的值应该是数字',function(){
            //写断言
        })
    });
     describe('现在要测YY功能',function(){
        it('某个数组长度应该不小于10',function(){
            //写断言
        })
    });
})
  • 异步测试语法
describe('现在要测XX功能',function(){
    it('某个变量的值应该是数字',function(done){
        //写断言
        //手动调用done()表示异步结束,类似于Promise中的resolve
    })
});
  • 不同风格的断言库 支持should.js,expect.js及node核心断言模块assert等。
  • 生命周期钩子 生命周期钩子一般用来建立和清理环境或全局变量。
describe('hooks', function() {
  before(function() {
    // runs before all tests in this block
  });
  after(function() {
    // runs after all tests in this block
  });
  beforeEach(function() {
    // runs before each test in this block
  });
  afterEach(function() {
    // runs after each test in this block
  });
  // test cases
});

2.3 Chai

Chai是一个断言库合集,支持expect,assert,should断言语法,非专业测试岗位其实没必要深究,了解使用方法就可以了。使用示例:

expect(bar).to.not.exist;//断言变量bar不存在
expect(data).to.have.ownProperty('length');//断言data有length属性
expect(name).to.be.a('string');//断言name是一个字符串
assert.equal(value1,value2);//断言value1和value2相等
Tim.should.be.an.instanceof(Person);//断言Tim是Person类的实例

上面的语法在引入了Chai后都是支持的,当断言不成立时,结果报告中会给出明确标记。

三. 基于Chai的自动化单元测试

单元测试的原理并不算复杂,相当于另外编写了一套程序,把业务逻辑中的脚本文件当做模块引入,模拟其运行环境(例如需要的浏览器类型,全局变量等),然后使用一组或若干组覆盖不同使用场景的参数来调用想要测试的函数单元,并判断函数返回的结果是否和预期的相同。

简单地说,自动化测试工具只是取代了一个照着Excel表格测试并记录结果的人力资源。

测试用例文件的基本写法:

var chai = require('chai');//引入断言库
var expect = chai.expect;//使用expect语法
//引用源代码中的业务逻辑模块;
var ColorFac = require('../../../../src/components/Example/colorFac');

describe("ColorFac Module Test", function () {
  it("should return a luminanced color", function () {
      //调用源代码中业务逻辑模块中的方法;
    var color = ColorFac.luminate("#fff", "-0.5");
      //编写测试断言
    expect(color).is.not.empty;
  });
});

单元测试报告:

使用Webpack + Karma + Mocha + Chai进行自动化测试(单元测试+代码覆盖率)的方法可以查看《webpack4.0各个击破(9)——Karma篇》

四. 基于Chai-http的自动化接口测试

Chai-Http是基于Chai扩展的插件,可用于测试与http请求相关的逻辑代码。开发中也可以利用PostMan或是DocLever来管理接口并进行接口测试。接口测试的运行方式和单元测试很类似,区别在于测试用例的写法。假设接口测试的用例都写在/test/apis/apis.js中,配置方式如下:

Karma.api.conf.js:

var path = require('path');
module.exports = function(config) {
    config.set({
        files: [
            'test/apis/apis.js'
        ],
        // frameworks to use
        frameworks: ['mocha'],
        preprocessors: {
            // only specify one entry point
            // and require all tests in there
            'test/apis/apis.js': ['webpack']
        },
        reporters: ['mocha'],
        webpack: {
            mode: 'none',
        },
        webpackMiddleware: {
            noInfo: true
        },
        plugins: [
            require("karma-webpack"),
            require("karma-mocha"),
            require("karma-chai"),
            require("karma-chrome-launcher"),
            require("karma-mocha-reporter"),
        ],
        browsers: ['Chrome']
    });
};

/test/apis/apis.js:(测试用例的语义化非常明显,代码基本不需要解释)。

var chai = require('chai');
var chaiHttp = require('chai-http');
var expect = chai.expect;
chai.use(chaiHttp);

//define address
const ADDRESS = "http://localhost:3001";
//open a http connection
var requester = chai.request(ADDRESS);
describe('列表服务APIS测试',function () {

    it('GET /healthmap/chart1 应该返回包含legendData字段的数据',function (done) {
        chai.request(ADDRESS).get('/healthmap/chart1')
        .end((err,res)=>{
            var data = JSON.parse(res.text);
            expect(res).to.have.status(200);
            expect(data.data).to.have.ownProperty('legendData');
            done();
        })
    });
    
    it('GET /operationdashboard/systemwarn 应该返回字符串',function (done) {
        chai.request(ADDRESS).get('/operationboard/systemwarn')
        .end((err,res)=>{
            var data = JSON.parse(res.text);
            expect(res).to.have.status(200);
            expect(data.data).to.be.a('String');
            done();
        })
    });
})

命令行里启动Karma跑一下接口测试,就可以看到结果:

测试用例没通过的接口全都被标记出来了,省心省力。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏吉浦迅科技

DAY41:阅读Synchronization Functions

waits until all threads in the thread block have reached this point and all glob...

9030
来自专栏游戏杂谈

Ant+JSDocTookit生成Javascript文档

需要备上下面三样东西 JSDocTookit http://code.google.com/p/jsdoc-toolkit/

21130
来自专栏王硕

原 PostgreSQL的FSM分析记录

9610
来自专栏撸码那些事

我看依赖注入

15830
来自专栏Python自动化测试

工厂设计模式在自动化中的引用(一)

在自动化测试的范围中,目前依据webdriver的,web应用测试框架有selenium2,对于移动app自动化的测试,有appium,selen...

17430
来自专栏魏琼东

一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-实例一个模块(商品字典)

        本文是一步一步教你使用AgileEAS.NET基础进行应用开发系统的WinForm应用篇的开篇,从本文起开始大家将看到一个距离真实应用非常接的开...

20550
来自专栏农夫安全

高级PHP应用程序漏洞审核技术【一】

前言 小编入门代码审计时看的几篇写的比较经典的PDF文档之一,分享出来希望能帮助到想学习代码审计的小伙伴。 [目录] 1. 前言 2. 传统的代码审计技...

501110
来自专栏Crossin的编程教室

Python 抓取网页乱码原因分析

在用 python2 抓取网页的时候,经常会遇到抓下来的内容显示出来是乱码。 发生这种情况的最大可能性就是编码问题:运行环境的字符编码和网页的字符编码不一致。 ...

38460
来自专栏开发 & 算法杂谈

基于Lockset的数据竞争检测方法汇总(二)

前一篇文章提到的是使用Lockset最经典的方法,但是存在很多误报,针对这些误报产生的原因,有很多分析并改进了原始的Lockset方法,今天主要和大家谈的就是有...

17870
来自专栏UDNZ

【译】Go 语言实践:编写可维护的程序的建议

本文为 QCon 2018 上海站主题演讲嘉宾、Heptio 资深工程师、著名 Go 语言专家 David Cheney 关于 Go 语言实践的英文分享。为方便...

51980

扫码关注云+社区

领取腾讯云代金券