Files
knowledge-kit/Chapter3 - Server/3.7.md
2020-02-25 17:46:51 +08:00

126 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Node 单元测试
## 为什么做这个事情
我在我写的文章里面多次提到单元测试的重要性。重要的事情说三遍“单测很重要”、“单测很重要”、“单测很重要”。
单纯说这句话没公信力和权威性,那我举例子来说明吧。
场景1
某业务线在不断的版本迭代在版本6的时候发现功能 A 的代码太乱太多了。小刘同学打算重构,他辛辛苦苦解决后,打算提交给测试工程师进行测试。测试工程师说“小刘,你这个代码全是 Bug 呀,我点进去就 Crash”。小刘听到后很尴尬心里想“功能 A 的代码我写的很小心,一行行检查过去的,不可能有问题”。测试说“我点击商品页,点击加入购物车,马上 Crash 了”。你这个测试被打回,阻塞主流程了。小刘想了想才发现他自己开发的模块是没有问题的,但是他在重构功能 A 的时候不小心把依赖功能 A 的地方少传递了配置参数 😅
场景2
某公司基础普通组有小刘同学在设计某个新技术方案的时候辛辛苦苦花了3天时间出了技术方案他去找老板聊老板让他把思路描述下再把设计的测试用例给一下。小刘吞吞吐吐讲完了设计思路但是他说还没有设计测试用例。老板说你没测试用例我怎么 review 你的设计,一行行看代码理解逻辑吗?一句句听你的设计判断有没有问题吗?以后你找我听技术设计,你理好设计思路,和测试用例。我看看主流程和一些边界的输入输出,确保这些东西正确那就是没问题的。我没有那么多时间一行行看代码。(说的也是,组长是 P9 忙得很)
场景3
某公司基础普通组有小刘同学在做了移动端的 APM 监控和数据上报 SDK 的第一版,但是他很乖,写好了单元测试。忘了说了小刘同学是负责 iOS 端的,同事做 Android 端的小张同学和他对应,不同就是他没有写单元测试的代码。 需求下来了需要迭代版本2小刘和小张都开发好代码了需要进行测试。哈哈哈小刘乐坏了他花了0.5天就测试结束小张花了1.5天进行测试。为什么呢?小刘写代码都要写单元测试代码,小张不写。虽然写单元测试代码可能需要花一点点时间。但是当新版本迭代的时候就不需要回头继续**全量测试**。他只要按下 `Command + U`, Xcode 就会跑单元测试相关的代码。
那单元测试的好处?😂 什么?你还问好处,上面那么清晰明了,那我再总结下:
- 确保你写的代码的每个分支都可以被覆盖,防止线上代在用户端,不小心执行到未知的分支里面
- 在进行新版本迭代或者重构的时候,可以集中精力到新逻辑里面,旧的逻辑可以用 UT 测试覆盖率来确保
- 在团队内进行 code review 或者 merge review 的时候review 的人可以看代码中主要逻辑,结合 ut 来判断。
另外,测试来说一般是结合 CI、CD 的,像我们公司有自己的工具 cli 工具, iOS、Android、RN、React、Vue、Node 项目都一起处理分析依赖、打包构建打包系统根据工程特点调度特定打包机、测试、hot fix、埋点统计、APM等等。
所以如果公司规模小,就写好 UT 然后结合 lint 做一些处理,公司规模大、开发有能力则需要结合 ci、cd 将测试的能力结合进去。
另外 UT 是一道工序,最好在每个开发者写代码的时候做 MR团队内 MR +1 数大于3才可以合并到分支且 +1 的人里面必须有一个同一个项目的同学必须有一个同技术栈且比你高水平的人MR 指出的问题修改好才可以合并。且 MR 代码不能太大,因为太大,给你做 MR 的同学会很耗费精力。人家阅读你代码时间成本太大。
## Node 侧如何进行 UT 开发
Node 在大学三年级的时候就听说了也写过之前也用来写过爬虫、自动化脚本、cli 等,之前学习过如何在 Node 侧写 ut这篇文章用来总结下。
举个例子,有个 Node 工程,一个模块的主要功能是获取该目录下的所有文件。开发代码如下
```javascript
// fetchCodeFiles.js
const fs = require('fs-extra'),
glob = require('glob')
const fetchCodeFiles = async (dirPath) => {
return new Promise((reslove, reject) => {
glob('**/*.?(sh|pch|json|xcconfig|mm|cpp|h|m)', { root: dirPath, cwd: dirPath, realpath: true }, (err, files) => {
if (err) reject(err)
reslove(files)
})
});
}
module.exports = fetchCodeFiles
```
单元测试该怎么做?
1. 在终端下切换到当前工程目录,安装 `npm install yamljs --save`
2. 在工程根目录下新建 `test` 文件夹
3. 为你需要的开发文件写测试代码。文件命名建议 `模块名称.test.js`
4. 测试代码需要引入 `assert`
5. 通过 `describe` 方法、 `it` 方法、`assert` 方法描写测试代码
6. 为了方便测试,在 `package.json` 文件中的 `scripts` 下添加描述 `"test": "mocha"`
7. 为了更方便,我使用的是 iterm2在 .zshrc 文件里设置别名 `alias nt="node test"`
提升效率的配置 .zshrc 可以查看文章: [Mac 终端效率神技](./../Chapter7 - Geek Talk/7.10.md)
上面开发代码的测试代码如下:
```javascript
// fetchCodeFiles.test.js
const fetchCodeFiles = require('./../src/fetchCodeFiles'),
assert = require('assert')
describe("fetch all code files", () => {
describe("fetch all code files", () => {
it("should return 12 when code directory is '/Users/liubinpeng/Workspace/search_key/test/code'", (done) => {
done(assert(fetchCodeFiles('/Users/liubinpeng/Workspace/search_key/test/code')) === 12)
})
it("should return 4 when code directory is '/Users/liubinpeng/Workspace/search_key/test/code/Classes'", (done) => {
done(assert(fetchCodeFiles('/Users/liubinpeng/Workspace/search_key/test/code/Classes')) === 4)
})
it("should return 0 when code directory is '/Users/liubinpeng/Workspace/search_key/test/code/EmptyCodeFiles'", (done) => {
done(assert(fetchCodeFiles('/Users/liubinpeng/Workspace/search_key/test/code/EmptyCodeFiles')) === 0)
})
})
})
```
```json
// package.json
{
"name": "search",
"version": "1.0.0",
"description": "des",
"main": "index.js",
"scripts": {
"test": "mocha",
"start": "node src/index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"fs-extra": "^8.1.0",
"glob": "^7.1.6",
"yamljs": "^0.3.0"
},
"devDependencies": {
"mocha": "^6.2.2"
}
}
```
运行结果
![测试结果](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2019-12-16-nodeUT.png)
## Mocha
本文主要想说明的是 UT 的重要性,以及 Node 测如何做单元测试。当然 UT 没这么简单,具体深入的不是本文的终点,感兴趣的可以查看 Mocha 这个项目的[官方文档](https://mochajs.org)。