日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

jest java_✅使用jest进行测试驱动开发

發(fā)布時(shí)間:2024/1/23 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jest java_✅使用jest进行测试驱动开发 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

本文將使用jest進(jìn)行測(cè)試驅(qū)動(dòng)開(kāi)發(fā)的示例,源碼在github。重點(diǎn)說(shuō)明在開(kāi)發(fā)中引入單元測(cè)試后開(kāi)發(fā)過(guò)程,以及測(cè)試先行的開(kāi)發(fā)思路。

本文的重點(diǎn)是過(guò)程以及思維方法,框架以及用法不是重點(diǎn)。

本文使用的編程語(yǔ)言是javascript,思路對(duì)其他語(yǔ)言也是適用的。

本文主要以函數(shù)作為測(cè)試對(duì)象。

環(huán)境搭建

假設(shè)項(xiàng)目結(jié)構(gòu)為

.

├── README.md

├── package.json

├── src

├── test

└── yarn.lock安裝依賴

yarn add --dev jest打開(kāi)package.json, 修改scripts字段

"scripts": {

"test": "jest"

}

之后把測(cè)試文件放在test文件夾下,使用yarn test 即可查看測(cè)試結(jié)果

開(kāi)發(fā)

現(xiàn)在要開(kāi)發(fā)一個(gè)函數(shù),根據(jù)傳入的文件名判斷是否為shell文件。

先做好約定:shell文件應(yīng)該以 .sh 結(jié)尾

shell文件不以 . 開(kāi)頭

函數(shù)為名 isShellFile

下面來(lái)看下開(kāi)發(fā)步驟是怎么樣的。

文件初始化

在src目錄下新建 isShellFile.js

touch isShellFile.js

然后一行代碼也不寫(xiě),在test目錄下新建 isShellFile.test.js

可以注意到,測(cè)試文件的名與源文件名類似,只是中間多了個(gè) .test

touch isShellFile.test.js

第一個(gè)用例

打開(kāi)測(cè)試文件 test/isShellFile.test.js ,編寫(xiě)第一個(gè)用例,也是最普通的一個(gè): bash.sh

const isShellFile = require('../src/isShellFile')

test('isShellFile', () => {

// 調(diào)用函數(shù),期望它返回值為 true expect(isShellFile('bash.sh')).toBeTruthy()

})

運(yùn)行 yarn test , 結(jié)果如下:

FAIL test/isShellFile.test.js

? isShellFile (2ms)

● isShellFile

TypeError: isShellFile is not a function

^^^

3 | test('isShellFile', () => {

4 |

> 5 | expect(isShellFile('bash.sh')).toBeTruthy()

| ^

6 | })

失敗是意料之中的,因?yàn)?src/isShellFile.js 一行代碼也沒(méi)寫(xiě),所以測(cè)試代碼中第5行 isShellFile 無(wú)法進(jìn)行函數(shù)調(diào)用。

完善源文件src/isShellFile.js

module.exports = function(filename) {

}

這樣 isShellFile 就可以作為函數(shù)被調(diào)用了。

再運(yùn)行 yarn test

FAIL test/isShellFile.test.js

? isShellFile (7ms)

● isShellFile

expect(received).toBeTruthy()

^^^

Received: undefined

3 | test('isShellFile', () => {

4 |

> 5 | expect(isShellFile('bash.sh')).toBeTruthy()

| ^

6 | })

又報(bào)錯(cuò)了,但這次報(bào)錯(cuò)原因跟上次不同,說(shuō)明有進(jìn)步。

這次報(bào)錯(cuò)原因是,期望函數(shù)調(diào)用返回值為真 , 但實(shí)際沒(méi)有返回真 。

這是當(dāng)然的,因?yàn)樵谠次募?#xff0c;根本沒(méi)有寫(xiě)返回語(yǔ)句。

為了讓測(cè)試通過(guò),修改 src/isShellFile.js

module.exports = function(filename) {

+ return true

}

運(yùn)行 yarn test , 測(cè)試通過(guò)了!

PASS test/isShellFile.test.js

? isShellFile (3ms)

Test Suites: 1 passed, 1 total

Tests: 1 passed, 1 total

Snapshots: 0 total

Time: 1.548s

Ran all test suites.

把上述修改,提交到版本控制系統(tǒng)中。

git add package.json yarn.lock src test

git commit -m 'feat: init jest test case'

第二個(gè)用例

觀察我們的測(cè)試用例,發(fā)現(xiàn)太簡(jiǎn)單了,只有正面的用例,沒(méi)有反面的、異常的用例

test('isShellFile', () => {

expect(isShellFile('bash.sh')).toBeTruthy()

})

在 test/isShellFile.test.js 添加一個(gè)反面的用例

test('isShellFile', () => {

expect(isShellFile('bash.sh')).toBeTruthy()

+ expect(isShellFile('bash.txt')).toBeFalsy()

})

運(yùn)行 yarn test

(可以發(fā)現(xiàn),在開(kāi)發(fā)過(guò)程中需要反復(fù)執(zhí)行上述命令,有個(gè)偷懶的辦法,執(zhí)行yarn test --watch,即可監(jiān)聽(tīng)文件變化,自動(dòng)執(zhí)行測(cè)試用例)

FAIL test/isShellFile.test.js

? isShellFile (6ms)

● isShellFile

expect(received).toBeFalsy()

^^^

Received: true

4 |

5 | expect(isShellFile('bash.sh')).toBeTruthy()

> 6 | expect(isShellFile('bash.txt')).toBeFalsy()

| ^

7 | })

報(bào)錯(cuò)了,期望返回假,但函數(shù)返回的是真。這是因?yàn)?#xff0c;源文件中, isShellFile 函數(shù)永遠(yuǎn)返回真!

完善 src/isShellFile.js 邏輯

module.exports = function(filename) {

- return true;

+ return filename.indexOf('.sh') > -1

};

測(cè)試通過(guò)了

PASS test/isShellFile.test.js

? isShellFile (4ms)

Test Suites: 1 passed, 1 total

Tests: 1 passed, 1 total

Snapshots: 0 total

Time: 1.568s

Ran all test suites.

把上述修改提交到版本控制系統(tǒng)

git commit -am 'fix: 函數(shù)永遠(yuǎn)返回真的bug'

第三個(gè)用例

我們?cè)偬砑右粋€(gè)用例,這次考慮特殊情況: .sh 這種文件,不算是shell文件。

修改 test/isShellFile.test.js

expect(isShellFile("bash.sh")).toBeTruthy();

expect(isShellFile("bash.txt")).toBeFalsy();

+ expect(isShellFile('.sh')).toBeFalsy()

測(cè)試不通過(guò)

FAIL test/isShellFile.test.js

? isShellFile (8ms)

● isShellFile

expect(received).toBeFalsy()

^^^

Received: true

5 | expect(isShellFile("bash.sh")).toBeTruthy();

6 | expect(isShellFile("bash.txt")).toBeFalsy();

> 7 | expect(isShellFile('.sh')).toBeFalsy()

| ^

8 | });

說(shuō)明邏輯待完善,修改 src/isShellFile.js

module.exports = function(filename) {

- return filename.indexOf(".sh") > -1;

+ let index = filename.indexOf(".sh");

+ return index > -1 && index != 0;

};

測(cè)試通過(guò)(為精簡(jiǎn)文章內(nèi)容,后面不再展示測(cè)試通過(guò)的輸出),提交代碼。

git commit -am 'fix: .sh應(yīng)該返回false'

第四個(gè)用例

按照第三個(gè)用例的邏輯, .bash.sh 也不應(yīng)該是shell文件,那么函數(shù)是否能正確判斷呢,測(cè)試便知。

修改 test/isShellFile.test.js

expect(isShellFile('.sh')).toBeFalsy()

+ expect(isShellFile('.bash.sh')).toBeFalsy()

測(cè)試不通過(guò)

FAIL test/isShellFile.test.js

? isShellFile (3ms)

● isShellFile

expect(received).toBeFalsy()

^^^

Received: true

6 | expect(isShellFile("bash.txt")).toBeFalsy();

7 | expect(isShellFile('.sh')).toBeFalsy()

> 8 | expect(isShellFile('.bash.sh')).toBeFalsy()

| ^

9 | });

說(shuō)明邏輯待完善,修改 src/isShellFile.js

module.exports = function(filename) {

let index = filename.indexOf(".sh");

- return index > -1 && index != 0;

+ return !filename.startsWith('.') && index > -1;

};

測(cè)試通過(guò),提交代碼。

git commit -am 'fix: .開(kāi)頭的文件不算sh文件'

第五個(gè)用例

再考慮一種情況,如果 .sh 出現(xiàn)在中間呢?如 bash.sh.txt , 它不應(yīng)該是shell文件,來(lái)看看函數(shù)是否能通過(guò)測(cè)試。

修改 test/isShellFile.test.js

expect(isShellFile('.bash.sh')).toBeFalsy()

+ expect(isShellFile('bash.sh.txt')).toBeFalsy()

測(cè)試不通過(guò)

FAIL test/isShellFile.test.js

? isShellFile (5ms)

● isShellFile

expect(received).toBeFalsy()

^^^

Received: true

7 | expect(isShellFile('.sh')).toBeFalsy()

8 | expect(isShellFile('.bash.sh')).toBeFalsy()

> 9 | expect(isShellFile('bash.sh.txt')).toBeFalsy()

| ^

10 | });

說(shuō)明邏輯待完善,修改 src/isShellFile.js

module.exports = function(filename) {

- let index = filename.indexOf(".sh");

- return !filename.startsWith('.') && index > -1;

+ let index = filename.lastIndexOf(".");

+ return !filename.startsWith('.') && filename.substr(index) == '.sh';

};

測(cè)試通過(guò),提交代碼。

git commit -am 'fix: .sh必須在結(jié)尾'

重構(gòu)

我們來(lái)觀察目前 src/isShellFile.js 的函數(shù)邏輯

module.exports = function(filename) {

let index = filename.lastIndexOf(".");

return !filename.startsWith('.') && filename.substr(index) == '.sh';

};

對(duì)于 .bashrc 這樣的文件,并不是shell文件,因?yàn)樗且?. 開(kāi)頭的。

則通過(guò) filename.startsWith('.') 判斷即可,前面的函數(shù)調(diào)用 filename.lastIndexOf(".") 是多余的。也即,目前的函數(shù)判斷邏輯不夠簡(jiǎn)明。

下面是一種優(yōu)化思路:

module.exports = function(filename) {

return !filename.startsWith('.') && filename.substr(filename.lastIndexOf(".")) == '.sh';

};

測(cè)試通過(guò),提交代碼

git commit -am 'refactor: 優(yōu)化邏輯'

注意,這個(gè)重構(gòu)示例的重點(diǎn)是:先完成功能,再重構(gòu)

重構(gòu)必須要有測(cè)試用例,且確保重構(gòu)后全部測(cè)試用例通過(guò)

至于其他方面,見(jiàn)仁見(jiàn)智,并不是重點(diǎn)。

結(jié)論

本文通過(guò)代碼實(shí)例,踐行了測(cè)試先行的理念。

文中的代碼實(shí)現(xiàn)不是重點(diǎn),而是開(kāi)發(fā)過(guò)程。

文中 文件初始化 及 第一個(gè)用例 的內(nèi)容,尤其值得回味,它體現(xiàn)了兩個(gè)思路:總是在有一個(gè)失敗的單元測(cè)試后才開(kāi)始編碼

用必要的最小代碼讓測(cè)試通過(guò)

總的來(lái)看,TDD總是處于一個(gè)循環(huán)中:編寫(xiě)用例

測(cè)試失敗

編寫(xiě)代碼

測(cè)試成功

提交代碼

重復(fù)以上

通過(guò)這樣,功能的實(shí)現(xiàn)每次都是最小成本的,功能也是有步驟地、通過(guò)迭代完成的,而不是一步登天。

更關(guān)鍵的是,完善的測(cè)試用例,是開(kāi)發(fā)者的“守護(hù)天使”,有了它們,以后在添加新功能時(shí),修改/重構(gòu)代碼都有了可靠的保障,讓開(kāi)發(fā)者可以充滿信心,code with confidence !

擴(kuò)展

使用babel

要想使用import/export語(yǔ)法,需要安裝babel相關(guān)依賴安裝依賴

yarn add --dev babel-jest @babel/core @babel/preset-env在項(xiàng)目根路徑新增配置文件 babel.config.js

module.exports = {

presets: [

[

'@babel/preset-env',

{

targets: {

node: 'current',

},

},

],

],

};重新啟動(dòng)測(cè)試

yarn test --watch

為什么使用jest

因?yàn)檫@是vue官方工具鏈的一部分, 同時(shí)也可以為后續(xù)的組件測(cè)試作準(zhǔn)備。

總結(jié)

以上是生活随笔為你收集整理的jest java_✅使用jest进行测试驱动开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。