天天看点

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

Karma+Jasmine+istanbul+webpack自动化单元测试

前言

一直用别人配置好的东西,经常看别人写教程来写简单的单元测试,闲来无事自己也来撸个配置玩玩。说干就干,从开始到运行成功差不多5个小时。遇到各种问题,主要是各种模块的配置版本问题。

简单介绍一下要用到东西是什么

Karma的介绍

Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma。Karma是一个让人感到非常神秘的名字,表示佛教中的缘分,因果报应,比Cassandra这种名字更让人猜不透!

Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner)。该工具可用于测试所有主流Web浏览器,也可集成到CI(Continuous integration)工具,也可和其他代码编辑器一起使用。这个测试工具的一个强大特性就是,它可以监控(Watch)文件的变化,然后自行执行,通过console.log显示测试结果。

Jasmine的介绍

Jasmine是单元测试框架,我将用Karma让Jasmine测试自动化完成。jasmine提出行为驱动【BDD(Behavior Driven Development)】,测试先行理念,Jasmine的官网

istanbul的介绍

istanbul是一个单元测试代码覆盖率检查工具,可以很直观地告诉我们,单元测试对代码的控制程度。(ps:这个玩意浪费我好久时间,后面详细说怎么配置)

webpack的介绍

webpack 是一个现代 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成少量的 bundle - 通常只有一个,由浏览器加载。(引用webpack中文网介绍)

构建Test工程,开始新生上路

  1. 创建一个文件test-demo
  2. 进入test-demo,在当前文件夹里打开命令行,输入

    npm init -y

    ;
    Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
  3. 自动生成package.json文件。
    Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
ps: 我的环境:nodejs v8.2.1 npm v5.3.0

安装相关依赖

安装Karma

npm install karma -g
           

并且还有安装项目中使用

需要全局安装,可以使用命令行。

安装完成以后,命令行输入

karma start

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

在浏览器输入

http://localhost:9876/

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

如果出现以上信息,表示

karma

已经安装成功。

Karma配置

初始化karma配置文件karma.conf.js

ctrl+c 结束刚才启动的Karma

在命令行输入

karma init

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

接下就是一段询问关于配置的问题。(ps:karma.conf.js配置可以自己修改,这里是快速生成配置)

1. Which testing framework do you want to use ?(你想要使用哪个测试框架?)

默认是jasmine。(如果你想用其他可以自己修改),直接回车下一步

  1. Do you want to use Require.js ? (你要使用Require.js吗?)

    This will add Require.js plugin. (这将添加Require.js插件。)

    Press tab to list possible options. Enter to move to the next question. (按选项卡列出可能的选项。 输入转到下一个问题。)

    默认是no。(现在都在使用webpack打包,这也是为什么你肯定奇怪的地方,单元测试为什么要用webpack) ,直接回车下一步

  2. Do you want to capture any browsers automatically ? (你想要在哪些浏览器里面运行)

    Press tab to list possible options. Enter empty string to move to the next question.(和上面一样)

    默认是Chrome。(你可以添加更多浏览器回车就是填写下一个浏览器名称,必须是你电脑安装的浏览器,最好还是去karma.conf.js添加直观一些),直接按2次回车下一步

  3. What is the location of your source and test files ?(测试文件的位置是什么?)

    You can use glob patterns, eg. “js/.js” or “test/*.spec.js,就是说scr文件夹下的所有

    .spec.js

    后缀都是t测试用例文件。回车下一步
    Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
    你写了这样一定会跟我报错,
    Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
    需要去如图新建随意

    .spec.js

    后缀文件,

如果不想建,可以直接下一步,等会到

karma.conf.js

修改。

  1. Should any of the files included by the previous patterns be excluded ?(是否应排除某些包含的任何文件?)

    You can use glob patterns, eg. “/.swp”. (您可以使用glob模式,例如。“/.SWP”。)

    这是为了性能优化,排除那些文件不需要去监听,加快运行速度。如果你不确定要排除哪些文件,可以去

    karma.conf.js

    修改。我就直接直接下一步了。
  2. Do you want Karma to watch all the files and run the tests on change ? (你想要Karma来监听所有的文件,并在变化中运行测试吗?)

    Press tab to list possible options. (按选项卡列出可能的选项。)

    默认yes,它的意思你写完了

    .spec.js

    后缀文件会自动运行测试,等我们把

    Karma

    跑起来,在自动运行。

    这里no。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

这就生成出来了配置

找一款你顺手的编辑器打开它,(我的用vscode)

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

一大堆看不懂的东西,我给它们一一注释一下;

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

接下来就说关于依赖插件plugins

1. 需要可以打开Chrome浏览器的插件

npm install karma-chrome-launcher --save-dev

2. 需要可以运行jasmine的插件

npm install karma-jasmine --save-dev

3. 需要可以运行webpack的插件

npm install karma-webpack --save-dev

4. 需要可以显示sourcemap的插件

npm install karma-sourcemap-loader --save-dev

5. 需要可以显示测试代码覆盖率的插件

npm install karma-coverage-istanbul-reporter --save-dev

插件就先安装这么多,后面需要在安装,可以这样一起安装:

把插件写到配置里面去

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

我们先只需要前2个,后面注释起来,让

karma

能随时跑起来。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

然后去

package.json

配置一个npm命令,编辑器或者ide可以直接运行npm命令。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

我们

karma

可以运行起来,karma配置先就到这里。

安装Jasmine

并且还有安装项目中使用

在安装的过程我们可以去看看jasmine文档

jasmine 5个核心

  1. describe块称为”测试套件”(test suite),表示一组相关的测试。它是一个函数,第一个参数是测试套件的名称(”index.js的测试”),第二个参数是一个实际执行的函数。
  2. it块称为”测试用例”(test case),表示一个单独的测试,是测试的最小单位。它也是一个函数,第一个参数是测试用例的名称(”1应该是数字”),第二个参数是一个实际执行的函数。
  3. expect是解析一段代码,返回解析后的值。
  4. 匹配器,jasmine内置了很多匹配器,例如:toBe 、not.toBe等,也可以自定义匹配器。
  5. 钩子函数,为了减少重复性的代码,jasmine提供了beforeEach、afterEach、beforeAll、afterAll方法。
    • beforeEach() :在describe函数中每个Spec执行之前执行;
    • afterEach() :在describe函数中每个Spec执行之后执行;
    • beforeAll() :在describe函数中所有的Specs执行之前执行,且只执行一次
    • afterAll () : 在describe函数中所有的Specs执行之后执行,且只执行一次

看了文档我们去写一个简单测试用例。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

这个例子非常简单,

1+1===2

;

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

因为我们的测试示例写的是对的,所以没有任何错误提示。

怎么看运行结果,karma会自动打开一个谷歌浏览器

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

点击后一片空白

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

打开控制台(F12)

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

可以看到输出结果。非常ok

接下来我们加一个1+1===3,这个按正常来说是错的,

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

你会发现没有任何提示,因为我们没有安装一些东西,后面来说。现在只能去看karma打开的谷歌浏览器的控制台了。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

有一个错误提示,说预期2,和匹配结果3不对应。ok没毛病。

简陋版测试已经跑起来了,接下来我们要写自己代码

add相加函数

安装Webpack

注意:Webpack有3个版本,1,2,3每个版本某些写法都有些差别,注意看官方文档,最新版3.5.5。

安装需要时间,这个我们去写个简单的例子,一个简单的add函数。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

这里用的es6,模块导出,浏览器还不认识,需要用到babel转换。

  1. babel核心文件

    npm install babel-core --save-dev

  2. webpack的Loader处理器

    npm install babel-loader --save-dev

  3. babel的istanbul覆盖率插件

    npm install babel-plugin-istanbul --save-dev

  4. babel转换到哪个版本这里是ES2015

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

    插件就先安装这么多,后面需要在安装,可以这样一起安装:

这时候我们代码还是那样,需要去配置

karma.conf.js

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

webpack配置就不多做介绍,这里不是webpack教程,也不是一两句可以说完,看教程。

因为这里配置比较简单,就直接放在里面。如果复杂就需要单独抽出去做一个配置文件。

ps:它和我们一般项目的配置是有点区别的,webpack有四个核心概念:入口(entry)、输出(output)、loader、插件(plugins)。这里不需要入口(entry)和输出(output)配置。这点需要注意。

还需要打开注释的插件

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

运行一下

npm run unit

, 没错误继续。一步一个脚印,不要到最后全是错误,放弃了。边写边测试。

测试add函数

  1. add.spec.js引入add.js
import add from './add';
           
  1. 新增一个测试套件
    Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
  2. 运行

    npm run unit

    Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
  3. karma打开的浏览器查看
    Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

出问题了,现在浏览器都还不识别

import

。我们需要用

babel

转换成ES5显示。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

我们需要配置preprocessors

我们在运行,打开控制台查看:

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

完美运行

接着继续,我们还需要生成源文件映射的map文件,

修改配置:

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
注意:每次修改完

karma.conf.js

都需要重新运行

npm run unit

。运行没有问题,我们接着继续最后一个话题

istanbul

代码覆盖率显示。

安装Istanbul

还需要安装Istanbul相关的依赖

1. webpack的Loader处理器

npm install istanbul-instrumenter-loader --save-dev

2. 测试覆盖率显示插件

npm install karma-coverage-istanbul-reporter --save-dev

我们先安装他们,然后去修改

karma.conf.js

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

先给

babel

加上插件

plugins: ['istanbul']

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

在写上

istanbul-instrumenter-loader

的配置。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
注意:这是webpack官方给的例子,注意画红线的,官方给的有问题,这个配置是决定Loader的优先级。
Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

添加完成以后,重新运行

npm run unit

。没问题继续。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

我们使用

coverage-istanbul

显示测试结果

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

打开所有插件注释。

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

覆盖率显示配置,看注释说明

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试
注意:一定要打开自动监听才有覆盖率显示,

运行以后,就会生成

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

命令行显示

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

文件夹里面显示

怎么测覆盖率(code coverage)

它有四个测量维度。

- 行覆盖率(line coverage):是否每一行都执行了?

- 函数覆盖率(function coverage):是否每个函数都调用了?

- 分支覆盖率(branch coverage):是否每个if代码块都执行了?

- 语句覆盖率(statement coverage):是否每个语句都执行了?

export default function add(num1, num2) {
    return num1 + num2;
}
           

我们将这个函数变得复杂点,如果不写num2,就默认是0。

export default function add(num1, num2) {
    if (num2 === undefined) num2 = ;
    return num1 + num2;
}
           
Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

命令行显示结果

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

浏览器打开

coverage/html/index.html

注意:命令行显示合计测试覆盖率,详细需在浏览器看。

测试结果分析:

1个语句覆盖率(statement coverage)没有覆盖到,1个分支覆盖率(branch coverage)没有覆盖到,1个函数覆盖率(function coverage)已经调用,3行行覆盖率(line coverage)全部覆盖

我们再来个复杂的栗子:

export default function add(num1, num2) {
    if (num1 === undefined) num1 = ;
    if (num2 === undefined) num2 = ;
    return num1 + num2;
}
           
Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

命令行显示结果

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

浏览器打开

coverage/html/index.html

测试结果分析:

2个语句覆盖率(statement coverage)没有覆盖到,2个分支覆盖率(branch coverage)没有覆盖到,1个函数覆盖率(function coverage)已经调用,3行行覆盖率(line coverage)全部覆盖

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

增加测试用例

Karma+Jasmine+istanbul+webpack自动化单元测试Karma+Jasmine+istanbul+webpack自动化单元测试

全部覆盖,ok完工。demo

继续阅读