Mocha和单元测试

Mocha测试框架和项目实例

测试项目已上传githubcss

地址:https://github.com/Hanxueqing...html

运行克隆命令,下载到本地前端

git clone git@github.com:Hanxueqing/Mocha-test.gitvue

1、什么是Mocha

Mocha(发音"摩卡")诞生于2011年,是如今最流行的JavaScript测试框架之一,在浏览器和Node环境均可以使用。所谓"测试框架",就是运行测试的工具。经过它,能够为JavaScript应用添加测试,从而保证代码的质量。node

2、Mocha安装和准备

前期准备:安装vue-cli脚手架、安装node、安装Gitgit

(1)先用vue-cli建立一个vue-test项目github

vue create vue-test

(2)全局安装mochavue-cli

npm i mocha -g

将mocha安装到本地目录npm

npm i mocha -D

(3)修改package.json中的test路径为咱们本地的mocha路径json

"test": "./node_modules/mocha/bin/mocha"

3、测试框架

一、建立test文件夹

测试脚本都存放在test文件夹中

二、编写测试框架

建立test/demo.js

describe("Demo", function(){
    describe("方法 1", function(){
        context("情境 1", function(){
            before(function(){
                console.log("-----测试以前------");
            });
            after(function(){
                console.log("-----测试以后------");
            });
            beforeEach(function(){
                console.log("-------每条测试以前---------");
            })
            afterEach(function(){
                console.log("-------每条测试以后---------");
            })
            it("测试 1", function(){

            })
            it("测试 2", function(){
                
            })
        })
    })
})

上面这段代码,就是测试脚本,它能够独立执行。测试脚本里面应该包括一个或多个describe块,每一个describe块应该包括一个或多个it块。

describe

describe块称为"测试套件"(test suite),表示一组相关的测试。它是一个函数,第一个参数是测试套件的名称("Demo"),第二个参数是一个实际执行的函数。

it

it块称为"测试用例"(test case),表示一个单独的测试,是测试的最小单位。它也是一个函数,第一个参数是测试用例的名称("测试1"),第二个参数是一个实际执行的函数。

测试用例的钩子

Mocha在describe块之中,提供测试用例的四个钩子:before()after()beforeEach()afterEach()。它们会在指定时间执行。

befor:定义测试以前进行的操做

after:定义测试以后进行的操做

beforeEach:定义每条测试以前进行的操做

afterEach:定义每条测试以后进行的操做

三、进行测试

执行mocha 命令使用全局安装的mocha进行测试或者执行npm test命令使用本地安装的mocha进行测试

4、断言库chai

所谓"断言",就是判断源码的实际执行结果与预期结果是否一致,若是不一致就抛出一个错误。

一、全局安装chai模块

npm i chai -g

二、本地安装chai模块

npm i chai -D

三、断言风格

断言库有不少种,Mocha并不限制使用哪种。

assert风格的断言

在test文件夹下新建test_lib文件夹,建立assert.js编写测试脚本。

const chai = require("chai");
//引入断言的风格
const assert = chai.assert;

describe("Demo", function () {
    it("使用 assert风格的断言测试", function () {
        var value = "hello";
        //断言value值的类型为字符串
        assert.typeOf(value, "string");
        //断言value值等于"hello"
        assert.equal(value, "hello");
        //断言value值的长度为5
        assert.lengthOf(value, 5);
    })
})

进入test_lib文件夹下,执行mocha assert.js运行测试脚本,由于咱们这三个断言都是真的,因此测试经过。

should风格断言

建立should.js编写测试脚本。

const chai = require("chai");
const should = chai.should();

describe("Demo", () => {
    it("使用 should风格的断言测试", function () {
        var value = "hello";
        //value应该存在
        value.should.exist
        //value的数字类型应该是一个字符串
        value.should.be.a("string");
        //value值应该等于"hello"
        value.should.equal("hello");
        //value值不等于"你好"
        value.should.not.equal("你好");
        //value的长度应该为5
                value.should.have.length(5);
        

    })
})

咱们也能够换成另外一种更简洁的写法,使用and链接断言

value.should.exist
            .and.be.a("string")
            .and.equal("hello")
            .and.have.length(5)

进入test_lib文件夹下,执行mocha should.js运行测试脚本,由于咱们这五个断言都是真的,因此测试经过。

expect风格断言

expect断言的优势是很接近天然语言

建立expect.js编写测试脚本。

const chai = require("chai");
const expect = chai.expect;

describe("Demo", () => {
    it("使用 expect风格的断言测试", function () {
        var value = "hello";
        //value应该存在
        expect(value).to.exist;
        //value的数字类型应该是一个字符串
        expect(value).to.be.a("string");
        //value值应该等于"hello"
        expect(value).to.equal("hello");
        //value值不等于"你好"
        expect(value).to.not.equal("你好");
        //value的长度应该为5
        expect(value).to.have.length(5);
    })
})

进入test_lib文件夹下,执行mocha expect.js运行测试脚本,由于咱们这五个断言都是真的,因此测试经过。

一样咱们也能够定义一个数字,使用expect断言来判断数字的区间

var number = 3;
        //判断number是否在3~5之间的数
        expect(number).to.be.at.most(5);
        expect(number).to.be.at.least(3);
        //判断number是否在1~3之间的数
        expect(number).to.be.within(1, 3);

5、编写测试脚本

Mocha的做用是运行测试脚本,首先必须学会写测试脚本。所谓"测试脚本",就是用来测试源码的脚本。

一、测试返回结果是否正确

(1)建立被测试的项目lib/demo-1.js

class Demo {
    subtotal(unitPrice, quantity) {
        return unitPrice * quantity;
    }
}
module.exports = Demo;

(2)建立测试脚本test/demo-1.test.js

一般,测试脚本与所要测试的源码脚本同名,可是后缀名为.test.js(表示测试)或者.spec.js(表示规格)。好比,demo-1.js的测试脚本名字就是demo-1.test.js

//demo-1.test.js
const chai = require("chai");
const expect = chai.expect;

var Demo = require("../lib/demo-1");
var demo = new Demo();
describe("Demo",()=>{
    it("单价10块钱的3件商品小计金额应该是30块",function(){
        var subtotal = demo.subtotal(10,3);
        expect(subtotal).to.equal(30);
    })
})

二、异步操做测试setTimeout

(1)Mocha默认每一个测试用例最多执行2000毫秒,若是到时没有获得结果,就报错。对于涉及异步操做的测试用例,这个时间每每是不够的,须要用-t--timeout参数指定超时门槛。

进入lib/demo-1.js,编写异步等待方法,规定2秒以后返回结果

waitTwoSecond(data,callback){
        setTimeout(function(){
            callback(data);
        },2000);
    }

(2)进入test/demo-1.test.js,编写测试脚本

//异步操做测试
    //mocha不会等到异步执行结束之后进行测试,而是直接运行获得测试结果
    it("一段时间之后返回数据",function(done){
        demo.waitTwoSecond("hello",function(data){
            expect(data).to.equal("hello")
            done(); //只有调用done方法才能等待调用结束之后测试
            //mocha默认的等待时间是2秒,上述操做超过两秒,报错
            //运行命令mocha demo-1.test.js -t 5000重置等待时间解决
        })
    })

另外,上面的测试用例里面,有一个done函数。it块执行的时候,传入一个done参数,当测试结束的时候,必须显式调用这个函数,告诉Mocha测试结束了。不然,Mocha就没法知道,测试是否结束,会一直等到超时报错。若是把这行删除,则mocha不会等到异步执行结束之后进行测试,而是直接运行获得测试结果,返回的断言结果始终为真。

(3)虽然测试用例中规定2秒返回结果,可是实际运行时间确定超过2秒,因此,须要用-t--timeout参数,改变默认的超时设置。

mocha demo-1.test.js -t 5000

上面命令将测试的超时时限指定为5000毫秒。

三、测试接口数据https

接口地址https://douban.uieee.com/v2/m...

(1)lib/demo-1.js

引入https模块

var https = require("https");

定义fetchData方法

fetchData(api,callback){
        var requestUrl = `https://douban.uieee.com/v2/movie/${api}`;
        https.get(requestUrl,function(res){
            var responseData = ""
            res.setEncoding("utf8")

            res.on("data",function(chunk){
                responseData += chunk
            })

            res.on("end",function(){
                callback(JSON.parse(responseData))
            })
        })
    }

(2)test/demo-1.test.js

it("加载豆瓣api,返回的数据,应该包含subjects属性",function(done){
        demo.fetchData("top250",function(data){
            expect(data).to.have.property("subjects");
            done();
        })
    })

    it("加载豆瓣api,返回的数据,subjects应为对象类型", function (done) {
        demo.fetchData("top250", function (data) {
            var subjects = data.subjects;
            expect(subjects).to.be.a("array");
            done();
        })
    })

    it("加载豆瓣api,返回的数据,subjects长度应为20", function (done) {
        demo.fetchData("top250", function (data) {
            var subjects = data.subjects;
            expect(subjects).to.have.length(20);
            done();
        })
    })

    it("加载豆瓣api,返回的数据,title属性应该是字符串类型的", function (done) {
        demo.fetchData("top250", function (data) {
            var title = data.subjects[0].title
            expect(title).to.be.a("string");
            expect(title).to.equal("肖申克的救赎")
            done();
        })
    })

(3)运行结果

四、测试异常

(1)lib/demo-1.js

engine(fuel){
        if(fuel !== "gas"){
            throw new Error("not accept")
        }
    }

(2)test/demo-1.test.js

//定义一个异常
    it("给汽车引擎加水是不能接受的事情",function(){
        expect(function(){
            demo.engine("water");
        }).to.throw("not accept")
    })
//另一种写法
    it("给汽车引擎加水是不能接受的事情",function(){
        expect(demo.engine.bind(demo,"water")).to.throw("not accept")
    })

(3)测试结果

6、运行多个测试

一、直接使用mocha命令运行test子目录中的测试脚本

Mocha默认运行test子目录里面的测试脚本。因此,通常都会把测试脚本放在test目录里面,而后执行mocha就不须要参数了。

因此在控制台中输入mocha,只会执行test子目录里的测试脚本demo-1.test.js和demo.js,而test_lib中的assert.js、expect.js、should.js则不会执行。

运行结果:

二、执行test子目录下面全部的测试用例

这时能够看到,test子目录里面的测试脚本执行了。可是,你打开test子目录,会发现下面还有一个test/test_lib子目录,里面还有三个测试脚本assert.js、expect.js、should.js,并无获得执行。Mocha默认只执行test子目录下面第一层的测试用例,不会执行更下层的用例。

为了改变这种行为,就必须加上--recursive参数,这时test子目录下面全部的测试用例,无论在哪一层,都会执行。

mocha --recursive

运行结果:

三、执行多个测试脚本

mocha命令后面紧跟测试脚本的路径和文件名,能够指定多个测试脚本。

进入tets_lib目录下,运行assert.js和should.js两个测试脚本

mocha assert.js should.js

运行结果

7、测试用例管理

一、only表示只运行某个测试套件或测试用例。

大型项目有不少测试用例。有时,咱们但愿只运行其中的几个,这时能够用only方法。describe块和it块都容许调用only方法,表示只运行某个测试套件或测试用例。

it.only("单价10块钱的3件商品小计金额应该是30块",function(){
        var subtotal = demo.subtotal(10,3);
        expect(subtotal).to.equal(30);
    })

运行结果:只运行了添加only方法的测试脚本

二、skip表示跳过指定的测试套件或测试用例。

it.skip("一段时间之后返回数据",function(done){
        demo.waitTwoSecond("hello",function(data){
            expect(data).to.equal("hello")
            done(); //只有调用done方法才能等待调用结束之后测试
            //mocha默认的等待时间是2秒,上述操做超过两秒,报错
            //运行命令mocha demo-5.js -t 5000重置等待时间解决
        })
    })

运行结果:跳过了添加skip方法的测试脚本

8、ES6测试

一、ES5写法

src/add.js

function add(x, y) {
    return x + y;
}

module.exports = add;

test/demo-2.test.js

const chai = require("chai");
const expect = chai.expect;
var Add = require("../src/add.js");

describe('加法函数的测试', function () {
    it('1 加 1 应该等于 2', function () {
        expect(Add(1, 1)).to.be.equal(2);
    });
});

运行命令

mocha

运行结果

二、ES6写法

test/demo-2.test.js

const chai = require("chai");
const expect = chai.expect;
var Add = require("../src/add.js");

describe('加法函数的测试', function () {
    it('1 加 1 应该等于 2', function () {
        expect(Add(1, 1)).to.be.equal(2);
    });
});

若是测试脚本是用ES6写的,那么运行测试以前,须要先用Babel转码。

(1)安装Babel

npm install babel-core babel-preset-es2015 --save-dev

(2)在项目目录下面,新建一个.babelrc文件:

{
  "presets": [ "es2015" ]
}

运行命令

./node_modules/mocha/bin/mocha --require babel-core/register

运行结果

9、测试报告

运行 mocha --reporters能够显示全部内置的报告格式。

一、spec格式

--reporter参数用来指定测试报告的格式,默认是spec格式。

mocha
等同于
mocha --reporter spec

运行结果:

二、tap格式

mocha --reporter tap

运行结果:

三、HTML格式

使用mochawesome模块,能够生成漂亮的HTML格式的报告。

(1)安装mochawesome模块

npm install --save-dev mochawesome

(2)执行测试命令

./node_modules/.bin/mocha --reporter mochawesome

上面代码中,mocha命令使用了项目内安装的版本,而不是全局安装的版本,由于mochawesome模块是安装在项目内的。

(3)运行结果:

(4)测试结果报告在mochaawesome-reports子目录生成。

(5)在浏览器中浏览html格式的测试报告

10、生成测试文件

Mocha支持从测试用例生成规格文件。

一、Markdown格式

mocha demo-1.test.js --recursive -R markdown > spec.md

上面命令根据test目录的demo-1.test.js测试脚本,生成一个规格文件spec.md-R markdown参数指定规格报告是markdown格式。

二、HTML格式

mocha demo-1.test.js --recursive -R doc > spec.html

上面命令根据test目录的demo-1.test.js测试脚本,生成一个规格文件spec.html.

11、在浏览器中测试

除了在命令行运行,Mocha还能够在浏览器运行。

一、首先,使用mocha init命令在指定目录生成初始化文件。

mocha init vue-test

运行上面命令,就会在vue-test目录下生成index.html文件,以及配套的脚本和样式表。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Mocha</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="mocha.css">
  </head>
  <body>
    <div id="mocha"></div>
    <script src="mocha.js"></script>
    <script>mocha.setup('bdd');</script>
    <script src="tests.js"></script>
    <script>
      mocha.run();
    </script>
  </body>
</html>

二、新建一个源码文件add.js

function add(x, y) {
    return x + y;
}

module.exports = add;

三、新建一个测试脚本tests.js

var expect = chai.expect;

describe('加法函数的测试', function () {
    it('1 加 1 应该等于 2', function () {
        expect(add(1, 1)).to.be.equal(2);
    });

    it('任何数加0等于自身', function () {
        expect(add(1, 0)).to.be.equal(1);
        expect(add(0, 0)).to.be.equal(0);
    });
});

四、而后,把这个文件,以及断言库chai.js,加入index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Mocha</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="mocha.css">
  </head>
  <body>
    <div id="mocha"></div>
    <script src="mocha.js"></script>
    <script>mocha.setup('bdd');</script>
    <script src="add.js"></script>
    <script src="http://chaijs.com/chai.js"></script>
    <script src="tests.js"></script>
    <script>
      mocha.run();
    </script>
  </body>
</html>

五、如今,在浏览器里面打开index.html,就能够看到测试脚本的运行结果。

参考文档

mocha官网

https://mochajs.org/

测试框架 Mocha 实例教程 by 阮一峰

https://juejin.im/entry/5941e...

【前端单元测试入门01】Mocha与chai

https://www.jianshu.com/p/aa5...

vue项目中添加单元测试

https://blog.csdn.net/weixin_...

vue官网-单元测试模块

https://cn.vuejs.org/v2/guide...

相关文章
相关标签/搜索