neo4j browser执行脚本后不提示用时_还不懂什么是分层自动化测试的,有赞的实践经历告诉你...
#? 背景
先理一下自動(dòng)化測(cè)試的概念,從廣義上來(lái)說(shuō),一切通過(guò)工具(程序)的方式來(lái)代替或者輔助手工測(cè)試的行為都可以成為自動(dòng)化。從狹義上來(lái)說(shuō),通過(guò)編寫腳本的方式,模擬手工測(cè)試的過(guò)程,從而替代人工對(duì)系統(tǒng)的功能進(jìn)行驗(yàn)證。
有贊是一家互聯(lián)網(wǎng)行業(yè)的創(chuàng)業(yè)公司,測(cè)試起步較晚,發(fā)布非常頻繁,就算每次只回歸核心功能,對(duì)人數(shù)極少的幾個(gè)測(cè)試人員來(lái)說(shuō)工作量巨大,且基本是重復(fù)勞動(dòng),極其枯燥,持續(xù)時(shí)間長(zhǎng)了也容易出錯(cuò)。
所以初期我們測(cè)試自動(dòng)化切入的思路非常簡(jiǎn)單:從實(shí)際用戶的角度出發(fā),模擬真實(shí)的操作,替代現(xiàn)有的手工測(cè)試用例的執(zhí)行。這樣一來(lái),每次重復(fù)的工作就可以用自動(dòng)化來(lái)替代,測(cè)試人員只需要關(guān)注每次發(fā)布的增量需求即可。
隨著腳本數(shù)量的增加,這種自動(dòng)化覆蓋的方式的弊端也逐漸暴露:
執(zhí)行效率低下
構(gòu)建成功率低(誤報(bào)率高)。
受前端樣式變更影響大
外部依賴較多,不是所有用例都能自動(dòng)化
覆蓋能力有限
雖然我們?cè)跍y(cè)試框架和工具層面通過(guò)結(jié)合 selenium-grid 實(shí)現(xiàn)了腳本并發(fā)執(zhí)行和失敗用例重試機(jī)制以提高執(zhí)行效率和降低誤報(bào)率,但是這種方式只能緩解問(wèn)題,并不能從根本解決覆蓋不全的問(wèn)題。
正好趕上公司的 SOA 服務(wù)化進(jìn)程,測(cè)試這邊也開始配合的做自動(dòng)化方面的轉(zhuǎn)變,從原來(lái)的黑盒系統(tǒng)級(jí)自動(dòng)化測(cè)試向分層自動(dòng)化測(cè)試轉(zhuǎn)變。
# 分層自動(dòng)化測(cè)試
在談分層測(cè)試之前,先回顧幾個(gè)概念:
單元測(cè)試:對(duì)軟件中的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證。
具體的說(shuō)就是開發(fā)者編寫的一小段代碼,用于檢驗(yàn)被測(cè)代碼的一個(gè)很小的、很明確的功能是否正確。通常而言,一個(gè)單元測(cè)試是用于判斷某個(gè)特定條件(或者場(chǎng)景)下某個(gè)特定函數(shù)的行為。
集成測(cè)試:集成測(cè)試是在單元測(cè)試的基礎(chǔ)上,測(cè)試在將所有的軟件單元按照概要設(shè)計(jì)規(guī)格說(shuō)明的要求組裝成模塊、子系統(tǒng)或系統(tǒng)的過(guò)程中各部分工作是否達(dá)到或?qū)崿F(xiàn)相應(yīng)技術(shù)指標(biāo)及要求的活動(dòng)。
也就是說(shuō),在集成測(cè)試之前,單元測(cè)試應(yīng)該已經(jīng)完成。這一點(diǎn)很重要,因?yàn)槿绻唤?jīng)過(guò)單元測(cè)試,那么集成測(cè)試的效果將會(huì)受到很大影響,并且會(huì)大幅增加軟件單元代碼糾錯(cuò)的代價(jià)。
系統(tǒng)測(cè)試:將需測(cè)試的軟件,作為整個(gè)基于計(jì)算機(jī)系統(tǒng)的一個(gè)元素,與計(jì)算機(jī)硬件、外設(shè)、某些支持軟件、數(shù)據(jù)和人員等其他系統(tǒng)元素及環(huán)境結(jié)合在一起測(cè)試。
系統(tǒng)測(cè)試的目的在于通過(guò)與系統(tǒng)的需求定義作比較,發(fā)現(xiàn)軟件與系統(tǒng)定義不符合或與之矛盾的地方。
接下來(lái)我們談?wù)動(dòng)匈澥侨绾坞S著系統(tǒng)拆分 SOA 服務(wù)化推進(jìn)分層自動(dòng)化測(cè)試的。在經(jīng)典的測(cè)試金字塔中:
其中 Unit 代表單元測(cè)試,Service 代表服務(wù)集成測(cè)試,UI 代表頁(yè)面級(jí)的系統(tǒng)測(cè)試。分層的自動(dòng)化測(cè)試倡導(dǎo)產(chǎn)品的不同層次都需要自動(dòng)化測(cè)試,這個(gè)金字塔也正表示不同層次需要投入的精力和工作量。
下面逐層介紹有贊的分層自動(dòng)化實(shí)踐。
1、Unit-單元測(cè)試
在系統(tǒng)拆分之前,有贊只有一個(gè)龐大的巨無(wú)霸系統(tǒng),單元測(cè)試極度缺失。在系統(tǒng)逐漸SOA服務(wù)化的過(guò)程中,我們逐漸提出了對(duì)單元測(cè)試覆蓋率的要求。
我們的單元測(cè)試會(huì)分別做DAO層和服務(wù)層的測(cè)試。DAO層的單元測(cè)試主要保障SQL腳本的正確性,在做服務(wù)層的單元測(cè)試時(shí)就可以以DAO層是正確的前提進(jìn)行用例編寫了。
為了做細(xì)粒度的測(cè)試,需要解決單元測(cè)試的外部依賴。系統(tǒng)和模塊之間的依賴可以通過(guò)Mock框架(Mockito/EasyMock)解耦,同時(shí)可以結(jié)合h2database解決對(duì)數(shù)據(jù)庫(kù)的依賴,使得測(cè)試用例盡可能做到可以隨時(shí)隨地運(yùn)行。
這一層發(fā)現(xiàn)并解決問(wèn)題付出的成本相對(duì)來(lái)說(shuō)最低,自動(dòng)化用例的維護(hù)成本也不高,總的來(lái)說(shuō)自動(dòng)化測(cè)試的投入產(chǎn)出比最高。
單元測(cè)試的責(zé)任主體一般來(lái)說(shuō)是開發(fā)人員,寫單元測(cè)試也是開發(fā)人員對(duì)自己的代碼進(jìn)行檢查的一個(gè)過(guò)程。
2、Service-服務(wù)集成測(cè)試
我們?cè)诜?wù)層的測(cè)試首要考慮的是各系統(tǒng)(子系統(tǒng))的集成測(cè)試。因?yàn)樵诮?jīng)過(guò)單元測(cè)試這一層的保障之后,在服務(wù)層我們更關(guān)注的是某個(gè)系統(tǒng)的輸入輸出功能是否正確,以及若干個(gè)系統(tǒng)間的交互是否和業(yè)務(wù)場(chǎng)景的要求一致。
先來(lái)看看我們系統(tǒng)拆分之后的SOA系統(tǒng)應(yīng)用架構(gòu)圖:
展現(xiàn)層:老的 Iron 應(yīng)用,代碼為 php。拆分之后 Iron 只剩下和前端交互的展現(xiàn)層邏輯,以及調(diào)用核心業(yè)務(wù)的 API層。
核心業(yè)務(wù):Iron 系統(tǒng)拆分出來(lái)的核心業(yè)務(wù)。
這一層的被測(cè)對(duì)象是抽離了展現(xiàn)層的代碼(前端以及部分后端展現(xiàn)層邏輯)。
鑒于有贊的測(cè)試起步較晚(應(yīng)該很多創(chuàng)業(yè)公司都有類似情況),測(cè)試資源緊缺,代碼覆蓋率低得可憐。所以我們的初期自動(dòng)化用例覆蓋策略是這樣的:
從老的 Iron 應(yīng)用的 API 接口作為業(yè)務(wù)場(chǎng)景覆蓋的切入點(diǎn)
優(yōu)先覆蓋核心業(yè)務(wù)的場(chǎng)景
配合系統(tǒng)拆分,優(yōu)先覆蓋拆分出去的系統(tǒng)
已拆分出去的系統(tǒng),做好系統(tǒng)服務(wù)層的測(cè)試覆蓋(全面覆蓋該服務(wù)的接口)
測(cè)試依賴的數(shù)據(jù)準(zhǔn)備優(yōu)先選擇調(diào)用系統(tǒng)接口的方式(為了增加業(yè)務(wù)覆蓋面)
測(cè)試方式逐漸從黑盒向灰盒/白盒轉(zhuǎn)變
這樣做的好處是,可以快速增加業(yè)務(wù)場(chǎng)景的覆蓋面,同時(shí)事先準(zhǔn)備好的 API 接口用例,可以作為系統(tǒng)拆分后的冒煙測(cè)試用例,起到核心老功能的回歸作用(只是做系統(tǒng)拆分,業(yè)務(wù)邏輯以及對(duì)展現(xiàn)層暴露的接口行為不變)。
畢竟在自動(dòng)化測(cè)試的過(guò)程中,最怕的就是變化,會(huì)帶來(lái)更多的腳本維護(hù)工作,而以這種方式覆蓋的用例,目前來(lái)看維護(hù)成本很低。
再介紹一下這一層的初期我們用例的基本形態(tài):
專注于業(yè)務(wù)場(chǎng)景,和 UI 腳本一致,只是腳本從操作頁(yè)面變成了調(diào)用接口。相對(duì)于 UI 自動(dòng)化,服務(wù)層的接口測(cè)試更加穩(wěn)定,測(cè)試用例也更容易維護(hù)。服務(wù)層接口測(cè)試可以更關(guān)注與系統(tǒng)整體的邏輯(業(yè)務(wù))驗(yàn)證,而 UI 自動(dòng)化則會(huì)轉(zhuǎn)變?yōu)轫?yè)面展示邏輯及界面前端與服務(wù)的集成驗(yàn)證(這個(gè)在 UI 層會(huì)介紹)。
暫時(shí)不做系統(tǒng)間的 Mock。更多的考慮系統(tǒng)之間的耦合和依賴。
搭建 MockServer 解決系統(tǒng)的外部依賴,主要是類似于支付等第三方系統(tǒng)(關(guān)于我們的 MockServer 會(huì)有專門的文章介紹)。
結(jié)合我們的交易系統(tǒng)舉個(gè)例子:比如交易系統(tǒng)會(huì)依賴于商品和營(yíng)銷活動(dòng),那我們的下單場(chǎng)景的用例會(huì)依次調(diào)用商品和營(yíng)銷這幾個(gè)系統(tǒng)的 API 構(gòu)造數(shù)據(jù)作為用例的前置條件,然后按照下單的業(yè)務(wù)場(chǎng)景調(diào)用交易系統(tǒng)的下單接口,校驗(yàn)返回值以及寫入 DB 的數(shù)據(jù),最后做好數(shù)據(jù)清理的工作。
我們?cè)谶@一層的測(cè)試框架選擇是基于公司通用的服務(wù)框架(Nova)基礎(chǔ)之上搭建的,架構(gòu)圖如下:
BIT :服務(wù)接口集成測(cè)試(Business Interface&Integration Test)
SUT:被測(cè)系統(tǒng)(System Under Test)
Validator:各個(gè)業(yè)務(wù)的數(shù)據(jù)庫(kù)結(jié)果驗(yàn)證封裝
Mock:用例前置條件依賴的數(shù)據(jù)Mock服務(wù)
HttpClient:根據(jù)IRON系統(tǒng)的接口封裝了返回通用的RPCResult對(duì)象
Util:常用工具類封裝
Biz:在此封裝了所有被測(cè)系統(tǒng)對(duì)外暴露的接口,供測(cè)試用例直接調(diào)用
TestCase:我們服務(wù)接口測(cè)試又分為SDV(System design Verify-系統(tǒng)設(shè)計(jì)驗(yàn)證)和SIT(System Integration Test-系統(tǒng)集成測(cè)試)。按照上面提到的用例覆蓋策略,我們是在系統(tǒng)拆分之前,先根據(jù)該系統(tǒng)的業(yè)務(wù)場(chǎng)景和REST接口補(bǔ)充核心的接口集成測(cè)試用例,后續(xù)可以作為系統(tǒng)拆分之后的冒煙用例。在系統(tǒng)拆分之后,詳細(xì)補(bǔ)充該系統(tǒng)的測(cè)試用例,粒度更細(xì)。
Facade:結(jié)合了Nova框架,對(duì)外發(fā)布各個(gè)業(yè)務(wù)的數(shù)據(jù)構(gòu)造的REST接口,同時(shí)可以作為測(cè)試數(shù)據(jù)構(gòu)造系統(tǒng),輔助測(cè)試人員的手工測(cè)試。
這一層的測(cè)試覆蓋主要是由測(cè)試人員進(jìn)行,是測(cè)試人員大展身手的地方。
我們不需要非常詳細(xì)的了解代碼的實(shí)現(xiàn),但是我們的用例里充分體現(xiàn)了我們對(duì)系統(tǒng)的結(jié)構(gòu),模塊之間關(guān)系等的充分的理解。
后續(xù)我們對(duì)于 Service 層自動(dòng)化測(cè)試的推進(jìn)策略是:
逐漸豐富 SDV 層的測(cè)試用例,并且在一定程度上進(jìn)行用例依賴的系統(tǒng)的解耦,比如數(shù)據(jù)構(gòu)造從調(diào)用接口向直接往數(shù)據(jù)庫(kù)寫入數(shù)據(jù)轉(zhuǎn)變。
逐漸細(xì)化拆分業(yè)務(wù)場(chǎng)景,做好用例的解耦。
優(yōu)先做場(chǎng)景覆蓋,之后再考慮代碼覆蓋。
3、UI-展現(xiàn)測(cè)試
先提一個(gè)問(wèn)題,既然在文章開篇提到了 UI 自動(dòng)化測(cè)試有這么多弊端,這么勞民傷財(cái),那么是否還有必要進(jìn)行 UI 層的自動(dòng)化呢?
答案是肯定的,因?yàn)?UI 層是產(chǎn)品最終呈現(xiàn)給用戶的東西。所以在做好上面兩層的測(cè)試覆蓋之后,測(cè)試人員可以投入更多的精力到 UI 層的測(cè)試上。正是因?yàn)闇y(cè)試人員會(huì)在 UI 層投入較大精力,還是有必要通過(guò)自動(dòng)化來(lái)幫助解放部分重復(fù)勞動(dòng)力。
根據(jù)我們的 UI 層自動(dòng)化實(shí)踐,提一下 UI 層自動(dòng)化覆蓋的原則:
能在底層做自動(dòng)化覆蓋,就盡量不在 UI 層做自動(dòng)化覆蓋
只做最核心的功能的自動(dòng)化覆蓋,腳本可維護(hù)性盡可能提高
提高 UI 腳本可維護(hù)性的方法是遵循 Page Object 設(shè)計(jì)模式。
Page Object
Page Object 模式是為了避免在測(cè)試代碼中直接操作 HTML 元素,對(duì) Web 頁(yè)面的抽象。好處有:
減少測(cè)試代碼的冗余
提高測(cè)試代碼的可讀性和穩(wěn)定性
提高測(cè)試代碼的可維護(hù)性
一個(gè)簡(jiǎn)單的例子
以有贊首頁(yè)的登錄操作為例(Ruby):
class LoginPage include HeaderNav def login(account, password) text_account.wait_until_present.set(account) text_password.set(password) button_login.wait_until_present.click return MainPage.new(@browser) end private def text_account @browser.text_field(:name => 'account') end def text_password @browser.text_field(:name => 'password') end def button_login @browser.button(:class => 'login-btn') endend123456789101112131415161718192021public 方法對(duì)外暴露頁(yè)面的服務(wù),對(duì)于登錄頁(yè)面來(lái)說(shuō)就是登錄行為
頁(yè)面的 UI 細(xì)節(jié)設(shè)為 private 方法對(duì)外隱藏
跳轉(zhuǎn)到新的頁(yè)面后在此方法中 return 之后的頁(yè)面的對(duì)象,比如登錄之后跳轉(zhuǎn)到首頁(yè)(MainPage)。甚至同一頁(yè)面也可以返回 self 做鏈?zhǔn)讲僮鳌?/p>
各個(gè)頁(yè)面的公共部分,如頁(yè)面頂部導(dǎo)航,可以封裝成 Module 供各個(gè)頁(yè)面對(duì)象直接 include
下面我們來(lái)看看測(cè)試用例:
class TestLogin < Test::Unit::TestCase def testLogin @browser = Browser.new @browser.goto 'youzan.com' main_page = @browser.login_page.login('xx', '123') #斷言 endend12345678這樣最終的測(cè)試腳本呈現(xiàn)的就是單純的頁(yè)面操作邏輯,更貼近文本測(cè)試用例。
下面來(lái)看一下我們的測(cè)試框架:
Base:這一層和大多數(shù) UI 測(cè)試框架大同小異,使用的是 selenium 和 watir,用例管理方面并沒(méi)有使用 Ruby 領(lǐng)域炙手可熱的 BDD 框架 cucumber,而是最基本的單元測(cè)試框架 MiniTest。同時(shí)還引入了 ruby 的多線程包,配合 UI 腳本的并發(fā)執(zhí)行。
Actir:我們自己封裝的測(cè)試框架。
Initializer:自動(dòng)按照約定的工程結(jié)構(gòu)加載所有的 ruby 文件,并根據(jù) Page 的類名和反射自動(dòng)生成了所有頁(yè)面類的對(duì)象實(shí)例。
UA:封裝好測(cè)試需要的瀏覽器U ser-Agent。
Executor:用例執(zhí)行器?;?ruby 的多線程包以及 selenium-grid,實(shí)現(xiàn)了所有用例的調(diào)度及分布式執(zhí)行,可以一定程度上大大提升 UI 腳本的執(zhí)行效率。執(zhí)行器還包括了失敗用例重試機(jī)制。
Util:工具類,包括了配置文件讀寫、數(shù)據(jù)驅(qū)動(dòng)等。
Report:根據(jù) UI 測(cè)試腳本執(zhí)行的最終結(jié)果(失敗重試的用例以最終的結(jié)果為準(zhǔn))自動(dòng)生成 HTML 格式的測(cè)試報(bào)告。
Cli:根據(jù) Actir 框架的上述功能,封裝出的命令行工具,方便持續(xù)集成。
Project
Pages:基于 PageObject 模式包裝出的頁(yè)面的對(duì)象
Components:各個(gè)頁(yè)面的公用的部分或者插件,如圖片上傳、地址選擇等。包裝成 Module 供各個(gè)頁(yè)面對(duì)象需要時(shí)直接include。
Item:根據(jù)系統(tǒng)業(yè)務(wù)抽象出的對(duì)象,如訂單、優(yōu)惠券、商品等
User:根據(jù)系統(tǒng)業(yè)務(wù)抽象出的角色及其Action,如買家的購(gòu)買行為、買家的退款、發(fā)貨等。
隨著服務(wù)層自動(dòng)化覆蓋率越來(lái)越高,UI層的自動(dòng)化覆蓋會(huì)逐漸轉(zhuǎn)變?yōu)轫?yè)面展示邏輯及界面前端與服務(wù)的展現(xiàn)層交互的集成驗(yàn)證。我們后續(xù)對(duì)于UI層自動(dòng)化的演進(jìn)規(guī)劃是這樣的:
依賴環(huán)境的 Mock,解除UI腳本的外部依賴
完善的數(shù)據(jù)準(zhǔn)備,可以通過(guò)后端服務(wù)接口的 mock 使 UI 自動(dòng)化更關(guān)注頁(yè)面業(yè)務(wù)邏輯的自動(dòng)校驗(yàn)。
頁(yè)面截圖比對(duì)校驗(yàn) UI 樣式。
UI 層的自動(dòng)化測(cè)試也是由測(cè)試人員負(fù)責(zé),在覆蓋了核心業(yè)務(wù)核心場(chǎng)景之后,不應(yīng)該在這層的自動(dòng)化覆蓋上投入太多的精力和資源。
就算我們?cè)谝欢ǔ潭壬咸岣吡四_本的可維護(hù)性,可是畢竟自動(dòng)化測(cè)試最怕的就是變化,而UI界面是變化頻率最高的一層,所以還是得投入一定的精力維護(hù),不是么?
# 持續(xù)集成
有了上述各層的自動(dòng)化測(cè)試腳本,下面我們需要建立起持續(xù)集成體系。持續(xù)集成的目的:
流程自動(dòng)化,提高工作效率
最大化自動(dòng)化測(cè)試腳本的價(jià)值
我們的持續(xù)集成是基于 Jenkins 搭建的,主要的動(dòng)作如下:
代碼提交自動(dòng)執(zhí)行單元測(cè)試
單元測(cè)試通過(guò)后自動(dòng)部署整體的環(huán)境
自動(dòng)執(zhí)行集成自動(dòng)化測(cè)試(Service/UI)
自動(dòng)生成構(gòu)建的詳細(xì)測(cè)試報(bào)告,同時(shí)自動(dòng)通知相關(guān)人員
持續(xù)集成所需的支撐有:
測(cè)試環(huán)境自動(dòng)部署腳本
代碼覆蓋率自動(dòng)收集
Java 應(yīng)用:基于 JaCoCo+Jenkins 插件的方式
php 應(yīng)用:通過(guò) Xdebug+phpunit 的方式
測(cè)試報(bào)告相關(guān)插件及腳本
代碼靜態(tài)檢查等
對(duì)于持續(xù)集成我們后續(xù)的演進(jìn)規(guī)劃是朝著持續(xù)交付和持續(xù)部署的方向努力,在持續(xù)集成的基礎(chǔ)之上,自動(dòng)將代碼部署到測(cè)試環(huán)境上方便測(cè)試人員進(jìn)行手工測(cè)試。
# 總結(jié)
本文主要從整體上介紹了在有贊 SOA 化的進(jìn)程中,測(cè)試推行的分層自動(dòng)化實(shí)踐,以及后續(xù)的發(fā)展方向,同時(shí)簡(jiǎn)單介紹了相關(guān)的測(cè)試框架結(jié)構(gòu)。下面再?gòu)恼w回顧一下我們的分層自動(dòng)化的要點(diǎn):
單元測(cè)試:
優(yōu)先級(jí)最高
粒度最細(xì)、覆蓋面最全
開發(fā)實(shí)施
服務(wù)測(cè)試
對(duì)測(cè)試來(lái)說(shuō)優(yōu)先級(jí)最高
從業(yè)務(wù)場(chǎng)景的角度切入
系統(tǒng)外部接口100%覆蓋
關(guān)注系統(tǒng)間的依賴和調(diào)用
測(cè)試實(shí)施
頁(yè)面測(cè)試
優(yōu)先級(jí)相對(duì)最低
只保證核心功能的自動(dòng)化覆蓋,只關(guān)注UI層的問(wèn)題
通過(guò)數(shù)據(jù)mock的方式減少對(duì)后臺(tái)數(shù)據(jù)的依賴。
測(cè)試實(shí)施
至于各層投入的具體比重,還是需要根據(jù)項(xiàng)目的需求來(lái)實(shí)際規(guī)劃。在《Google 測(cè)試之道》一書,對(duì)于 Google 產(chǎn)品,70%的投入為單元測(cè)試,20%為集成、接口測(cè)試,10% 為UI層的自動(dòng)化測(cè)試。
最后再提一些觀點(diǎn)吧:
越底層的自動(dòng)化,收益越高
質(zhì)量不是測(cè)試人員一個(gè)人的事情
自動(dòng)化測(cè)試的目的不是為了減少手工測(cè)試,而是為了測(cè)試人員做更多更有意義的手工測(cè)試(end)
?往期推薦?
?
- 轉(zhuǎn)給你的老板,如何給程序員更少的薪水?
- 20年3月數(shù)據(jù)庫(kù)排行榜
- v2ex:飛機(jī)上用的是什么操作系統(tǒng)?
點(diǎn)擊
總結(jié)
以上是生活随笔為你收集整理的neo4j browser执行脚本后不提示用时_还不懂什么是分层自动化测试的,有赞的实践经历告诉你...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c语言scanf函数隐藏的缓冲区,零基础
- 下一篇: vc6.0mfc中单选按钮如何分组_按钮