本文將作為多瀏覽器自動(dòng)化測(cè)試的第一篇文章,給讀者從頭介紹如何進(jìn)行本地多瀏覽的自動(dòng)化測(cè)試工作,包括測(cè)試的原理、測(cè)試框架的選取、測(cè)試工程的搭建和實(shí)現(xiàn)等。另外“從入門(mén)到不放棄”系列將給讀者們帶來(lái)更多從零開(kāi)始的前端實(shí)踐案例,諸如前端組件庫(kù)設(shè)計(jì)與實(shí)施、項(xiàng)目自動(dòng)化構(gòu)建等案例,歡迎大家關(guān)注本系列的其他文章。
前端之殤
要是你碰到前端工程師朋友,那聊聊瀏覽器的兼容性準(zhǔn)是沒(méi)錯(cuò),這和碰到英國(guó)朋友就談天氣是一個(gè)道理。大部分程序員朋友們一定會(huì)捶胸頓足,連連訴苦,不過(guò)如果對(duì)方一時(shí)語(yǔ)塞,或者欲言又止,請(qǐng)拍拍他 / 她肩膀說(shuō):
“沒(méi)事,過(guò)兩年出了新瀏覽器又是一條好漢。”
在前端界,瀏覽器兼容性是讓工程師們頭疼的問(wèn)題,對(duì)于經(jīng)驗(yàn)豐富的人來(lái)說(shuō),很清楚瀏覽器有哪些坑,但是對(duì)于大部分程序員,最可怕的是代碼明明在這個(gè)瀏覽器運(yùn)行得很好,但是到了另一個(gè)瀏覽器中就不能正常運(yùn)行了。對(duì)于這部分的程序員,保障代碼能正常運(yùn)行的方法便是能盡早發(fā)現(xiàn)問(wèn)題,然后將其解決。
通常情況下,發(fā)現(xiàn)兼容性問(wèn)題的方法莫過(guò)于將程序在各個(gè)瀏覽器中執(zhí)行一遍,但這是極其浪費(fèi)人力和時(shí)間的,最省力的方法也需要在每次版本的更迭時(shí)重復(fù)一遍測(cè)試工作。對(duì)于不同的兼容性要求,測(cè)試需要的時(shí)間各不相同,若是只支持最新版本的瀏覽器發(fā)現(xiàn)新版本瀏覽器,一樣的簡(jiǎn)單易用,速度提升30%,那么便測(cè)試 3、4 個(gè)瀏覽器即可,但是對(duì)于兼容性要求高的程序,有可能要測(cè)試 10 個(gè)瀏覽器以上。
對(duì)于中小型公司來(lái)說(shuō),如果沒(méi)有專職的測(cè)試人員,這樣的測(cè)試耗時(shí)是致命的。若進(jìn)行嚴(yán)格測(cè)試,則會(huì)拖慢項(xiàng)目進(jìn)度,倘若敷衍了事,那程序的質(zhì)量便沒(méi)法保證。
本文將作為多瀏覽器自動(dòng)化測(cè)試的第一篇文章,將以項(xiàng)目 A 作為例子,給讀者從頭介紹如何進(jìn)行本地多瀏覽的自動(dòng)化測(cè)試工作,包括測(cè)試的原理、測(cè)試框架的選取、測(cè)試工程的搭建和實(shí)現(xiàn)等。在下一篇文章中將介紹如何使用云服務(wù)實(shí)現(xiàn)更多瀏覽器的測(cè)試工作。另外“從入門(mén)到不放棄”系列將給讀者們帶來(lái)更多從零開(kāi)始的前端實(shí)踐案例,諸如前端組件庫(kù)設(shè)計(jì)與實(shí)施、項(xiàng)目自動(dòng)化構(gòu)建等案例,歡迎大家關(guān)注本系列的其他文章。
小窺測(cè)試
測(cè)試是一個(gè)龐大的主題,包括各種分類的測(cè)試,諸如黑盒測(cè)試/白盒測(cè)試、單元測(cè)試 / 集成測(cè)試 / 端到端測(cè)試等。通常程序員在測(cè)試自己的代碼的時(shí)候用得最多的便是單元測(cè)試,但是因?yàn)闇y(cè)試也是需要代價(jià),很多人是不喜歡寫(xiě)測(cè)試的,甚至是一點(diǎn)都不寫(xiě)。當(dāng)然今天我們不是要討伐諸位,而是希望讀者能從文中受益,從一個(gè)測(cè)試小白可以自己動(dòng)手搭建自己的測(cè)試工程。
在多瀏覽器的自動(dòng)化測(cè)試,我們多半是進(jìn)行端到端的測(cè)試工作,一小部分是大粒度的單元測(cè)試。端到端測(cè)試測(cè)試模擬用戶的行為。在 Web 應(yīng)用程序中,他們會(huì)啟動(dòng)服務(wù)器,打開(kāi)瀏覽器,模擬用戶的行為進(jìn)行點(diǎn)擊、輸入、提交等動(dòng)作,斷言瀏覽器中發(fā)生了特定的事情或者是得到了期待的結(jié)果,從而讓我們相信功能可以正常的運(yùn)行。而單元測(cè)試根據(jù)代碼單元的公共 API 運(yùn)行它們。這些測(cè)試需要?jiǎng)?chuàng)建一個(gè)類的實(shí)例,使用特定的輸入調(diào)用它的方法,斷言被調(diào)用的方法達(dá)到了預(yù)期的效果。
在下文中我們會(huì)看到這兩種測(cè)試的實(shí)踐,當(dāng)然有時(shí)候區(qū)分度并不大,可能無(wú)法明顯地區(qū)分哪些是端對(duì)端測(cè)試哪些是單元測(cè)試,有時(shí)候他們是混合起來(lái)的,不過(guò)只要記住我們的目標(biāo)是保證功能可以正常運(yùn)行就足夠了。
在瀏覽器的測(cè)試中, 可謂是最重要的工具之一。簡(jiǎn)單來(lái)說(shuō) 的作用是 " "——讓瀏覽器可以自動(dòng)化起來(lái)的工具。它提供了統(tǒng)一的接口,讓用戶可以使用不同的編程語(yǔ)言,調(diào)用其接口來(lái)模擬用戶的操作,例如點(diǎn)擊,移動(dòng)等操作。基本上一切人工操作的行為都可以通過(guò) 的 API 進(jìn)行觸發(fā)操作。我們將 看作是人手的代理,幫程序員完成一切用手干的活。
測(cè)試的技術(shù)方案選擇
在進(jìn)行項(xiàng)目實(shí)踐前,很重要的一項(xiàng)工作是選擇合適的技術(shù)棧。好比在前端開(kāi)發(fā)時(shí)應(yīng)該選擇 React,Vue 還是 作為框架一樣,前端的測(cè)試工作也需要選擇一套技術(shù)棧。
很多時(shí)候大家在制定技術(shù)棧時(shí)容易走偏,在選擇技術(shù)框架時(shí)不是選擇最合適的框架,而是選擇最熱門(mén)的框架。當(dāng)然一定程度上熱門(mén)的框架能反應(yīng)其受歡迎程度,可能是因?yàn)槠涑霰姷膬?yōu)點(diǎn),如較高的開(kāi)發(fā)效率、高效的渲染特性或者是活躍的社區(qū)。在前端開(kāi)發(fā)中,很容易有這樣的感受,就是只要半個(gè)月沒(méi)有關(guān)注業(yè)界的最新動(dòng)態(tài),就感覺(jué)恍若隔世,新的解決方案層出不窮,讓人喘不過(guò)氣。
就作者本人經(jīng)驗(yàn)來(lái)說(shuō),已經(jīng)過(guò)了慌亂的年紀(jì),再也不會(huì)盲目地追尋新技術(shù),而轉(zhuǎn)向關(guān)注技術(shù)背后解決的痛點(diǎn),就好像 2C 創(chuàng)業(yè)者們嘴上老說(shuō)的用戶痛點(diǎn)一樣。
在介紹本文涉及項(xiàng)目的技術(shù)棧之前,需要提醒諸位,此處的技術(shù)選擇并不一定完全適用于諸位的項(xiàng)目,請(qǐng)各位三思而測(cè)。目前市場(chǎng)上有眾多的測(cè)試框架,測(cè)試斷言庫(kù)甚至是全套的測(cè)試解決方案。Karma、 和 Mocha 是大家熟知的測(cè)試框架,而 chai, .js 是流行的斷言庫(kù),另外在不同的技術(shù)社區(qū)還有自成一套的測(cè)試技術(shù),比如 React 社區(qū)中的 Jest 和 都是受開(kāi)發(fā)者喜愛(ài)的測(cè)試框架和庫(kù),最近一些新的并行測(cè)試解決方案也日漸流行,如 AVA 、 。本文中的實(shí)踐來(lái)自于項(xiàng)目 A,在項(xiàng)目測(cè)試前期我們分析了測(cè)試需求,我們希望整個(gè)測(cè)試方案能滿足一下要求:
考量了以上的需求,我們認(rèn)為 .js 是一款非常合適的測(cè)試解決方案。當(dāng)然其他的測(cè)試框架也基本能滿足需求,但是從方便易用性上考慮,我們最后采用了 .js,該方案不僅提供簡(jiǎn)易封裝的瀏覽器代理操作 API, 還給我們提供了方便便捷的云測(cè)試配置(下一篇文章將著重介紹此內(nèi)容),就憑這兩點(diǎn)就已經(jīng)非常吸引我們了。對(duì)于前端測(cè)試新手,強(qiáng)烈推薦試用此框架,讓你可以迅速完成曾經(jīng)畏而卻步的測(cè)試工作。
項(xiàng)目實(shí)踐
項(xiàng)目 A 的本地測(cè)試實(shí)踐是需要分別在兩臺(tái)電腦上的多瀏覽器中執(zhí)行測(cè)試,兩臺(tái)電腦分別是 系統(tǒng)和 Mac 系統(tǒng),包括了 IE 、( / mac)、( / mac)、 等最新的主流瀏覽器。兩臺(tái)機(jī)子的測(cè)試是分別執(zhí)行的,我們通過(guò) 分別定期執(zhí)行機(jī)子上的測(cè)試任務(wù),將測(cè)試結(jié)果通過(guò)郵件的方式反饋給開(kāi)發(fā)人員。 是一個(gè)持續(xù)集成的平臺(tái),關(guān)于如果使用 請(qǐng)各位自己 。
在接下來(lái)的文章中,我們將只介紹在一臺(tái)機(jī)子上的工程實(shí)踐,對(duì)于多個(gè)機(jī)子的測(cè)試需要將如下的工程部署到不同的機(jī)子,再使用諸如 之類的工具進(jìn)行定期執(zhí)行就可以。
開(kāi)始工作前,我們需要將技術(shù)關(guān)系了然于心。我們?cè)? 框架下使用 中的 對(duì)瀏覽器進(jìn)行操作。不同的瀏覽器有不同的 ,整個(gè)技術(shù)棧圖如圖1所示:
在圖中 Test 即為 ,我們使用 提供封裝過(guò)的 API 進(jìn)行 Test Case 的書(shū)寫(xiě)。下面我們將從零開(kāi)始手把手教你如何使用 啟動(dòng)你的第一個(gè) Test case。
01安裝測(cè)試所需包
在自己的前端項(xiàng)目中安裝 .js,并將其保存在 .json的 中。
npm install nightwatch --save-dev
02增加 npm 入口
在 npm 中加入 test 指令入口,該條指令的具體工作是使用 test.conf.js 的配置發(fā)現(xiàn)新版本瀏覽器,一樣的簡(jiǎn)單易用,速度提升30%,執(zhí)行名為 'A' 、'B' 、'C' 的配置項(xiàng)(若為了直觀查看測(cè)試的內(nèi)容,可根據(jù)項(xiàng)目的測(cè)試瀏覽器和版本將名字設(shè)為 .0, .0 這樣的名字,此處設(shè)為 A , B , C 是避免大家誤認(rèn)為是指令是自動(dòng)根據(jù)名字去尋找匹配的瀏覽器)。更多命令的詳解請(qǐng)參照 文檔。
"scripts": {
...
"test": "./node_modules/.bin/nightwatch -c conf/test.conf.js -e A,B"
...
}
03配置
完成指令入口的配置工作,接下來(lái)需要完成 test.conf.js 的配置工作。在本地測(cè)試中,我們使用 對(duì)瀏覽器進(jìn)行代理操作。配置使用本地 操作本機(jī)瀏覽器 有三個(gè)重點(diǎn):
...
selenium : {
"start_process" : true,
"server_path":"./bin/selenium-server-standalone-3.4.0.jar",
"host" : "127.0.0.1",
"port" : 4444,

"cli_args": {
"webdriver.chrome.driver": "bin/chromedriver",
"webdriver.gecko.driver" : "bin/geckodriver"
}
},
...
test_settings: {
A: {
desiredCapabilities: {
'browserName': 'chrome'
}
},
B: {
desiredCapabilities: {
'browserName': 'safari'

}
}
}
諸位需要根據(jù)自己機(jī)子的實(shí)際情況進(jìn)行配置,如果是系統(tǒng),那么將沒(méi)有瀏覽器,而使用 IE 瀏覽器,這樣則會(huì)需要 IE 瀏覽器對(duì)應(yīng)的 。
04書(shū)寫(xiě)測(cè)試用例
在各項(xiàng)準(zhǔn)備工作完畢后,就只差測(cè)試用例了,下面是項(xiàng)目 A 的一個(gè)測(cè)試用例的片段,用于檢測(cè)頁(yè)面上 id 為 的 DOM 中的內(nèi)容字符,我們期待字符的長(zhǎng)度為 32, 如果該字符為 32 個(gè)字符,那么測(cè)試通過(guò),否則測(cè)試失敗。
需要注意的是因?yàn)榇?DOM 是動(dòng)態(tài)插入的,所以在判斷其字符前,我們使用 e 來(lái)檢查瀏覽器中 的 DOM 是否已經(jīng)顯示,若在5秒內(nèi)顯示則進(jìn)行下面的工作,如果沒(méi)有顯示,那么測(cè)試也會(huì)失敗。
module.exports = {
'@tags': ['unit'],
'unit testing' : function (browser) {
browser.url(`http://localhost:3010/test`)
.waitForElementVisible('#testid', 5000)
.getText("#testid",function(result){
this.assert.equal(result.value.length,32);
});

browser.end();
}
};
5. 運(yùn)行測(cè)試
到此為止,我們簡(jiǎn)單的測(cè)試工程已經(jīng)搭建完畢。現(xiàn)在我們回過(guò)頭去,執(zhí)行我們最開(kāi)始配置的 test 指令,啟動(dòng)測(cè)試任務(wù)。你需要在命令中執(zhí)行:
npm test
如果順利的話,此時(shí)你會(huì)看到瀏覽器自動(dòng)地打開(kāi)關(guān)閉,很快就能從終端上看到如下的測(cè)試結(jié)果,圖 2 展示的是多個(gè)測(cè)試用例成功的結(jié)果,圖 3 展示的是測(cè)試失敗的結(jié)果(如遇到無(wú)法測(cè)試或者其它異常情況請(qǐng) 。:D)。
從測(cè)試結(jié)果中可以查看測(cè)試用例的測(cè)試結(jié)果,包括測(cè)試的瀏覽器、未通過(guò)測(cè)試的信息詳情等。至此,一個(gè)從零開(kāi)始的本地測(cè)試實(shí)踐教程結(jié)束。
本地測(cè)試與云測(cè)試
因?yàn)楸镜貫g覽器的類型有限,一般我們更多地使用本地的多瀏覽器測(cè)試來(lái)完成功能驗(yàn)證的工作,對(duì)于要求更嚴(yán)的兼容性測(cè)試,我們將采用云測(cè)試的方式。云測(cè)試即云服務(wù)提供商將向我們提供更多的云主機(jī),每臺(tái)主機(jī)上運(yùn)行著不同版本的瀏覽器。通過(guò)使用云測(cè)試服務(wù),我們就能將測(cè)試覆蓋到更多類型、版本的瀏覽器。
在下一篇文章中,我們?nèi)砸皂?xiàng)目 A 為例子,使用 框架,在此文章的基礎(chǔ)上介紹云測(cè)試和云測(cè)試工程的搭建。
潘潘,豈安科技軟件工程師
同濟(jì)大學(xué)畢業(yè),曾在等多家知名公司實(shí)習(xí),3年全棧開(kāi)發(fā)經(jīng)驗(yàn),負(fù)責(zé)豈安科技核心產(chǎn)品初期的前端開(kāi)發(fā)和架構(gòu)工作。