前端自動化測試:測試到底測什么?
對于稍微有一些開發(fā)經(jīng)驗的同學(xué)在開發(fā)過程中總會經(jīng)歷下面類似的問題:
每次在版本發(fā)布上線之前,在電腦前蹲上好幾個小時甚至是更長時間對你的應(yīng)用進行測試,這個過程非常枯燥而痛苦。
當(dāng)代碼的復(fù)雜度達到了一定的級別,當(dāng)維護者的數(shù)量不止你一個,你應(yīng)該會逐漸察覺到你在開發(fā)新功能或修復(fù) bug 的時候,會變得越發(fā)小心翼翼,即使代碼看起來沒什么問題,但你心里還是會犯嘀咕:這個 Feature 會不會帶來其他 Bug ?這個 Fix 會不會引入其他"Feature" ?
當(dāng)你想要對項目中的代碼進行重構(gòu)的時候,你會花費大量的時間進行回歸測試。
以上這些問題都是由于大多數(shù)開發(fā)者所使用最基本的手動測試的方式所帶來的問題,解決它的根本舉措就是引入自動化測試方案。
測試的流程
在實際開發(fā)過程中,編寫自動化測試代碼通常是開發(fā)人員不太喜歡的一個環(huán)節(jié)。大多數(shù)情況下,前端開發(fā)人員在開發(fā)完一項功能后,只是打開瀏覽器手動點擊,查看效果是否正確,之后就很少對該塊代碼進行管理。
造成這種情況的原因主要有兩個:
一個是業(yè)務(wù)繁忙,沒有時間進行測試的編寫。
另一個是不知道如何編寫測試。
但這些問題不應(yīng)該作為我們掌握前端自動化測試的絆腳石。而且,一旦掌握了前端自動化測試方案,無論是對大型項目的開發(fā),還是升職加薪,都是有益的。
提到測試的時候,即使是最簡單的一個代碼塊可能都讓初學(xué)者不知所措。最常問的問題的是“我怎么知道要測試什么?”。如果你正在寫一個 Web 應(yīng)用,那么你每個頁面每個頁面的測試用戶交互的方式,就是一個很好的開端了。但 Web 應(yīng)用也是由很多個函數(shù)和模塊組成的代碼單元,也是需要測試的。通常有兩種情況:
你接手的遺留代碼沒有寫測試用例
你必須從無到有的實現(xiàn)一個新功能
該怎么辦呢?對于上面兩種場景,你可以把測試視為代碼的一部分來編寫。我所說的這些代碼,是用來檢查給定的函數(shù)是否產(chǎn)生預(yù)期輸出結(jié)果的。一個典型的測試流程如下:
1. 引入要測試的函數(shù)
2. 給函數(shù)一個輸入
3. 定義預(yù)期輸出
4. 檢查函數(shù)是否返回了預(yù)期的輸出結(jié)果
就這么多。這樣看測試也沒那么可怕的嘛:輸入 —— 預(yù)期輸出 —— 驗證結(jié)果。
一個測試案例
下面來看一個例子:
// math.jsfunctionadd (a, b) {return a + b}functionsubtract (x, y) {return x - y}module.exports= {add,subtract}
如何保證上面代碼的正確性?
下面來寫一段測試代碼:
// test.jsconst { add, subtract } =require('./math')const result =add(1,2)const expected =3if (result !== expected) {thrownewError(`1 + 2 應(yīng)該等于${expected},但是結(jié)果卻是${result}`)}const result2 =subtract(2,1)const expected2 =1if (result2 !== expected2) {thrownewError(`2 - 1 應(yīng)該等于${expected2},但是結(jié)果卻是${result2}`)}
命令行執(zhí)行 node test.js 后,會看到錯誤信息:
Error: 1 + 2 應(yīng)該等于 3,但是結(jié)果卻是 2通過測試代碼可以很方便的幫助驗證代碼的正確性。
封裝測試工具函數(shù)
之前示例的測試代碼太過繁瑣,可以思考一下能否封裝的更簡便一些,比如下面這樣:
expect(add(1,2)).toBe(3)expect(subtract(2,1)).toBe(-1)
上面的測試代碼就像自然語言說話一樣,很舒服。
實現(xiàn) expect 方法:
// test.jsconst { add, subtract } =require('./math')expect(add(1,2)).toBe(3)expect(subtract(2,1)).toBe(1)functionexpect (result) {return {toBe (actual) {if (result !== actual) {thrownewError(`預(yù)期值和實際值不相等,預(yù)期結(jié)果: ${actual},實際結(jié)果: ${result}`)}}}}
增加錯誤提示信息:
// test.jsconst { add, subtract } =require('./math')test('測試加法', () => {expect(add(1,2)).toBe(3)})test('測試減法', () => {expect(subtract(2,1)).toBe(1)})functiontest (description, callback) {try {callback()console.log(`${description}通過測試`)} catch (err) {console.error(`${description}沒有通過測試:${err}`)}}functionexpect (result) {return {toBe (actual) {if (result !== actual) {thrownewError(`預(yù)期值和實際值不相等,預(yù)期結(jié)果: ${actual},實際結(jié)果: ${result}`)}}}}
推薦閱讀:
前端工程化中的重要環(huán)節(jié)——自動化構(gòu)建
更新不易,點個“在看”和“贊”吧(●'?'●)!
