軟件測試 | UI自動化設(shè)計(jì)軍規(guī)
前言
有段時間沒碰過 UI 自動化的東西了。 最近出了新產(chǎn)品要搞 UI 自動化,所以又開始把以前的東西撿回來。 在這里分享一下我們使用的 UI 自動化設(shè)計(jì)軍規(guī)。
PS: 此軍規(guī)是在 java 1.8 的背景下設(shè)計(jì)的
總體規(guī)則
所有模塊設(shè)計(jì)均遵循 page object 結(jié)構(gòu)

用例層:測試人員編寫測試用例代碼的地方,可以調(diào)用 page 層和封裝層。
page 層:一個頁面一個類,包含該頁面的業(yè)務(wù)邏輯封裝以及部分控件定義。
封裝層:根據(jù)業(yè)務(wù)需要,封裝常用的業(yè)務(wù)邏輯 (相比于 page 層的業(yè)務(wù)邏輯封裝,它的范圍更廣,有些時候是跨頁面的業(yè)務(wù)邏輯。 屬于模塊級的業(yè)務(wù)封裝)
頁面設(shè)計(jì)規(guī)則
所有導(dǎo)航,頁面輔助以及會跨越多個頁面的邏輯均涉及為接口,接口中定義默認(rèn)實(shí)現(xiàn)。

如上圖的導(dǎo)航,二級導(dǎo)航以及頁面輔助功能都會在不同的主頁面上出現(xiàn)。 一級導(dǎo)航為幾乎所有頁面都會用到, 二級導(dǎo)航為該模塊下所有頁面會用到。 頁面輔助功能為不同的頁面會用到不同的頁面輔助功能。比如 DAG 頁面會使用元素列表和算子列表。 但是 notebook 文件只使用元素列表。 基于此種特性, 我們將這些功能設(shè)計(jì)為接口并提供默認(rèn)實(shí)現(xiàn)。哪個頁面需要用到就去 implement。以此來達(dá)到代碼復(fù)用的目的。例如:

由于 jdk 1.8 的接口有 default 實(shí)現(xiàn)的功能。所以需要用到相應(yīng)功能的子類直接實(shí)現(xiàn)接口以繼承相應(yīng)的能力。 這也是為什么選擇用 jdk1.8 的主要原因。
每個 page 類只負(fù)責(zé)自己頁面的邏輯
page 類遵循一個原則---- 產(chǎn)品 UI 上這個頁面能做什么, 這個 page 類就只能做什么。 不準(zhǔn)許跨頁面邏輯合并在一個類中實(shí)現(xiàn) (頁面可以有跨頁面和模塊級功能,但是具體每個頁面的邏輯必須由每個頁面自己實(shí)現(xiàn))。 出現(xiàn)多個頁面共用的功能參考上一條規(guī)則將其實(shí)現(xiàn)為接口。
頁面類的類名以 Page 為結(jié)尾。 接口 (共用邏輯) 不得使用 Page 結(jié)尾
頁面較多的時候用來區(qū)分頁面和共用邏輯的規(guī)則
每個頁面以封裝業(yè)務(wù)邏輯為主,通過參數(shù)控制調(diào)用不同的業(yè)務(wù)邏輯。 無特殊情況下不要讓外界知道控件的信息。
如上圖,這是一個設(shè)置 FE 算子的邏輯,其他任何頁面或者測試用例都通過此邏輯來設(shè)置 FE 算子。外界不感知任何控件信息。 如需要不同的算子設(shè)置,可以在初始化該類對象的時候,set 不同的屬性值。如下:
所有頁面邏輯皆返回特定頁面對象,以保證測試用例使用 workflow 式 API。
以登錄為例。 如下圖:

登錄后,進(jìn)入導(dǎo)航頁,然后在導(dǎo)航頁的方法如下:

在進(jìn)入模型 IDE 的時候返回模型 IDE page 的對象。
這樣可以保持測試用例始終保持 workflow 式的調(diào)用。 如下:
除特別簡單的邏輯外。所有業(yè)務(wù)邏輯的參數(shù)均使用 java bean 以及枚舉封裝,禁止使用基本數(shù)據(jù)類型 (int,String, long 等),并按照 UI 實(shí)際情況設(shè)計(jì)默認(rèn)值
為防止產(chǎn)品設(shè)計(jì)變化,所有的業(yè)務(wù)邏輯參數(shù)都由 java bean 封裝。 因?yàn)槿绻皇褂?java bean 而是使用基本數(shù)據(jù)類型。那么在產(chǎn)品變化的時候,比如 UI 上多了一個必填的元素的時候。方法簽名就會變化,導(dǎo)致所有調(diào)用此方法的調(diào)用方都要變化。 而是使用 java bean 封裝的參數(shù)可以在其中直接增加一個屬性并設(shè)置默認(rèn)值即可。
如下圖:圖 1 為 FE 算子的配置類,圖二為調(diào)用方。


所有狀態(tài)嗎,產(chǎn)品特定文案,內(nèi)置類型等均使用枚舉定義。并使用枚舉來規(guī)范入?yún)ⅰ?/p>
產(chǎn)品文案會變化,狀態(tài)流轉(zhuǎn)會變化。 有些時候我們會使用相應(yīng)的文案來搜索頁面控件, 有時候我們也會以查詢數(shù)據(jù)庫的方式來跟蹤任務(wù)的狀態(tài), 并且這些會在整個測試的各個地方使用到。 所以嚴(yán)禁在 case 中或者 page 類中直接使用字符串或者數(shù)據(jù)類型的變量直接使用。 而是要將他們提取為枚舉來使用。如下圖:
上圖是數(shù)據(jù)庫中一個任務(wù)當(dāng)前狀態(tài)的枚舉類型,在 case 運(yùn)行時會動態(tài)查詢數(shù)據(jù)庫中此任務(wù)的 status 字段來判斷任務(wù)當(dāng)前狀態(tài)。在 case 中調(diào)用等待任務(wù)完成的時候,需要傳入此枚舉表示這個用例期望這次任務(wù)的結(jié)果是哪種狀態(tài),如下圖表示期望 dataload 運(yùn)行成功。 當(dāng)然也有些 case 會期望任務(wù)失敗。
模塊間有數(shù)據(jù)依賴的時候。每個模塊自己負(fù)責(zé)提供對外接口。
比如測試模型中心或者預(yù)估服務(wù)的時候,首先必須要有模型事先產(chǎn)出。而產(chǎn)出一個模型需要在模型 IDE 中執(zhí)行很復(fù)雜的步驟,跳轉(zhuǎn)多個頁面。 那么模型 IDE 負(fù)責(zé)對外提供一個封裝了所有邏輯的簡單接口對外使用。 例如:
ModelIDE 負(fù)責(zé)提供 modelFactory,調(diào)用方只需要傳遞一個模型訓(xùn)練算法的默認(rèn)配置就可以產(chǎn)出相應(yīng)算法的模型出來。 至于里面如何創(chuàng)建 project 和 dag, 使用什么數(shù)據(jù),怎么抽取特征等等都不是調(diào)用方關(guān)心的。 他們只要一個模型出來,至于這個模型怎么出來的邏輯,不要暴露給調(diào)用方。
所有業(yè)務(wù)邏輯使用*@*Step標(biāo)注進(jìn)行標(biāo)記 (allure 的特性).

用例編寫規(guī)則
每個 case 都必須使用 Features,Stroies, Title 標(biāo)注來為 case 添加 report 信息 (我們使用的是 allure 這個 report 框架), 根據(jù)情況可以添加 Description 標(biāo)注。
具體如下:

case 中涉及 UI 上創(chuàng)建的實(shí)體名稱,比如項(xiàng)目,數(shù)據(jù),模型,用戶等都需要使用隨機(jī)名稱。 不能使用固定名稱。 以防一個環(huán)境多次運(yùn)行的時候因?yàn)槊Q沖突而失敗
case 中不準(zhǔn)許出現(xiàn)頁面元素信息,所有頁面元素的封裝和業(yè)務(wù)邏輯的封裝要寫在 page 層中
結(jié)尾
到這里差不多了,主要是一些設(shè)計(jì)上的規(guī)范,剩下的什么命名規(guī)范之類的就不講了。 下一次更新一把 UI 自動化中常用的設(shè)計(jì)模式。