自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

卓越工程實(shí)踐之—前端高質(zhì)量單測(cè)

原創(chuàng) 精選
數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
在我們的項(xiàng)目中,用issue來(lái)管理用戶需求。用戶每發(fā)現(xiàn)一個(gè)問(wèn)題都可以到我們指定倉(cāng)庫(kù)中去提issue,新增的issue觸發(fā)機(jī)器人在釘釘群里艾特對(duì)應(yīng)修改人,修復(fù)后機(jī)器人通知?jiǎng)?chuàng)建人。

作者 | 范喆(六瓶)

高單測(cè)等于高質(zhì)量?

筆者負(fù)責(zé)的npm包是 ICBU信天翁低代碼平臺(tái)渲染引擎,160+應(yīng)用 600+頁(yè)面基于該引擎開(kāi)發(fā),內(nèi)網(wǎng)日npm下載 1K+。經(jīng)過(guò)不懈努力(CV),終于把單測(cè)提到了95%。

然而,雖然在覆蓋率上獲得了一些數(shù)據(jù)的改變,但作為開(kāi)發(fā)者,想要的并不是數(shù)據(jù)上的完美,而是它真的完美(沒(méi)BUG)。作為一個(gè)高頻引用的底層庫(kù),改動(dòng)一行代碼都可以影響到用戶意想不到的bug。

高單測(cè)覆蓋率不能避免改動(dòng)引發(fā),小的改動(dòng)引發(fā)就可能帶來(lái)大的線上問(wèn)題。

寫(xiě)好單測(cè)

issue=單測(cè)

每一個(gè)issue都有它命中注定的一個(gè)單測(cè)。

在我們的項(xiàng)目中,用issue來(lái)管理用戶需求。用戶每發(fā)現(xiàn)一個(gè)問(wèn)題都可以到我們指定倉(cāng)庫(kù)中去提issue,新增的issue觸發(fā)機(jī)器人在釘釘群里艾特對(duì)應(yīng)修改人,修復(fù)后機(jī)器人通知?jiǎng)?chuàng)建人。

圖片

在軟件工程中,對(duì)單元測(cè)試的描述是“針對(duì)每一個(gè)單元的測(cè)試,以確保每個(gè)模塊能正常工作為目標(biāo)”。在我們行覆蓋率和分支覆蓋率都很高的情況下,還需要有新的機(jī)制保證模塊更穩(wěn)定。除去那些框架還沒(méi)探索到的業(yè)務(wù)場(chǎng)景,怎么樣保證現(xiàn)在用戶的一定沒(méi)有問(wèn)題?于是有了issue即單測(cè)。在現(xiàn)在的issue運(yùn)作機(jī)制下,保證每一個(gè)單側(cè)都有對(duì)應(yīng)的issue。在倉(cāng)庫(kù)中新增了腳本tnpm run create-issue。


// package.json
"scripts": {
"create-issue": "node ./script/issue_dev/createIssueTem.js",
}

// createIssueTem.js
/**
* 快速創(chuàng)建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才能運(yùn)行');
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(`創(chuàng)建${issueID}成功`);

在發(fā)布前把對(duì)應(yīng)的demo做刪除。


// prebuild
// 構(gòu)建前刪除issue的demo
const 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}`);
}
});
});

當(dāng)我們運(yùn)行tnpm run create-issue 123456,幫我們創(chuàng)建對(duì)應(yīng)issue 123456的單測(cè)+demo,復(fù)用同一個(gè)template內(nèi)容,可以在瀏覽器端看到demo,也可以在vs code中直接編寫(xiě)單測(cè)內(nèi)容。

圖片

在demo中,可以直接點(diǎn)擊gitlab鏈接跳轉(zhuǎn)到對(duì)應(yīng)issue。

圖片

這里拿一個(gè)簡(jiǎn)單的issue做演示:

圖片

對(duì)應(yīng)的原子單測(cè)。


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();
});
});

單測(cè)非常簡(jiǎn)單,雖然只有兩句expect,但這兩句是只為這個(gè)issue存在,強(qiáng)行cp。

issue唯一單測(cè)覆蓋,保證0改動(dòng)引發(fā)。

在業(yè)界一些優(yōu)秀的開(kāi)源框架也是有同樣的issue即單測(cè)的案例,比如mobx。

圖片

單測(cè)=文檔

原子類單測(cè)可以極大程度保證代碼穩(wěn)定性,組件類可以描述開(kāi)發(fā)者期望的用法。單測(cè)即文檔。

圖片

閉環(huán)沉淀反哺

除此之外,issue的Milestone代表對(duì)應(yīng)npm版本:


// changelog
# 1.24.0
1. 【FEAT】列表過(guò)濾提供類似表單的校驗(yàn)?zāi)J?#115827(cover by test)
2. 【FEAT】model內(nèi)置屬性應(yīng)該不可枚舉 #116193(cover by test)
3. 【FEAT】期望提供ref注解,方便平臺(tái)側(cè)做區(qū)分 #116364
4. 【Bug】watch 在正則的模式下,調(diào)用 silent validate 會(huì)導(dǎo)致 autoValidate 失效 #116242(cover by test)

issue的最好歸宿就是cover by test。釘釘 -> issue -> npm changelog 相互對(duì)應(yīng),做到每個(gè)單測(cè)可溯源。

圖片

筆者負(fù)責(zé)的框架已經(jīng)推行了一年,再回顧一下。值得思考的是,重頭設(shè)計(jì)一次架構(gòu),是否能完美的解決現(xiàn)在的這些issue。

這些issue和單測(cè)都是走過(guò)的腳印,現(xiàn)在我們已經(jīng)積累單測(cè)170+, 其中60+ issue原子類單測(cè)。不能保證0BUG。但可預(yù)見(jiàn)的是讓用戶放心用,不會(huì)有改動(dòng)引發(fā)。單測(cè)是質(zhì)量的守門神,幫助框架做好用戶預(yù)期,一步步更穩(wěn)健的前行。

最后

寫(xiě)單測(cè)最好的時(shí)間是項(xiàng)目開(kāi)始前,其次是現(xiàn)在。

責(zé)任編輯:武曉燕 來(lái)源: 阿里開(kāi)發(fā)者
相關(guān)推薦

2023-07-06 14:51:30

開(kāi)發(fā)高質(zhì)量軟件

2022-12-02 10:38:50

機(jī)器學(xué)習(xí)開(kāi)發(fā)工程項(xiàng)目

2011-05-31 13:43:46

外鏈

2017-07-14 09:54:47

代碼函數(shù)程序

2021-08-08 14:26:24

SQL數(shù)據(jù)庫(kù)開(kāi)發(fā)

2023-03-09 15:05:46

HTMLWeb 開(kāi)發(fā)SEO

2023-12-08 07:59:41

對(duì)象設(shè)計(jì)設(shè)計(jì)模式軟件設(shè)計(jì)

2012-09-13 10:44:18

Python代碼

2011-03-04 10:11:09

JavascriptAPI

2011-07-20 15:26:52

C++

2015-08-19 08:54:23

Android開(kāi)發(fā)框架

2023-10-15 12:07:09

2020-03-02 09:26:16

JavaScript程序員JSON

2013-12-03 09:34:26

iOS應(yīng)用開(kāi)發(fā)實(shí)踐高質(zhì)量Objectiv

2020-04-02 15:45:24

JavaScript開(kāi)發(fā) 模塊

2011-06-24 14:59:41

外鏈

2022-12-23 19:22:47

前端單測(cè)

2015-08-25 08:29:11

編寫(xiě)高質(zhì)量命名
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)