卓越工程实践之—前端高质量单测

2022 年 7 月 6 日 阿里技术


高单测等于高质量?


笔者负责的npm包是 ICBU信天翁低代码平台渲染引擎,160+应用 600+页面基于该引擎开发,内网日npm下载 1K+。经过不懈努力(CV),终于把单测提到了95%。

然而,虽然在覆盖率上获得了一些数据的改变,但作为开发者,想要的并不是数据上的完美,而是它真的完美(没BUG)。作为一个高频引用的底层库,改动一行代码都可以影响到用户意想不到的bug。

高单测覆盖率不能避免改动引发,小的改动引发就可能带来大的线上问题。

写好单测

issue=单测

每一个issue都有它命中注定的一个单测
在我们的项目中,用issue来管理用户需求。用户每发现一个问题都可以到我们指定仓库中去提issue,新增的issue触发机器人在钉钉群里艾特对应修改人,修复后机器人通知创建人。

在软件工程中,对单元测试的描述是“针对每一个单元的测试,以确保每个模块能正常工作为目标”。
在我们行覆盖率和分支覆盖率都很高的情况下,还需要有新的机制保证模块更稳定。除去那些框架还没探索到的业务场景,怎么样保证现在用户的一定没有问题?
于是有了issue即单测。
在现在的issue运作机制下,保证每一个单侧都有对应的issue。在仓库中新增了脚本 tnpm run create-issue
// package.json"scripts": {    "create-issue": "node ./script/issue_dev/createIssueTem.js",}
// createIssueTem.js/** * 快速创建issue示例 */const path = require('path');const execSync = require('child_process').execSync;const args = process.argv.slice(2);
const issueID = args[0];
if (!issueID) { console.error('需要输入issue id才能运行'); process.exit();}
const demoTarget = path.resolve(__dirname, `../../demo/issue_${issueID}`);const demoSrc = path.resolve(__dirname, `../template/demo/base.md`);
const testTarget = path.resolve(__dirname, `../../test/issues-cov/${issueID}`);const testSrc = path.resolve(__dirname, `../template/test/*`);const specTarget = path.resolve(__dirname, `../../test/issues-cov/${issueID}/app.spec.tsx`);
execSync(`mkdir ${demoTarget}`);execSync(`cp ${demoSrc} ${demoTarget}/`);execSync(`sed -i '' 's/issueID/${issueID}/g' ${demoTarget}/base.md`);
execSync(`mkdir ${testTarget}`);execSync(`cp ${testSrc} ${testTarget}`);execSync(`sed -i '' 's/issueID/${issueID}/g' ${specTarget}`);
console.log(`创建${issueID}成功`);
在发布前把对应的demo做删除
// prebuild// 构建前删除issue的democonst fs = require('fs');const path = require('path');const ENV = process.env.BUILD_ENV == 'cloud';
function removeDir(dir) { let files = fs.readdirSync(dir); for (var i = 0; i < files.length; i++) { let newPath = path.join(dir, files[i]); let stat = fs.statSync(newPath); if (stat.isDirectory()) { //如果是文件夹就递归下去 removeDir(newPath); } else { //删除文件 fs.unlinkSync(newPath); } } fs.rmdirSync(dir); //如果文件夹是空的,就将自己删除掉}
fs.readdir('./demo', (err, path) => { if (err) { console.log(err); } path.forEach((pathItem) => { if (pathItem.includes('issue') && ENV) { removeDir(`./demo/${pathItem}`); console.log(`删除${pathItem}`); } });});
当我们运行 tnpm run create-issue 123456 ,帮我们创建对应issue 123456的单测+demo,复用同一个 template 内容,可以在浏览器端看到demo,也可以在vs code中直接编写单测内容。


在demo中,可以直接点击gitlab链接跳转到对应issue。

这里拿一个简单的issue做演示:


对应的原子单测
describe('116193', () => {  it('should work', async () => {    const wrapper = mount(<App />);    await sleep(10);    wrapper.mount();    expect(Object.keys(A)).toMatchSnapshot();    expect(A.hasApplied).toBeDefined();    return wrapper.unmount();  });});

单测非常简单,虽然只有两句expect,但这两句是只为这个issue存在,强行cp。

issue唯一单测覆盖,保证0改动引发。

在业界一些优秀的开源框架也是有同样的issue即单测的案例,比如mobx。


单测=文档

原子类单测可以极大程度保证代码稳定性,组件类可以描述开发者期望的用法。
单测即文档


闭环沉淀反哺


除此之外,issue的Milestone代表对应npm版本:

// changelog# 1.24.01. 【FEAT】列表过滤提供类似表单的校验模式 #115827(cover by test)2. 【FEAT】model内置属性应该不可枚举 #116193(cover by test)3. 【FEAT】期望提供ref注解,方便平台侧做区分 #1163644. 【Bug】watch 在正则的模式下,调用 silent validate 会导致 autoValidate 失效 #116242(cover by test)


issue的最好归宿就是cover by test。钉钉 -> issue -> npm changelog 相互对应,做到每个单测可溯源。


笔者负责的框架已经推行了一年,再回顾一下。值得思考的是,重头设计一次架构,是否能完美的解决现在的这些issue。

这些issue和单测都是走过的脚印,现在我们已经积累单测170+, 其中60+ issue原子类单测。不能保证0BUG。但可预见的是让用户放心用,不会有改动引发。单测是质量的守门神,帮助框架做好用户预期,一步步更稳健的前行。

最后


写单测最好的时间是项目开始前,其次是现在。



“阿里灵杰”问天引擎电商搜索算法大赛



点击阅读原文查看详情。


登录查看更多
0

相关内容

如何用latext画神经网络?这个PlotNeuralNet能帮到你
专知会员服务
25+阅读 · 2022年1月15日
隐私计算应用白皮书, 54页pdf
专知会员服务
173+阅读 · 2021年12月18日
专知会员服务
104+阅读 · 2021年7月18日
专知会员服务
153+阅读 · 2021年3月6日
专知会员服务
38+阅读 · 2020年9月6日
专知会员服务
118+阅读 · 2020年7月22日
代码重构:面向单元测试
阿里技术
0+阅读 · 2022年7月29日
代码覆盖率在性能优化上的一种可行应用
阿里技术
0+阅读 · 2022年5月13日
淘系用户平台技术团队单元测试建设
阿里技术
0+阅读 · 2022年5月12日
前端实现多文件编译器
阿里技术
0+阅读 · 2022年3月28日
JavaScript 中的 7 个“杀手级”单行代码
InfoQ
0+阅读 · 2022年3月17日
谈一谈单元测试
阿里技术
0+阅读 · 2022年2月14日
大规模 Node.js 网关的架构设计与工程实践
面向云原生应用的低代码开发平台构建之路
AI前线
0+阅读 · 2022年1月26日
自己动手写符合自己业务需求的eslint规则
阿里技术
0+阅读 · 2021年12月7日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
4+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
1+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
1+阅读 · 2008年12月31日
Arxiv
0+阅读 · 2022年8月30日
Arxiv
1+阅读 · 2022年8月29日
Arxiv
25+阅读 · 2018年1月24日
VIP会员
相关VIP内容
如何用latext画神经网络?这个PlotNeuralNet能帮到你
专知会员服务
25+阅读 · 2022年1月15日
隐私计算应用白皮书, 54页pdf
专知会员服务
173+阅读 · 2021年12月18日
专知会员服务
104+阅读 · 2021年7月18日
专知会员服务
153+阅读 · 2021年3月6日
专知会员服务
38+阅读 · 2020年9月6日
专知会员服务
118+阅读 · 2020年7月22日
相关资讯
代码重构:面向单元测试
阿里技术
0+阅读 · 2022年7月29日
代码覆盖率在性能优化上的一种可行应用
阿里技术
0+阅读 · 2022年5月13日
淘系用户平台技术团队单元测试建设
阿里技术
0+阅读 · 2022年5月12日
前端实现多文件编译器
阿里技术
0+阅读 · 2022年3月28日
JavaScript 中的 7 个“杀手级”单行代码
InfoQ
0+阅读 · 2022年3月17日
谈一谈单元测试
阿里技术
0+阅读 · 2022年2月14日
大规模 Node.js 网关的架构设计与工程实践
面向云原生应用的低代码开发平台构建之路
AI前线
0+阅读 · 2022年1月26日
自己动手写符合自己业务需求的eslint规则
阿里技术
0+阅读 · 2021年12月7日
相关基金
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
4+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
1+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
1+阅读 · 2008年12月31日
Top
微信扫码咨询专知VIP会员