前言
经过本系列之前的教程我们已经可以跑起来一个集成测试了,如果团队践行了这个实践,那么项目一定是坚不可摧的。但是又引发出了另一个问题,就是如果测试数量庞大,几千几万个case,每次 mr 跑一遍是很耗时的,这时候就需要有人来研究测试慢的原因了,进行 debug,profile 等。找出慢的测试同时也能帮我们定位有问题的代码,下面我来教你们怎么通过测试代码进行性能分析
step 1: 新建 profile.ts
代码如下
import fs from 'fs'
import { Session } from 'inspector'
import path from 'path'
let session: Session
export async function startProfiling() {
session = new Session()
session.connect()
await new Promise((f) => {
session.post('Profiler.enable', () => {
session.post('Profiler.start', f)
})
})
}
export async function stopProfiling(profileName = 'integration-test') {
await new Promise((f) =>
session.post('Profiler.stop', (err, res) => {
if (!err) {
const targetPath = path.join(__dirname, profileName + '.json')
fs.writeFileSync(targetPath, JSON.stringify(res.profile))
}
f(1)
})
)
}
我们使用的 nodejs 的 inspector,这是一个强大的内置调试工具,它可以连接到 chrome devtool 对 nodejs 进行调试。那么就说明他一定有方法导出 profile。于是看了一下类型定义,果然发现了一个接口
那么我们就直接在测试的开始和结束的时候调用一下就行了,然后把记录的内容新建一个文件导出来。
step 2: 模拟一个慢操作
我们找到一个地方加点 hack 的代码,比如在点击收藏按钮的时候创建 3000 个 div
step 3: 在测试中开启记录 profile
在测试代码中添加如下命令
// ...
beforeAll(async () => {
await startProfiling()
})
afterAll(async () => {
await stopProfiling()
})
// ...
然后运行测试npm run test后可以看到新增了一个文件
step 4: 把生成的 profile 给拖到 chrome性能面板中进行查看
点击 自上而下
可以看到最耗时的操作
appendChil暴露出来了,
继续展开看一下
定位到前面写的 mockSlow 了。🎉
结尾
可能有人会问,我明明自己录制调试一下也可以发现,为什么要折腾这么一圈? 这其实就是测试的好处了,因为大部分情况,人们不知道自己的代码有问题,比如 100ms 200ms 的延迟察觉不到,比如本应该是全局单例结果实例数量会随着页面跳转而增加。这些问题通常会被“我这跑起来没问题啊”这种话给忽略掉。但是未来你可能就要被页面卡死或者内存泄露的 bug 折磨一整天。通过观察测试运行的时间变化,内存变化可以及时定位这些问题,除掉隐患。