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