NodeJS项目使用AVA模块做自动化测试

目录

1、为什么选择 AVA ?
2、API 概览。
3、准备工作。
4、单元测试,测试一个简单的工具函数。
5、使用 Promise、Async/await、Observable 。
6、使用 JSDOM 模拟浏览器环境。
7、单元测试,测试一个简单的 React 组件。
8、Http 接口测试,GitHub 用户信息接口测试。
9、串行测试。
10、快照断言。
11、覆盖率报告:nyc + Coveralls 。
12、持续集成:CircleCI 。
13、学习借鉴,一些使用 AVA 做测试的开源项目。
14、e2e测试框架推荐:TestCafe 。
15、参考。

为什么选择 AVA

原子测试 – 名词的链接属于自己猜测,不知作者本人是否也是表达这个意思。
断言 – 通俗的讲,就是用来判断 “ 函数的返回值 ” 与我们想要的值是否一致,一致则测试通过,不一致则不通过。

1、轻量,高效,简单。
2、并发测试,强制编写原子测试
3、没有隐藏的全局变量,每个测试文件独立环境。
4、支持 ES2017,Promise,Generator,Async,Observable。
5、内置断言,强化断言信息。
6、可选的 TAP 输出显示
7、为什么不用 Mocha,Tape,Tap?

  1. 官方文档解释:https://github.com/avajs/ava#faq
  2. 一些测试框架的对比:https://github.com/koajs/koa/…

API 概览

内置断言

也可以用 chai, node assert 等其他断言库

准备工作

务虚已过,编写测试用例之前我们需要先安装 AVA
先全局安装:npm i --global ava
再在项目根目录安装一次:npm i --save-dev ava
这是通俗的安装方式,全局安装方便 AVA 自身命令行调用,不用太纠结。

像我们刚刚说的,AVA 已经内置支持 ES2017 的语法,安装 AVA 的时候已经帮我们安装了一些关于 babel 的模块,不过我们还再安装几个我们需要用到的 babel 模块,如下。
npm i --save-dev babel-polyfill babel-preset-es2015 babel-preset-react babel-preset-stage-0

关于 AVA 的一些基础配置的意思,可以查看一下官方文档
实际用到的配置也不多,我们在 package.json 文件中配置一下 AVA :

在项目根目录创建 .babelrc 文件, 并输入以下内容:

这里的坑在于,如果不创建 .babelrc 文件,而是把 babel 的配置写在 package.json 里,在使用 import 导入 React 组件时,会报语法错误。
可使用命令行创建文件:touch .babelrc

看看现在的目录结构是怎么样的:
689022717-59773c9bd0a32_articlex

单元测试,测试一个简单的工具函数

test 目录创建一个 simple_test.js 文件,内容如下

test():执行一个测试,第一个参数为标题,第二参数为测试用例函数,接收一个包含内置断言 API 的参数 t,也是唯一一个参数;按照惯例这个参数名字叫做 t,没必要重新取名字。

这里使用到的内置断言:

  • t.is(resultValue, expected), 断言结果值等于我们想要的预期值,则测试通过。全等判断。
  • t.throws(function), 在 throws 里放入一个函数,函数自动执行,里面执行的结果必须抛出错误,则测试通过。

运行 npm test,可以看到如下结果,一个测试用例通过。
1337936034-59773df7dcad2_articlex

改动一下测试用例,看看测试不通过是怎么样的。

运行 npm test
3284225197-5977410660792_articlex

红色框框就是我们说的强化断言信息,将结果值预期值进行了差异对比,帮助我们定位错误。

使用 Promise、Async/await、Observable

PromiseAsync/await 都是语法层面的东西,Observable 还没深入了解过,
语法糖的代码就不贴来占用空间了,可以下载示例代码看看就会了。
Observable 这里的坑在于需要引入 RxJS: npm i --save rxjs,官方文档并没有说明。

使用 JSDOM 模拟浏览器环境

安装 JSDOM 模块:npm i --save-dev jsdom

在目录下创建一个 jsdom.js 文件,内容如下:

简单介绍 JSDOM API

  • new JSDOM(html, {runScripts: 'dangerously'}); :创建一个 DOM 环境,可以传入完整的 HTML 文档,也可以值传入一行 HTML 文档声明,如:<!DOCTYPE html>
  • 参数 runScripts: 'dangerously' 表示让文档里的 JavaScript 可以运行,默认禁止运行。
  • 创建后返回一个对象,里面包含一个 window 对象,我们便是需要用到这个 window 对象,及其属性 document 对象,用在我们的测试。
  • 更多使用方法和配置可以查看一下官方文档

测试里面的代码就是原生的 JavaScript DOM 操作代码。

单元测试,测试一个简单的 React 组件

测试 React 组件需要依赖 JSDOM, 所以我们放在这里讲。
安装需要依赖的一些模块:npm i --save react react-dom, npm i --save-dev enzyme react-test-renderer。这里也不用纠结为什么一会用 --save, 一会用 --save-dev, 因为 --save 表示这些模块在线上项目也需要用到,而 --save-dev 表示这些模块只用作开发或者测试等,线上项目不需要用到这些模块。
Enzyme 是一个 React 测试工具,可以说是把 React 组件渲染在我们测试的环境里,不需要依赖真实的浏览器。
Enzyme 依赖 react-test-rendererReact >=15.5 安装 react-test-renderer,其它版本安装 react-addons-test-utils

src 目录下创建 todo.js 文件,内容如下,一个简单的备忘录组件:

test 目录下创建一个 helpers 文件夹,并在文件夹里面创建 setup_dom_env.js 文件, 内容如下。

AVA 的规则会忽略 helpers 文件夹,不会将里面的文件当做测试文件执行。

这就是 React 组件需要依赖的 JSDOM 模拟的 DOM 环境的代码。
需要将 windowdocumentnavigator 等对象挂载到 global 对象上,组件才能运行。

test 目录下创建 react_component.js, 内容如下,先引入模拟 DOM 环境的文件。

简单介绍 Enzyme API

  • mount: 表示渲染组件的时候支持生命周期,个人觉得测试时一般都会用这个,因为真实组件生命周期的调用是极为平常的事。
  • Enzyme APIjQuery API 很相似,会 jQuery 应该很容易理解。

Http 接口测试,GitHub 用户信息接口测试

打开接口:https://api.github.com/users/…,返回用户的一些基本信息,有些字段值是动态改变的,用户修改即变,这样的动态字段我们可以查询数据库来对比。这里我们以一个假设不变的 login 字段来演示。

先安装 Request 模块: npm i --save-dev request,方便发送 http 请求。

test 目录下创建 http.js, 内容如下。

运行 npm test,可以看到测试通过。
2286793649-597c582b10d35_articlex

串行测试

很多情况并行测试就好,但某些场景我们需要测试按顺序一个接一个的执行,即使是异步,并且后面的测试可能依赖前面测试的结果,这时就需要用到串行测试,test.serial()

test 目录下创建 serial.js, 内容如下,一个简单的串行测试演示。

这里只是 serial.js 文件串行执行,如果想所有文件都串行执行,需要在命令行传递 --serial 标志。

快照断言

t.snapshot(expected, [options]), 将预期值与先前记录的快照进行比较。
第一次运行测试,快照断言会将预期值存储起来,待第二次及以后运行测试,则拿已经存储好的快照与新的预期值进行比较,吻合则测试通过,否则测试失败。

一般用于预期值比较庞大的情况,如:Html 模板,React 渲染出来的模板,或许还可以用于 Http 接口返回的一堆数据。

如下,做个简单演示。

覆盖率报告:nyc + Coveralls

安装模块 nyccoverallsnpm i --save-dev nyc coveralls
扩展测试命令,前面加个 nyc 即可:"test": "nyc ava --verbose"
测试覆盖率是基于文件被测试的情况来反馈出指标,所以我们把 simple_test.js 里的 trimAll 函数单独提出来作为一个文件,放到 src 目录,命名为 trim_all.js

运行 npm test,简洁的覆盖率报告如下。
1925083221-597d46375eba4_articlex

Stmts: Statement 的缩写,语句覆盖,通常指某一行代码是否被测试覆盖了,不包括注释,条件等。
Branch: 分支覆盖或条件覆盖,指某一个条件语句是否被测试覆盖了,如:ifwhile;分支数是条件语句的两倍。
Funcs: Function 的缩写,函数覆盖,指这个函数是否被测试代码调用了。
Lines: 行覆盖,通常情况等于语句覆盖。一行未必只有一条语句(官方给的差异解释):https://github.com/gotwarlost…

这里有一篇关于这几个指标的具体解释和演示说明,和对做覆盖率报告的思考:http://www.infoq.com/cn/artic…

如果想看具体报告的信息,可以输出成 html 文档来瞧瞧,如下添加输出报告命令。

运行 npm run reportcoverage 目录就会生成一些相关文件,浏览器打开 index.html,就可以看到如下内容。
4244219707-597d54191eecc_articlex

点击文件进去,可以查看该文件测试覆盖的详情。

Coveralls

一个将项目覆盖率展示到网页上,适合开源项目。
网址:https://coveralls.io

先注册登录,然后在项目根目录添加 .coveralls.yml,内容如下。

添加上传命令。

运行 npm run coverage,等待报告上传完毕,就可以在网站上看到报告。

持续集成:CircleCI

通俗的讲,持续集成就是每次提交代码,自动化程序就自动构建(包括编译,发布,自动化测试等)来验证代码,从而尽早地发现代码中的错误。
网址:https://circleci.com/,适合开源项目。

在项目根目录添加 circle.yml 文件,内容如下,配置项都可以在文档中找到。

使用 GitHub 账号登录 CircleCI 网站,选择持续集成这个项目,这里我们用的是 1.0 平台,不要选 2.0,因为配置的写法不一样。
至此,每次提交代码到这个项目,CircleCI 就会自动帮我们集成。
3877398443-597d8f7ebd6e9_articlex

完成了覆盖率和持续集成,这两个网站都提供了小徽章给我们,类似如下,可以贴到项目中以显某种态度。
3063873866-597d8d8a254ed_articlex

学习借鉴,一些使用 AVA 做测试的开源项目

e2e测试框架推荐:TestCafe

官网地址:https://devexpress.github.io/…

推荐理由(缺点须躬行):

  1. 无需配置繁琐的环境。
  2. 基于 NodeJS 生态。

参考

http://i5ting.github.io/ava-p…
https://github.com/avajs/ava

最后

文中的代码托放于 GitHub,可供参考。

承接各种网站开发与修改、爬虫、数据采集分析、小程序等任务

Html+Css+JS+PHP+Nodejs+Python

专治网站各种不服

一起探讨,互相学习,共同进步!有事儿您说话。

This entry was posted in NodeJS and tagged , by 织梦先生. Bookmark the permalink.