Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jiayisheji opened this issue Aug 26, 2017 · 6 comments
Open

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

jiayisheji opened this issue Aug 26, 2017 · 6 comments

Comments

@jiayisheji
Copy link
Owner

jiayisheji commented Aug 26, 2017

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;
    image

  3. 自动生成package.json文件。
    image

ps: 我的环境:nodejs v8.2.1 npm v5.3.0

@jiayisheji
Copy link
Owner Author

jiayisheji commented Aug 26, 2017

安装相关依赖

安装Karma

npm install karma -g

并且还有安装项目中使用

npm install karma  --save-dev

需要全局安装,可以使用命令行。
安装完成以后,命令行输入 karma start
image

在浏览器输入http://localhost:9876/
image

如果出现以上信息,表示karma已经安装成功。

Karma配置

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

ctrl+c 结束刚才启动的Karma

在命令行输入karma init

image

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

  1. Which testing framework do you want to use ?(你想要使用哪个测试框架?)
    默认是jasmine。(如果你想用其他可以自己修改),直接回车下一步

  2. 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) ,直接回车下一步

  3. 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次回车下一步

  4. What is the location of your source and test files ?(测试文件的位置是什么?)
    You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".(你可以使用glob模式,例如。 “js / *.js”或“test / ** / * Spec.js”)
    Enter empty string to move to the next question.(输入空字符串移动到下一个问题。)
    默认是空,这个是配置你的单元测试用例的文件,根据自己项目和喜好,你可以把测试用例文件和当前被文件放在一起,例如angular-cli就是这样的。也可以单独分离放到test文件下,github大量的npm包都是这样的。我这里就学angular-cli做法,填写:src/**/*.spec.js,就是说scr文件夹下的所有.spec.js后缀都是t测试用例文件。回车下一步
    image
    你写了这样一定会跟我报错,
    image
    需要去如图新建随意.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。

image
这就生成出来了配置
找一款你顺手的编辑器打开它,(我的用vscode)
image
一大堆看不懂的东西,我给它们一一注释一下;
image

接下来就说关于依赖插件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

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

npm install karma-chrome-launcher karma-jasmine karma-webpack karma-sourcemap-loader karma-coverage-istanbul-reporter  --save-dev

把插件写到配置里面去
image

我们先只需要前2个,后面注释起来,让karma能随时跑起来。
image
然后去package.json 配置一个npm命令,编辑器或者ide可以直接运行npm命令。
image
我们karma可以运行起来,karma配置先就到这里。

@jiayisheji
Copy link
Owner Author

jiayisheji commented Aug 26, 2017

安装Jasmine

并且还有安装项目中使用

npm install jasmine-core  --save-dev

在安装的过程我们可以去看看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执行之后执行,且只执行一次

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

这个例子非常简单,1+1===2;
image

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

怎么看运行结果,karma会自动打开一个谷歌浏览器
image
点击后一片空白
image
打开控制台(F12)
image
可以看到输出结果。非常ok

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

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

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

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

@jiayisheji
Copy link
Owner Author

jiayisheji commented Aug 26, 2017

安装Webpack

npm install webpack  --save-dev

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

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

这里用的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
    插件就先安装这么多,后面需要在安装,可以这样一起安装:
npm install babel-core babel-loader install babel-plugin-istanbul babel-loader babel-preset-es2015  --save-dev

这时候我们代码还是那样,需要去配置karma.conf.js
image

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

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

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

还需要打开注释的插件
image

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

测试add函数

  1. add.spec.js引入add.js
import add from './add';
  1. 新增一个测试套件
    image

  2. 运行npm run unit
    image

  3. karma打开的浏览器查看
    image

出问题了,现在浏览器都还不识别import。我们需要用babel转换成ES5显示。
image

我们需要配置preprocessors

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

完美运行

接着继续,我们还需要生成源文件映射的map文件,
修改配置:
image

image

注意:每次修改完karma.conf.js 都需要重新运行npm run unit。运行没有问题,我们接着继续最后一个话题istanbul 代码覆盖率显示。

@jiayisheji
Copy link
Owner Author

jiayisheji commented Aug 26, 2017

安装Istanbul

还需要安装Istanbul相关的依赖

  1. webpack的Loader处理器 npm install istanbul-instrumenter-loader --save-dev
  2. 测试覆盖率显示插件 npm install karma-coverage-istanbul-reporter --save-dev

我们先安装他们,然后去修改karma.conf.js
image

先给babel加上插件plugins: ['istanbul']
image

在写上istanbul-instrumenter-loader的配置。
image

注意:这是webpack官方给的例子,注意画红线的,官方给的有问题,这个配置是决定Loader的优先级。
image

添加完成以后,重新运行npm run unit。没问题继续。

image
我们使用coverage-istanbul显示测试结果
image
打开所有插件注释。

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

image

注意:一定要打开自动监听才有覆盖率显示,

运行以后,就会生成

image

命令行显示

image

文件夹里面显示

怎么测覆盖率(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 = 0;
    return num1 + num2;
}

image
命令行显示结果

image
浏览器打开 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 = 0;
    if (num2 === undefined) num2 = 0;
    return num1 + num2;
}

image
命令行显示结果

image
浏览器打开 coverage/html/index.html

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

image
增加测试用例

image

全部覆盖,ok完工。demo

@liuxsen
Copy link

liuxsen commented Apr 3, 2019

跟着一路走下来,run的很好,大神有没有计划写一下有关 e2e测试的呢?

跟 react / vue 搭配,会更好,或者说大神有没有相关的博客推荐?

@jiayisheji
Copy link
Owner Author

@liuxsen 没有计划,angular有 传送门

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants