為什么需要前端自動化測試呢?
點擊上方 前端Q,關(guān)注公眾號
回復(fù)加群,加入前端Q技術(shù)交流群
本文為讀者投稿,感謝時光大佬。
原文為:https://www.wolai.com/4RCFtUJ1gqnP5eTNCkxCkB
我們先來回顧幾個公知問題

自動化測試就是面向這些問題而生的。
接下來我們進入正題,向大家介紹前端自動化測試
前端自動化測試的種類
共四類:
-
單元測試 單元測試是最基礎(chǔ)的自動化測試,用來檢測項目當(dāng)中的最小可測單元,例如工具函數(shù)、基礎(chǔ)組件等
-
集成測試 在單元測試的基礎(chǔ)上,不同功能集成在一起,驗證整體功能
-
ui測試 并不是只對ui設(shè)計效果的驗證,而是只對數(shù)據(jù)渲染、交互上的驗證
-
端對端測試 相對真實、完整鏈路的模擬真實操作驗證
在vue或react這種前端框架下,延伸出一種組件測試,根據(jù)組件的粒度,其實應(yīng)該屬于單元測試、或者集成測試的部分。
自動化測試金字塔
介紹完自動化測試的種類,我們來簡單比較一下這四種測試

有下之上,測試用例的數(shù)量逐步減少、粒度變粗、驗證的功能變多變復(fù)雜。
同時受需求變化的影響變大,重復(fù)利率降低
同時編寫測試用例的時間變長 、執(zhí)行的時間也響應(yīng)變長
另一方面,由上至下,發(fā)先的bug數(shù)量逐漸變小。
所以,從發(fā)先bug數(shù)量/編寫測試用例時間&重復(fù)利用率的緯度上講,單元測試的收益最大,越向上收益越小。
這也是大部分項目中采用的自動化測試,是在單元測試這一層的原因。
滿足自動化測試的條件
說了那么多,哪什么情況下,我們適合使用前端自動化測試呢?
這里我總結(jié)了一些情況,實際上只需要滿足幾點就可以了
-
任務(wù)測試明確,不會頻繁變動
-
每日構(gòu)建后的測試驗證
-
比較頻繁的回歸測試
-
軟件系統(tǒng)界面穩(wěn)定,變動少
-
多平臺上測試、組合遍歷型的測試、大量的重復(fù)任務(wù)
-
軟件維護周期長
-
項目進度壓力不太大
-
開發(fā)比較規(guī)范,具有可測試性
-
具備大量的自動化測試平臺
-
測試人員具備較強的編程能力
一些常見的測試工具
-
單元測試(Unit Test)有 Jest, Mocha
-
UI測試Test Render, Enzyme,
-
端到端(E2E Test)Cypress.io、Nightwatch.js、Puppeteer、TestCafe
說了這么多,其實應(yīng)用的最廣泛的,收益相對來講最高的還是單元測試
所以后面我將具體給大家講一下,如何將單元測試融入到我們的開發(fā)當(dāng)中
如何編寫單元測試
我們是先開發(fā),后補充單元測試呢?還是先編寫單元測試再開發(fā)呢?
相信大多數(shù)第一次,接觸這個問題的人可能都想我一樣,覺得是先開發(fā)后補充
但是實際上應(yīng)當(dāng)是先編寫單元測試,在開發(fā)代碼。這種模式成為測試驅(qū)動開發(fā)(TDD)

很簡單的道理,如果你寫的代碼邏輯有問題,那么按照錯誤邏輯寫的單元測試,永遠(yuǎn)不可能驗證出問題來。
我們應(yīng)當(dāng)圍繞功能設(shè)計來編寫我們的單元測試,測試內(nèi)容對我們來講就是一個黑盒,我們只需要驗證他是否滿足我們的設(shè)計預(yù)期就好了,而無關(guān)內(nèi)部細(xì)節(jié)。只有這樣,才能保證測試用例的穩(wěn)定,支撐重構(gòu)
測試驅(qū)動開發(fā)流程
-
快速新增一個測試
-
運行新增測試,發(fā)現(xiàn)新增的測試不能通過
-
分節(jié)點開發(fā),一邊開發(fā)一邊驗證,擴大測試通過范圍運行
-
所有的測試,并且全部通過
-
重構(gòu)代碼,以消除重復(fù)設(shè)計,優(yōu)化設(shè)計結(jié)構(gòu)
-
再次驗證,通過完成開發(fā)
單元測試步驟
-
準(zhǔn)備(Arrange) 為測試做好設(shè)置。渲染組件/執(zhí)行條件/準(zhǔn)備數(shù)據(jù)
-
行動(Act)
對系統(tǒng)執(zhí)行操作,例如點擊按鈕、觸發(fā)鉤子函數(shù) -
斷言(Assert)
確保真實的結(jié)果匹配你的期望
單元測試開發(fā)案例
假設(shè)現(xiàn)在我們要開發(fā)一個按鈕,
我們先來設(shè)計這個按鈕的功能
首先能接收自定義文字,能夠接收size設(shè)置不同尺寸,能夠觸發(fā)事件,然后還有禁用功能
接下來我們開始寫單元測試
// tests/button.spec.js
import Button from '@/components/Button.vue'
import { mount } from "@vue/test-utils"
const BUTTON_TEXT = '點擊'
describe('Button.vue', () => {
it('render text', () => {
const wrapper = mount(Button, {
slots: {
default: BUTTON_TEXT,
},
})
expect(wrapper.text()).toBe(BUTTON_TEXT)
})
it('size', () => {
const wrapper = mount(Button, {
propsData: {
size: 'small'
}
})
expect(wrapper.classes()).toContain('btn-small')
})
test('handle click', async () => {
const wrapper = mount(Button, {
slots: {
default: BUTTON_TEXT,
},
})
await wrapper.trigger('click')
expect(wrapper.emitted().click).toBeDefined()
})
test('handle disabled click', async () => {
const wrapper = mount(Button, {
slots: {
default: BUTTON_TEXT,
},
propsData: {
disabled: true
}
})
expect(wrapper.classes()).toContain('is-disabled')
await wrapper.trigger('click')
expect(wrapper.emitted().click).toBeUndefined()
})
})
完成組件功能
<template>
<button
:class="[
'el-button',
size ? 'btn-' + size : '',
{
'is-disabled': disabled,
}
]"
@click="handleClick">
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
<script>
export default {
props:{
size:{
type:String,
required:false
},
disabled:{
type:Boolean,
default:false,
required:false
},
},
methods:{
handleClick(evt) {
!this.disabled && this.$emit('click', evt)
}
}
}
</script>
<style>
//省略樣式
</style>
總結(jié)
在開發(fā)中引入前端自動化測試,可以幫我們帶來很多好處。但是同時不能忽視的一個問題,就是成本、無論是編寫自動測試的時間成本,平臺的搭建成本,項目成員學(xué)習(xí)自動化測試的成本。要考慮驗證的的內(nèi)容是否有價值需要自動化測試,我們費勁心血寫的自動化測試是否足夠穩(wěn)健,不會頻繁變更。
總之只有合適的才是最好的。
往期推薦
最后
歡迎加我微信,拉你進技術(shù)群,長期交流學(xué)習(xí)...
歡迎關(guān)注「前端Q」,認(rèn)真學(xué)前端,做個專業(yè)的技術(shù)人...
