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 工程,一个模块的主要功能是获取该目录下的所有文件。开发代码如下

// 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 终端效率神技

上面开发代码的测试代码如下:

// 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)
        })
    })
})
// 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"
  }
}

运行结果

测试结果

Mocha

本文主要想说明的是 UT 的重要性,以及 Node 测如何做单元测试。当然 UT 没这么简单,具体深入的不是本文的终点,感兴趣的可以查看 Mocha 这个项目的官方文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值