午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

這是有贊的分層自動化測試實踐

 西北望msm66g9f 2019-12-10

1. 背景

先理一下自動化測試的概念,從廣義上來說,一切通過工具(程序)的方式來代替或者輔助手工測試的行為都可以成為自動化。從狹義上來說,通過編寫腳本的方式,模擬手工測試的過程,從而替代人工對系統(tǒng)的功能進行驗證。

有贊是一家互聯(lián)網(wǎng)行業(yè)的創(chuàng)業(yè)公司,測試起步較晚,發(fā)布非常頻繁,就算每次只回歸核心功能,對人數(shù)極少的幾個測試人員來說工作量巨大,且基本是重復勞動,極其枯燥,持續(xù)時間長了也容易出錯。

所以初期我們測試自動化切入的思路非常簡單:從實際用戶的角度出發(fā),模擬真實的操作,替代現(xiàn)有的手工測試用例的執(zhí)行。這樣一來,每次重復的工作就可以用自動化來替代,測試人員只需要關注每次發(fā)布的增量需求即可。

隨著腳本數(shù)量的增加,這種自動化覆蓋的方式的弊端也逐漸暴露:

  • 執(zhí)行效率低下

  • 構(gòu)建成功率低(誤報率高)。

  • 受前端樣式變更影響大

  • 外部依賴較多,不是所有用例都能自動化

  • 覆蓋能力有限

雖然我們在測試框架和工具層面通過結(jié)合selenium-grid實現(xiàn)了腳本并發(fā)執(zhí)行和失敗用例重試機制以提高執(zhí)行效率和降低誤報率,但是這種方式只能緩解問題,并不能從根本解決覆蓋不全的問題。

正好趕上公司的SOA服務化進程,測試這邊也開始配合的做自動化方面的轉(zhuǎn)變,從原來的黑盒系統(tǒng)級自動化測試向分層自動化測試轉(zhuǎn)變。

2. 分層自動化測試

在談分層測試之前,先回顧幾個概念:

  • 單元測試

    對軟件中的最小可測試單元進行檢查和驗證。具體的說就是開發(fā)者編寫的一小段代碼,用于檢驗被測代碼的一個很小的、很明確的功能是否正確。通常而言,一個單元測試是用于判斷某個特定條件(或者場景)下某個特定函數(shù)的行為。

  • 集成測試

    集成測試是在單元測試的基礎上,測試在將所有的軟件單元按照概要設計規(guī)格說明的要求組裝成模塊、子系統(tǒng)或系統(tǒng)的過程中各部分工作是否達到或?qū)崿F(xiàn)相應技術指標及要求的活動。也就是說,在集成測試之前,單元測試應該已經(jīng)完成。這一點很重要,因為如果不經(jīng)過單元測試,那么集成測試的效果將會受到很大影響,并且會大幅增加軟件單元代碼糾錯的代價。

  • 系統(tǒng)測試

    將需測試的軟件,作為整個基于計算機系統(tǒng)的一個元素,與計算機硬件、外設、某些支持軟件、數(shù)據(jù)和人員等其他系統(tǒng)元素及環(huán)境結(jié)合在一起測試。系統(tǒng)測試的目的在于通過與系統(tǒng)的需求定義作比較,發(fā)現(xiàn)軟件與系統(tǒng)定義不符合或與之矛盾的地方。


接下來我們談談有贊是如何隨著系統(tǒng)拆分SOA服務化推進分層自動化測試的。先來看看經(jīng)典的測試金字塔:

其中Unit代表單元測試,Service代表服務集成測試,UI代表頁面級的系統(tǒng)測試。分層的自動化測試倡導產(chǎn)品的不同層次都需要自動化測試,這個金字塔也正表示不同層次需要投入的精力和工作量。下面我會逐層介紹有贊的分層自動化實踐。

2.1 Unit-單元測試

在系統(tǒng)拆分之前,有贊只有一個龐大的巨無霸系統(tǒng),單元測試極度缺失。在系統(tǒng)逐漸SOA服務化的過程中,我們逐漸提出了對單元測試覆蓋率的要求。

我們的單元測試會分別做DAO層和服務層的測試。DAO層的單元測試主要保障SQL腳本的正確性,在做服務層的單元測試時就可以以DAO層是正確的前提進行用例編寫了。

為了做細粒度的測試,需要解決單元測試的外部依賴。系統(tǒng)和模塊之間的依賴可以通過Mock框架(Mockito/EasyMock)解耦,同時可以結(jié)合h2database解決對數(shù)據(jù)庫的依賴,使得測試用例盡可能做到可以隨時隨地運行。

這一層發(fā)現(xiàn)并解決問題付出的成本相對來說最低,自動化用例的維護成本也不高,總的來說自動化測試的投入產(chǎn)出比最高。

單元測試的責任主體一般來說是開發(fā)人員,寫單元測試也是開發(fā)人員對自己的代碼進行檢查的一個過程。

2.2 Service-服務集成測試

我們在服務層的測試首要考慮的是各系統(tǒng)(子系統(tǒng))的集成測試。因為在經(jīng)過單元測試這一層的保障之后,在服務層我們更關注的是某個系統(tǒng)的輸入輸出功能是否正確,以及若干個系統(tǒng)間的交互是否和業(yè)務場景的要求一致。

先來看看我們系統(tǒng)拆分之后的SOA系統(tǒng)應用架構(gòu)圖:

  • 展現(xiàn)層老的Iron應用,代碼為php。拆分之后iron只剩下和前端交互的展現(xiàn)層邏輯,以及調(diào)用核心業(yè)務的API層

  • 核心業(yè)務:Iron系統(tǒng)拆分出來的核心業(yè)務


這一層的被測對象是抽離了展現(xiàn)層的代碼(前端以及部分后端展現(xiàn)層邏輯)。

鑒于有贊的測試起步較晚(應該很多創(chuàng)業(yè)公司都有類似情況),測試資源緊缺,代碼覆蓋率低得可憐。所以我們的初期自動化用例覆蓋策略是這樣的:

  • 從老的Iron應用的API接口作為業(yè)務場景覆蓋的切入點

  • 優(yōu)先覆蓋核心業(yè)務的場景

  • 配合系統(tǒng)拆分,優(yōu)先覆蓋拆分出去的系統(tǒng)

  • 已拆分出去的系統(tǒng),做好系統(tǒng)服務層的測試覆蓋(全面覆蓋該服務的接口)

  • 測試依賴的數(shù)據(jù)準備優(yōu)先選擇調(diào)用系統(tǒng)接口的方式(為了增加業(yè)務覆蓋面)

  • 測試方式逐漸從黑盒向灰盒/白盒轉(zhuǎn)變
這樣做的好處是,可以快速增加業(yè)務場景的覆蓋面,同時事先準備好的API接口用例,可以作為系統(tǒng)拆分后的冒煙測試用例,起到核心老功能的回歸作用(只是做系統(tǒng)拆分,業(yè)務邏輯以及對展現(xiàn)層暴露的接口行為不變)。畢竟在自動化測試的過程中,最怕的就是變化,會帶來更多的腳本維護工作,而以這種方式覆蓋的用例,目前來看維護成本很低。

再介紹一下這一層的初期我們用例的基本形態(tài):

  • 專注于業(yè)務場景,和UI腳本一致,只是腳本從操作頁面變成了調(diào)用接口。相對于UI自動化,服務層的接口測試更加穩(wěn)定,測試用例也更容易維護。服務層接口測試可以更關注與系統(tǒng)整體的邏輯(業(yè)務)驗證,而UI自動化則會轉(zhuǎn)變?yōu)轫撁嬲故具壿嫾敖缑媲岸伺c服務的集成驗證(這個在UI層會介紹)。

  • 暫時不做系統(tǒng)間的Mock。更多的考慮系統(tǒng)之間的耦合和依賴。

  • 搭建MockServer解決系統(tǒng)的外部依賴,主要是類似于支付等第三方系統(tǒng)(關于我們的MockServer會有專門的文章介紹)。
結(jié)合我們的交易系統(tǒng)舉個例子:比如交易系統(tǒng)會依賴于商品和營銷活動,那我們的下單場景的用例會依次調(diào)用商品和營銷這幾個系統(tǒng)的API構(gòu)造數(shù)據(jù)作為用例的前置條件,然后按照下單的業(yè)務場景調(diào)用交易系統(tǒng)的下單接口,校驗返回值以及寫入DB的數(shù)據(jù),最后做好數(shù)據(jù)清理的工作。

我們在這一層的測試框架選擇是基于公司通用的服務框架(Nova)基礎之上搭建的,架構(gòu)圖如下:

BIT :服務接口集成測試(Business Interface&Integration Test)

SUT:被測系統(tǒng)(System Under Test)

  • Validator:各個業(yè)務的數(shù)據(jù)庫結(jié)果驗證封裝

  • Mock用例前置條件依賴的數(shù)據(jù)Mock服務

  • HttpClient根據(jù)IRON系統(tǒng)的接口封裝了返回通用的RPCResult對象

  • Util常用工具類封裝

  • Biz在此封裝了所有被測系統(tǒng)對外暴露的接口,供測試用例直接調(diào)用

  • TestCase我們服務接口測試又分為SDV(System design Verify-系統(tǒng)設計驗證)和SIT(System Integration Test-系統(tǒng)集成測試)。按照上面提到的用例覆蓋策略,我們是在系統(tǒng)拆分之前,先根據(jù)該系統(tǒng)的業(yè)務場景和REST接口補充核心的接口集成測試用例,后續(xù)可以作為系統(tǒng)拆分之后的冒煙用例。在系統(tǒng)拆分之后,詳細補充該系統(tǒng)的測試用例,粒度更細。

  • Facade:結(jié)合了Nova框架,對外發(fā)布各個業(yè)務的數(shù)據(jù)構(gòu)造的REST接口,同時可以作為測試數(shù)據(jù)構(gòu)造系統(tǒng),輔助測試人員的手工測試


這一層的測試覆蓋主要是由測試人員進行,是測試人員大展身手的地方。

我們不需要非常詳細的了解代碼的實現(xiàn),但是我們的用例里充分體現(xiàn)了我們對系統(tǒng)的結(jié)構(gòu),模塊之間關系等的充分的理解。

后續(xù)我們對于Service層自動化測試的推進策略是:

  • 逐漸豐富SDV層的測試用例,并且在一定程度上進行用例依賴的系統(tǒng)的解耦,比如數(shù)據(jù)構(gòu)造從調(diào)用接口向直接往數(shù)據(jù)庫寫入數(shù)據(jù)轉(zhuǎn)變。

  • 逐漸細化拆分業(yè)務場景,做好用例的解耦。

  • 優(yōu)先做場景覆蓋,之后再考慮代碼覆蓋。

2.3 UI-展現(xiàn)測試

先提一個問題,既然在文章開篇提到了UI自動化測試有這么多弊端,這么勞民傷財,那么是否還有必要進行UI層的自動化呢?答案是肯定的,因為UI層是我們的產(chǎn)品最終呈現(xiàn)給用戶的東西。所以在做好上面兩層的測試覆蓋之后,測試人員可以投入更多的精力到UI層的測試上。正是因為測試人員會在UI層投入較大精力,我們還是有必要通過自動化來幫助我們解放部分重復勞動力。

根據(jù)我們的UI層自動化實踐,提一下我們的UI層自動化覆蓋的原則:

  • 能在底層做自動化覆蓋,就盡量不在UI層做自動化覆蓋

  • 只做最核心的功能的自動化覆蓋,腳本可維護性盡可能提高

我們提高UI腳本可維護性的方法是遵循Page Object設計模式。

Page Object

Page Object模式是為了避免在測試代碼中直接操作HTML元素,對Web頁面的抽象。好處有:

  • 減少測試代碼的冗余

  • 提高測試代碼的可讀性和穩(wěn)定性

  • 提高測試代碼的可維護性

一個簡單的例子

以有贊首頁的登錄操作為例(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')
end
end
  • public方法對外暴露頁面的服務,對于登錄頁面來說就是登錄行為

  • 頁面的UI細節(jié)設為private方法對外隱藏

  • 跳轉(zhuǎn)到新的頁面后在此方法中return之后的頁面的對象,比如登錄之后跳轉(zhuǎn)到首頁(MainPage)。

    甚至同一頁面也可以返回self做鏈式操作。

  • 各個頁面的公共部分,如頁面頂部導航,可以封裝成Module供各個頁面對象直接include

下面我們來看看測試用例:

class TestLogin < Test::Unit::TestCase
def testLogin
@browser = Browser.new
@browser.goto 'youzan.com'
main_page = @browser.login_page.login('xx', '123')
#斷言
end
end

這樣最終的測試腳本呈現(xiàn)的就是單純的頁面操作邏輯,更貼近文本測試用例。

下面來看一下我們的測試框架:

  • Base這一層和大多數(shù)UI測試框架大同小異,使用的是selenium和watir,用例管理方面并沒有使用Ruby領域炙手可熱的BDD框架cucumber,而是最基本的單元測試框架MiniTest。同時還引入了ruby的多線程包,配合UI腳本的并發(fā)執(zhí)行。

  • Actir我們自己封裝的測試框架

    • Initializer:自動按照約定的工程結(jié)構(gòu)加載所有的ruby文件,并根據(jù)Page的類名和反射自動生成了所有頁面類的對象實例。

    • UA:封裝好測試需要的瀏覽器User-Agent。

    • Executor:用例執(zhí)行器。基于ruby的多線程包以及selenium-grid,實現(xiàn)了所有用例的調(diào)度及分布式執(zhí)行,可以一定程度上大大提升UI腳本的執(zhí)行效率。執(zhí)行器還包括了失敗用例重試機制。

    • Util:工具類,包括了配置文件讀寫、數(shù)據(jù)驅(qū)動等。

    • Report:根據(jù)UI測試腳本執(zhí)行的最終結(jié)果(失敗重試的用例以最終的結(jié)果為準)自動生成HTML格式的測試報告。

    • Cli:根據(jù)Actir框架的上述功能,封裝出的命令行工具,方便持續(xù)集成。

  • Project

    • Pages:基于PageObject模式包裝出的頁面的對象

    • Components:各個頁面的公用的部分或者插件,如圖片上傳、地址選擇等。包裝成Module供各個頁面對象需要時直接include。

    • Item:根據(jù)系統(tǒng)業(yè)務抽象出的對象,如訂單、優(yōu)惠券、商品等

    • User:根據(jù)系統(tǒng)業(yè)務抽象出的角色及其Action,如買家的購買行為、買家的退款、發(fā)貨等。


隨著服務層自動化覆蓋率越來越高,UI層的自動化覆蓋會逐漸轉(zhuǎn)變?yōu)轫撁嬲故具壿嫾敖缑媲岸伺c服務的展現(xiàn)層交互的集成驗證。我們后續(xù)對于UI層自動化的演進規(guī)劃是這樣的:

  • 依賴環(huán)境的Mock,解除UI腳本的外部依賴

  • 完善的數(shù)據(jù)準備,可以通過后端服務接口的mock使UI自動化更關注頁面業(yè)務邏輯的自動校驗。

  • 頁面截圖比對校驗UI樣式。

UI層的自動化測試也是由測試人員負責,在覆蓋了核心業(yè)務核心場景之后,不應該在這層的自動化覆蓋上投入太多的精力和資源。就算我們在一定程度上提高了腳本的可維護性,可是畢竟自動化測試最怕的就是變化,而UI界面是變化頻率最高的一層,所以還是得投入一定的精力維護,不是么?

3. 持續(xù)集成

有了上述各層的自動化測試腳本,下面我們需要建立起持續(xù)集成體系。持續(xù)集成的目的:

  • 流程自動化,提高工作效率

  • 最大化自動化測試腳本的價值

我們的持續(xù)集成是基于Jenkins搭建的,主要的動作如下:

  • 代碼提交自動執(zhí)行單元測試

  • 單元測試通過后自動部署整體的環(huán)境

  • 自動執(zhí)行集成自動化測試(Service/UI)

  • 自動生成構(gòu)建的詳細測試報告,同時自動通知相關人員

持續(xù)集成所需的支撐有:

  • 測試環(huán)境自動部署腳本

  • 代碼覆蓋率自動收集

    • Java應用 基于JaCoCo+Jenkins插件的方式

    • php應用 通Xdebug+phpunit的方式

  • 測試報告相關插件及腳本

  • 代碼靜態(tài)檢查等

對于持續(xù)集成我們后續(xù)的演進規(guī)劃是朝著持續(xù)交付和持續(xù)部署的方向努力,在持續(xù)集成的基礎之上,自動將代碼部署到測試環(huán)境上方便測試人員進行手工測試。

4. 總結(jié)

本文主要從整體上介紹了在有贊SOA化的進程中,測試推行的分層自動化實踐,以及后續(xù)的發(fā)展方向,同時簡單介紹了相關的測試框架結(jié)構(gòu)。下面再從整體回顧一下我們的分層自動化的要點:

  • 單元測試:

    • 優(yōu)先級最高

    • 粒度最細、覆蓋面最全

    • 開發(fā)實施

  • 服務測試

    • 對測試來說優(yōu)先級最高

    • 從業(yè)務場景的角度切入

    • 系統(tǒng)外部接口100%覆蓋

    • 關注系統(tǒng)間的依賴和調(diào)用

    • 測試實施

  • 頁面測試

    • 優(yōu)先級相對最低

    • 只保證核心功能的自動化覆蓋,只關注UI層的問題

    • 通過數(shù)據(jù)mock的方式減少對后臺數(shù)據(jù)的依賴。

    • 測試實施

至于各層投入的具體比重,還是需要根據(jù)項目的需求來實際規(guī)劃。在《google 測試之道》一書,對于google產(chǎn)品,70%的投入為單元測試,20%為集成、接口測試,10% 為UI層的自動化測試。

最后再提一些觀點吧:

  • 越底層的自動化,收益越高

  • 質(zhì)量不是測試人員一個人的事情

  • 自動化測試的目的不是為了減少手工測試,而是為了測試人員做更多更有意義的手工測試

本文來源:https://tech.youzan.com/layers_test_automation_practice/

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多