自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS UI 自動(dòng)化測(cè)試原理以及在 Trip.com 的應(yīng)用實(shí)踐

移動(dòng)開(kāi)發(fā) iOS 自動(dòng)化
筆者更深入地研究了 iOS 平臺(tái)下的自動(dòng)化測(cè)試技術(shù),目前也在負(fù)責(zé)部門(mén) App 自動(dòng)化測(cè)試平臺(tái)的搭建和維護(hù)。故想借這篇文章一并將所踩過(guò)的坑以及學(xué)習(xí)到的技術(shù),系統(tǒng)且全面地整理出分享給大家。

[[429539]]

前言

筆者入職 Trip.com 已滿一年,回顧這一年的工作歷程,約一半的時(shí)間都在做 UI 自動(dòng)化測(cè)試相關(guān)內(nèi)容。從而,筆者更深入地研究了 iOS 平臺(tái)下的自動(dòng)化測(cè)試技術(shù),目前也在負(fù)責(zé)部門(mén) App 自動(dòng)化測(cè)試平臺(tái)的搭建和維護(hù)。故想借這篇文章一并將所踩過(guò)的坑以及學(xué)習(xí)到的技術(shù),系統(tǒng)且全面地整理出分享給大家。

本文的內(nèi)容大致如下:

  • iOS/macOS UI 自動(dòng)化測(cè)試框架 XCUITest 原理詳解
  • 基于 Web Service 的自動(dòng)化測(cè)試平臺(tái)架構(gòu)設(shè)計(jì)
  • Appium 與 Macaca 介紹與對(duì)比
  • Trip.com App UI 自動(dòng)化測(cè)試現(xiàn)狀

自動(dòng)化測(cè)試可以分為白盒測(cè)試、黑盒測(cè)試以及灰盒測(cè)試,本文主要圍繞 Apple 官方提供的 XCUITest 測(cè)試框架,逐步闡明 iOS 操作系統(tǒng)下的 UI 自動(dòng)化測(cè)試原理、架構(gòu)設(shè)計(jì)思想以及應(yīng)用場(chǎng)景。

XCUITest 原理詳解

iOS UI自動(dòng)化測(cè)試核心技術(shù)

2015 年,Apple 發(fā)布了 UI 自動(dòng)化測(cè)試框架 XCUITest 并集成在 Xcode7 中,而 iOS/macOS UI 自動(dòng)化測(cè)試依賴兩個(gè)核心技術(shù):XCUITest 和 Accessibility。

XCUITest 是集成在 Xcode 中的測(cè)試框架,若想使用 UI 測(cè)試功能,可以在創(chuàng)建 iOS 項(xiàng)目時(shí)勾選 Include Tests 選項(xiàng),從而使項(xiàng)目具備自動(dòng)化測(cè)試的能力。而 Accessibility 技術(shù),則是 Apple 官方為視障用戶提供的一整套使用 iOS/macOS App 的解決方案。

Xcode 項(xiàng)目創(chuàng)建 UITests Target 并運(yùn)行測(cè)試,其編譯產(chǎn)物 Test App 本質(zhì)上是一個(gè) Deamon 守護(hù)進(jìn)程,該進(jìn)程有獨(dú)立的應(yīng)用程序生命周期,依靠 XCUIApplication 類型進(jìn)行管理。UITests 的 Test App 進(jìn)程在運(yùn)行時(shí)會(huì)驅(qū)動(dòng) Host App(項(xiàng)目的主 Target 產(chǎn)物),并且利用元素審查的相關(guān) API 驅(qū)動(dòng) Host App 模擬用戶行為交互,從而進(jìn)行 UI 自動(dòng)化測(cè)試。

對(duì)于 Accessibility 技術(shù),開(kāi)發(fā)人員需要注意的是,XCUITest 框架默認(rèn)并不能將所有視圖元素審查到,只會(huì)審查到可以被 VoiceOver 功能讀取文字的元素。比如,UIButton 和 UILabel,這些視圖對(duì)于視障用戶而言可以通過(guò)語(yǔ)音來(lái)獲知其內(nèi)容,而對(duì)于 UIImageView、 UIView 這種對(duì)于視障人士并不友好的 UIKit 視圖元素默認(rèn)是不會(huì)審查到的,所以編碼時(shí)要另行配置 Accessibility 相關(guān)屬性,以保證其支持 Accessibility 從而在 UI 自動(dòng)化查詢的元素層級(jí)中可見(jiàn)。

基于 XCUITest 框架 和 Accessibility 技術(shù)的自動(dòng)化測(cè)試,有利于 App 進(jìn)行數(shù)據(jù)一致性校驗(yàn),但 UI 一致性校驗(yàn)?zāi)芰^弱。比如,App 可以針對(duì)某些數(shù)據(jù)請(qǐng)求結(jié)果或者某個(gè)元素是否存在進(jìn)行校驗(yàn),而視覺(jué)展示效果卻仍需要人工介入。

XCUITest 框架結(jié)構(gòu)

XCUITest 測(cè)試框架 API 主要包含:元素查詢(UI Element Queries)相關(guān)類型,如 XCUIElementQuery,UI 元素(UI Elements)相關(guān)類型,如 XCUIElement,以及測(cè)試 App 生命周期類型(Application Lifecycle)類型,如 XCUIApplication。

接下來(lái),我們創(chuàng)建一個(gè)簡(jiǎn)單 Demo 項(xiàng)目,來(lái)學(xué)習(xí)如何使用 XCUITest 框架編程,并進(jìn)行 iOS UI 自動(dòng)化測(cè)試。

利用 Xcode UITests Target 進(jìn)行自動(dòng)化測(cè)試

創(chuàng)建一個(gè) Demo 工程,勾選 Include Tests 選項(xiàng),在 ViewController 里編寫(xiě)如下代碼。本文 Demo 工程可訪問(wèn)鏈接 https://github.com/niyaoyao/UITestDemo 。

  1. import UIKit 
  2.  
  3. class ViewController: UIViewController { 
  4.     lazy var testImageView: UIImageView = { 
  5.         let testImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) 
  6.         testImageView.backgroundColor = .red 
  7.         testImageView.accessibilityIdentifier = "test imageview" 
  8.         return testImageView 
  9.     }() 
  10.     lazy var testLabel: UILabel = { 
  11.         let testLabel = UILabel(frame: CGRect(x: 0, y: 130, width: 100, height: 20)) 
  12.         testLabel.backgroundColor = .green 
  13.         testLabel.text = "test label" 
  14.         return testLabel 
  15.     }() 
  16.     lazy var testView: UIView = { 
  17.         let testView = UIView(frame: CGRect(x: 0, y: 170, width: 100, height: 50)) 
  18.         testView.backgroundColor = .blue 
  19.         testView.accessibilityIdentifier = "test view" 
  20.         return testView 
  21.     }() 
  22.     lazy var testButton: UIButton = { 
  23.         let testButton = UIButton(frame: CGRect(x: 0, y: 230, width: 100, height: 50)) 
  24.         testButton.backgroundColor = .yellow 
  25.         testButton.setTitle("測(cè)試按鈕"for: .normal) 
  26.         return testButton 
  27.     }() 
  28.      
  29.     override func viewDidLoad() { 
  30.         super.viewDidLoad() 
  31.         view.addSubview(testImageView) 
  32.         view.addSubview(testLabel) 
  33.         view.addSubview(testView) 
  34.         view.addSubview(testButton) 
  35.     } 

源碼解釋,上面的這段代碼創(chuàng)建了四個(gè)視圖實(shí)例,分別為 UIImageView、UILabel、UIView 和 UIButton 類型,并將四個(gè)視圖實(shí)例添加到當(dāng)前頁(yè)面中。其中,UILable 和 UIButton 僅設(shè)置了frame、字符串、背景顏色等屬性,但是對(duì)于 UIImageView 和 UIView 視圖除了一般的視圖屬性,還設(shè)置了 accessibilityIdentifier 個(gè)屬性是為了讓 UIImageView 和 UIView 支持 Accessibility 功能,但僅設(shè)置這個(gè)屬性并不能使這兩個(gè)視圖在 Accessibility 的元素層級(jí)結(jié)構(gòu)中可見(jiàn)。接下來(lái)就對(duì) Accessibility 功能做簡(jiǎn)要介紹。

讓 App 支持輔助功能

使用 Accessibility Inspector

前文中提到 Apple 對(duì)于視圖元素會(huì)默認(rèn)審查能夠通過(guò) VoiceOver 播放文字的視圖元素,而對(duì)于 UIImageView、UIView 這種默認(rèn)不支持 Accessibility 功能的需要配置相關(guān)特性,而開(kāi)發(fā)人員在開(kāi)發(fā)過(guò)程中可以通過(guò) Accessibility Inspector 查看不同進(jìn)程的 Accessibility 元素層級(jí),該應(yīng)用可以審查 iOS 和 macOS 的元素。

選擇 Xcode 的圖標(biāo)菜單并選擇 Open Developer Tool 選項(xiàng),點(diǎn)擊 Accessibility Inspector 即可開(kāi)始使用。

當(dāng)我們沒(méi)有設(shè)置 isAccessibilityElement 屬性時(shí),在 Accessibility 元素層級(jí)結(jié)構(gòu)中就無(wú)法看到 UIImageView 和 UIView 元素,只能看到 “test label” 和“測(cè)試按鈕”。而當(dāng)我們將 UIImageView 和 UIView 的 isAccessibilityElement 屬性設(shè)置為 true 時(shí), UIImageView 和 UIView 元素才能在元素層級(jí)中可見(jiàn)。

Accessibility 相關(guān)屬性

  1. UIAccessibility: var accessibilityLabel: String? { get set } 

accessibilityLabel 屬性可以解決絕大部分的 Accessibility 問(wèn)題,當(dāng)光標(biāo)將焦點(diǎn)放在設(shè)置該屬性的元素師時(shí),它的內(nèi)容可由 VoiceOver 讀取的人類可讀的字符串。但如果不是需要被視障用戶獲知的視圖元素,僅用于自動(dòng)化測(cè)試,就可以不用設(shè)置該屬性。

  1. UIAccessibility: var accessibilityIdentifier: String? { get set } 

accessibilityIdentifier 屬性不會(huì)被 VoiceOver 誦讀,而是面向開(kāi)發(fā)人員的字符串,可在不希望用戶操作 accessibilityLabel 的情況下使用。

  1. UIAccessibility: var isAccessibilityElement: Bool { get set } 

如果 isAccessibilityElement 未設(shè)置為 true,那么這個(gè)視圖將不會(huì)在 Accessibility 視圖層次結(jié)構(gòu)中可見(jiàn)。

  • The default value for this property is false unless the element is a standard UIKit control, in which case, the value is true. —— Apple Documentation

另外,根據(jù) Apple 官方中的介紹 UIControl 的子類的 isAccessibilityElement 屬性都默認(rèn)設(shè)置為 true。

手動(dòng)編寫(xiě)測(cè)試 case

  1. import XCTest 
  2.  
  3. class UITestDemoUITests: XCTestCase { 
  4.  
  5.     override func setUpWithError() throws { 
  6.         // ... 
  7.     } 
  8.  
  9.     override func tearDownWithError() throws { 
  10.         // Put teardown code here. This method is called after the invocation of each test method in the class. 
  11.     } 
  12.  
  13.     func testExample() throws { 
  14.         // UI tests must launch the application that they test. 
  15.         let app = XCUIApplication() 
  16.         app.launch() 
  17.         let label = app.staticTexts["test label"
  18.         XCTAssertTrue(label.exists) 
  19.         let button = app.buttons["測(cè)試按鈕"
  20.         XCTAssertTrue(button.exists) 
  21.         let imgview = app.images["test imageview"
  22.         XCTAssertTrue(imgview.exists) 
  23.         let view = app.otherElements["test view"
  24.         XCTAssertTrue(view.exists)   
  25.         // Use recording to get started writing UI tests. 
  26.         // Use XCTAssert and related functions to verify your tests produce the correct results. 
  27.     } 
  28.  
  29.     func testLaunchPerformance() throws { 
  30.         if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 
  31.             // This measures how long it takes to launch your application. 
  32.             measure(metrics: [XCTApplicationLaunchMetric()]) { 
  33.                 XCUIApplication().launch() 
  34.             } 
  35.         } 
  36.     } 

源碼解釋,XCUIApplication 類型的實(shí)例,是管理 Test App 生命周期的實(shí)例對(duì)象,可以通過(guò)該對(duì)象獲取 Accessibility 視圖層級(jí)結(jié)構(gòu),通過(guò) XCTAssertTrue 斷言元素是否存在。

錄制交互行為自動(dòng)生成測(cè)試 case

對(duì)于相對(duì)復(fù)雜的 Test Case,可以通過(guò) Xcode 提供的測(cè)試行為錄制功能進(jìn)行自動(dòng)代碼生成。

UITest 執(zhí)行過(guò)程

點(diǎn)擊 Test 定義的 function 前方對(duì)應(yīng)的播放按鈕或者 Test Navigator 中對(duì)應(yīng) function 的播放按鈕,就可以開(kāi)始執(zhí)行 UI 測(cè)試。而開(kāi)始 UI 測(cè)試后,會(huì)先執(zhí)行源碼編譯,將 Target 中的源碼編譯出產(chǎn)物,啟動(dòng) Test App 進(jìn)程,進(jìn)入 Test 程序執(zhí)行 app.launch() 則會(huì)啟動(dòng) App,然后執(zhí)行斷言源碼。

iOS 自動(dòng)化測(cè)試工具鏈

編寫(xiě)了基本的 UI 測(cè)試的 UITest Target 方法之后,我們可以利用相關(guān)命令行工具鏈,將 iOS UI 自動(dòng)化測(cè)試腳本化,從而可以方便集成入 CI 流程。

xcodebuild

  1. xcodebuild test -project UITestDemo.xcodeproj -scheme UITestDemoUITests -destination 'platform=iOS,id=<iPhoneUDID>' 

可以利用上述命令執(zhí)行自動(dòng)化測(cè)試,也可以將命令進(jìn)行拆分,拆分為測(cè)試編譯命令和測(cè)試執(zhí)行命令,以便細(xì)化自動(dòng)化測(cè)試過(guò)程。測(cè)試編譯命令:

  1. xcodebuild build-for-testing -project ****.xcodeproj -scheme **** -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,id=XXXXX' -derivedDataPath ~/derived_path -quiet COMPILER_INDEX_STORE_ENABLE=NO GCC_WARN_INHIBIT_ALL_WARNINGS=YES | tee build.log 

測(cè)試執(zhí)行命令:

  1. xcodebuild test-without-building -xctestrun ****.xctestrun -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,id=XXXXXX' -derivedDataPath ~/derived_path -resultBundlePath ****.xcresult -only-testing:****-UITests/TargetTests 

xcrun simctl

simctl 命令是 xcrun 的一套自命令,提供一系列用來(lái)控制 iOS 模擬器的命令。

列舉當(dāng)前已經(jīng)啟動(dòng)的模擬器 xcrun simctl list devices | grep booted

啟動(dòng)模擬器 xcrun simctl boot XXXXX

關(guān)閉模擬器 xcrun simctl shutdown XXXXX

設(shè)置模擬器權(quán)限 xcrun simctl privacy XXX grant location-always xx.xx.xxx

安裝 App xcrun simctl install {} {}'.format(uuid, app_path)

運(yùn)行指定 App xcrun simctl launch {} {}'.format(uuid, bundle_id)

結(jié)束指定 App xcrun simctl terminate {} {}'.format(uuid, bundle_id)

卸載指定 App xcrun simctl uninstall {} {}'.format(uuid, bundle_id)

ideviceinstaller

與控制模擬器相似,iOS 真機(jī)也有相應(yīng)的控制命令行工具鏈,例如 ideviceinstaller。

安裝 apppath 下的 app ideviceinstaller -i apppath

安裝 xxx.ipa 為應(yīng)用在本地的路徑ideviceinstaller -u [udid] -i [xxx.ipa]

卸載應(yīng)用 ideviceinstaller -u [udid] -U [bundleId]

查看設(shè)備安裝的第三方應(yīng)用 ideviceinstaller -u [udid] -l

同上,查看設(shè)備安裝的第三方應(yīng)用 ideviceinstaller -u [udid] -l -o list_user

查看設(shè)備安裝的系統(tǒng)應(yīng)用 ideviceinstaller -u [udid] -l -o list_system

查看設(shè)備安裝的所有應(yīng)用 ideviceinstaller -u [udid] -l -o list_all

列出手機(jī)上所有的用戶安裝的app ideviceinstaller -l

ios-deploy

查看當(dāng)前鏈接的設(shè)備 ios-deploy -c

安裝APP ios-deploy --[xxx.app]

卸載應(yīng)用 ios-deploy --id [udid] --uninstall_only --bundle_id [bundleId]

查看所有應(yīng)用 ios-deploy --id [udid] --list_bundle_id

查看應(yīng)用是否安裝 ios-deploy --id [udid] --exists --bundle_id

利用以上命令行工具鏈,就可將 UI 自動(dòng)化測(cè)試根據(jù)不同項(xiàng)目進(jìn)行自定義的腳本接入 CI 流程,比如接入 GitLab Pipelines 中,對(duì) code review、 merge request 等過(guò)程進(jìn)行干預(yù)。

基于 Web Service 的架構(gòu)設(shè)計(jì)

App 自動(dòng)化測(cè)試平臺(tái)的架構(gòu)設(shè)計(jì)

從前文中我們了解到,我們可以利用 Xcode 創(chuàng)建 UITest Target,編寫(xiě) UITest Case 測(cè)試腳本,輔以 xcodebuild 等相關(guān)命令工具鏈編寫(xiě)自動(dòng)化腳本,就能接入 CI/CD 流程,實(shí)現(xiàn) iOS App 的 UI 自動(dòng)化測(cè)試,從而達(dá)到釋放人力資源,降低人工測(cè)試的成本的目的。

但與此同時(shí),又有新的問(wèn)題出現(xiàn),那就是業(yè)務(wù)頻繁的迭代的情況下,我們寫(xiě)的 Test Case 腳本,很容易因?yàn)闃I(yè)務(wù)的改變而導(dǎo)致廢棄,測(cè)試腳本復(fù)用率低,又增加了開(kāi)發(fā)成本。如果不同系統(tǒng)平臺(tái)的 App,如,Android、iOS 甚至 Web App 能共用一套測(cè)試腳本,提高腳本復(fù)用率,會(huì)降低開(kāi)發(fā)成本,更有利于業(yè)務(wù)回歸。

除此之外,對(duì)于復(fù)雜業(yè)務(wù)的回歸測(cè)試,若希望提高大量測(cè)試 case 的業(yè)務(wù)回歸效率,必然要提高并發(fā)性,縮減測(cè)試時(shí)間。故在這樣的需求下, Facebook 團(tuán)隊(duì)就設(shè)計(jì)出了 Appium 這樣的基于 Web Service 的自動(dòng)化測(cè)試工具。類似 Appium 的測(cè)試工具還有阿里巴巴團(tuán)隊(duì)設(shè)計(jì)的 Macaca,這類測(cè)試工具的設(shè)計(jì)架構(gòu)如下圖可視。

基于 Web Service 的自動(dòng)化測(cè)試的架構(gòu)主要可以分為命令分發(fā)服務(wù) Web Service 模塊和 UI 測(cè)試驅(qū)動(dòng)模塊。

對(duì)于命令分發(fā)服務(wù)模塊,其任務(wù)是搭建通用測(cè)試 case 腳本與底層驅(qū)動(dòng)之間的通信橋梁,而 HTTP RESTful API 恰能滿足這樣跨平臺(tái)的需求。因此,Web Service 模塊需要搭建 HTTP Web Service 進(jìn)行命令轉(zhuǎn)發(fā),將自動(dòng)化測(cè)試中的 Test Case 腳本作為 Web Service 的 Client 端,向 Web Service 的 Server 端發(fā)送請(qǐng)求。而 Web Service 的 Server 接收到請(qǐng)求后,再將請(qǐng)求轉(zhuǎn)發(fā)到底層的 UI 測(cè)試的驅(qū)動(dòng)進(jìn)程,以便后續(xù)驅(qū)動(dòng) UI 測(cè)試。

對(duì)于 UI 測(cè)試驅(qū)動(dòng)模塊,其主要任務(wù)是,接收 Web Service Server 端轉(zhuǎn)發(fā)來(lái)的請(qǐng)求,并觸發(fā)驅(qū)動(dòng)進(jìn)程進(jìn)行 UI 自動(dòng)化測(cè)試,最終收集測(cè)試結(jié)果,并生成測(cè)試報(bào)告。Android 操作系統(tǒng)的底層驅(qū)動(dòng)一般是 UIAutomator 程序;而對(duì)于 iOS 系統(tǒng), Appium 用的是 WebDriverAgent,Macaca 是 XCTestWD。而不論 WebDriverAgent 還是 XCTestWD 都是一個(gè)基于 XCUITest 的 Xcode project,其技術(shù)核心也就是我們前文介紹的以 XCUITest 和 Accessibility 為基礎(chǔ)的 iOS UI 自動(dòng)化測(cè)試技術(shù)。

App 自動(dòng)化測(cè)試平臺(tái),需要先運(yùn)行 Web Service Server,Server 作為測(cè)試指令的發(fā)出者,向測(cè)試驅(qū)動(dòng)發(fā)出請(qǐng)求,從而驅(qū)動(dòng) Test App 進(jìn)程操作 App。因此,需要先在 Jenkins Slave 機(jī)器啟動(dòng)運(yùn)行 Web Service Server,例如,在本地 4722 端口創(chuàng)建 Web Service,并監(jiān)聽(tīng) Client 向該端口發(fā)送的請(qǐng)求,再轉(zhuǎn)發(fā)給驅(qū)動(dòng)層。

驅(qū)動(dòng)項(xiàng)目(WebDriverAgent 或 XCTestWD)編譯成功后,都會(huì)在運(yùn)行的設(shè)備上創(chuàng)建并運(yùn)行一個(gè) Runner 程序,該程序就是利用 XCUITest 編譯成 Test App,但與前文 Demo 不同的是,這個(gè)程序會(huì)在設(shè)備上也會(huì)創(chuàng)建一個(gè) Web Service,接收 Server 發(fā)來(lái)的請(qǐng)求,并根據(jù) Test App 中程序處理請(qǐng)求,最后返回響應(yīng)結(jié)果給 Server。

例如,創(chuàng)建測(cè)試 Session 過(guò)程,WebDriverAgent 編譯成功后會(huì)在測(cè)試設(shè)備的 8080 端口創(chuàng)建 Web Service,從而 Jenkins Slave 上運(yùn)行的 Web Service Server 能夠?qū)?Client 的請(qǐng)求轉(zhuǎn)發(fā)給 WebDriverAgent 創(chuàng)建的 Web Service,然后經(jīng)過(guò) WebDriverAgent 的內(nèi)部路由/wd/hub/session 進(jìn)行映射,找到對(duì)應(yīng)創(chuàng)建 session 的具體代碼,保存 Session ID 值,并將 Session ID 作為響應(yīng)結(jié)果返回給 Jenkins 的 Web Server。其他測(cè)試操作如,查找 element、查找元素 value,滾動(dòng)某個(gè)元素等操作,這些操作 Jenkins 的 Web Service C/S 和底層驅(qū)動(dòng)間的通信過(guò)程,都與建立 Session 過(guò)程相類似。

所以,有了基于 Web Service 的 UI 自動(dòng)化測(cè)試工具,我們可以更加高效地進(jìn)行自動(dòng)化測(cè)試,復(fù)用性更高、可支持多平臺(tái),跨平臺(tái)測(cè)試,甚至可以利用其 Web Service 搭建分布式的測(cè)試平臺(tái),基于 Jenkins 服務(wù)的架構(gòu)設(shè)計(jì)如下圖所示。

根據(jù)上圖架構(gòu)設(shè)計(jì),我們可以利用多臺(tái)機(jī)器搭建 Jenkins 集群,根據(jù)我們 CI/CD 流程所需,向 Jenkins Server 發(fā)送請(qǐng)求,再由 Jenkins Server 分配不同 Jenkins Slave 執(zhí)行 Job,每個(gè) Jenkins Slave 都配置好 UI 自動(dòng)化測(cè)試平臺(tái)驅(qū)動(dòng)多臺(tái)設(shè)備進(jìn)行自動(dòng)化測(cè)試。從而實(shí)現(xiàn)分布式的自動(dòng)化測(cè)試平臺(tái),提高并發(fā)性、提升測(cè)試效率,縮減回歸測(cè)試的時(shí)間。

接下來(lái)就分別介紹 Appium 和 Macaca 的簡(jiǎn)單使用。

Appium 工具鏈矩陣

WebDriverAgent

WDA 是 Facebook 基于 XCUITest 測(cè)試框架開(kāi)發(fā)的 iOS UI 自動(dòng)測(cè)試 Driver。類比 Macaca Runner。

源碼安裝 WDA

  1. git clone https://github.com/appium/WebDriverAgent.git 

真機(jī)測(cè)試修改 Team ID

選擇 Apple 開(kāi)發(fā)賬號(hào)的 Team。

Appium Web Service Server

Appium Server 用于 HTTP 命令轉(zhuǎn)發(fā),驅(qū)動(dòng)底層 Driver WDA。

利用 Appium Desktop 啟動(dòng) Server

下載鏈接 https://github.com/appium/appium-desktop/releases/download/v1.21.0/Appium-mac-1.21.0.dmg

安裝 Appium App,并用 GUI App 啟動(dòng) Server。

利用 Appium Command 啟動(dòng) Server

安裝 Nodejs 依賴

執(zhí)行命令行

  1. npm install -g appium 

啟動(dòng) Server

執(zhí)行命令行

  1. appium -a 127.0.0.1 -p 4722 

參數(shù)列表:http://appium.io/docs/en/writing-running-appium/server-args/index.html

端口映射

執(zhí)行命令行

  1. iproxy [LOCAL_TCP_PORT] [DEVICE_TCP_PORT] 

http://manpages.ubuntu.com/manpages//trusty/man1/iproxy.1.html

https://github.com/libimobiledevice/libusbmuxd/blob/master/tools/iproxy.c

端口映射關(guān)系

執(zhí)行命令行

  1. appium -a 127.0.0.1 -p 4722 --webdriveragent-port 8123 

如果啟動(dòng) appium server 時(shí)設(shè)置了 WDA 的 Port 為 8123,則 iproxy 命令第一個(gè)入?yún)㈨毷潜镜乇O(jiān)聽(tīng)端口可任意隨機(jī)選擇,第二個(gè)入?yún)⒈仨殞?duì)應(yīng) appium 命令指定的 WDA 的端口,可如下執(zhí)行

  1. iproxy 8100 8123 

驅(qū)動(dòng) Runner 存儲(chǔ)位置

全局安裝 appium server 到本地后,WebDriverAgent.xcodeproj 存儲(chǔ)在以下路徑中。

  1. /usr/local/lib/node_modules/appium/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj 

Web Service Client —— Test Case

測(cè)試項(xiàng)目

https://github.com/appium/appium/tree/master/sample-code

javascript-webdriverio

安裝依賴

執(zhí)行命令行

  1. cd appium-master/sample-code/javascript-webdriverio 
  2. npm install 

修改配置

修改測(cè)試腳本中 capabilities 配置。

  1. const iosCaps = { 
  2.   platformName: 'iOS'
  3.   automationName: 'XCUITest'
  4.   deviceName: process.env.IOS_DEVICE_NAME || 'iPhone'
  5.   udid: 'iphone udid'
  6.   platformVersion: process.env.IOS_PLATFORM_VERSION || '13.6.1'
  7.   noReset: true
  8.   bundleId: 'your app id'
  9.   app: undefined // Will be added in tests 
  10. }; 

capabilities 文檔 https://appium.io/docs/en/writing-running-appium/caps/

https://appium.io/docs/en/writing-running-appium/default-capabilities-arg/

運(yùn)行 Case

執(zhí)行命令行

  1. npm test 

Macaca 工具鏈矩陣

與 Appium 相類似,Macaca 的工具鏈矩陣也包含 Driver、Web Service Server 和 Web Service Client。

安裝 Macaca 工具鏈

  1. # 本地安裝 
  2. $ npm i macaca-ios --save-dev 
  3. # 全局安裝 
  4. $ npm i macaca-ios -g 
  5. # 安裝有 TEAM_ID 的 macaca-ios 
  6. $ DEVELOPMENT_TEAM_ID=TEAM_ID npm i macaca-ios -g 

更多詳細(xì)安裝過(guò)程可參閱官方文檔 https://macacajs.github.io/zh/guide/environment-setup.html#%E5%AE%89%E8%A3%85-node-js

Appium 與 Macaca 的對(duì)比

框架名稱相同點(diǎn)不同點(diǎn)

我們的 UI 自動(dòng)化測(cè)試平臺(tái)最初僅接入 Macaca 框架,獨(dú)立維護(hù)一份倉(cāng)庫(kù)以供內(nèi)部平臺(tái)使用。而維護(hù)過(guò)程中也會(huì)遇到各種問(wèn)題并自行解決,驗(yàn)證無(wú)誤后也會(huì)反饋給官方,并提供相應(yīng)解決方案。目前也已開(kāi)始逐步接入 Appium 框架對(duì)現(xiàn)有平臺(tái)進(jìn)行技術(shù)改造,以適應(yīng)更多場(chǎng)景,以及保障框架長(zhǎng)期穩(wěn)定可持續(xù)地維護(hù)。

Trip.com App 自動(dòng)化測(cè)試現(xiàn)狀

Trip.com App 在日常開(kāi)發(fā)迭代過(guò)程中, UI 自動(dòng)化測(cè)試的應(yīng)用場(chǎng)景有很多,例如冒煙測(cè)試、探索測(cè)試,以及基于 Web Service 的 UI 自動(dòng)化測(cè)試平臺(tái)。接下來(lái),向大家分別介紹不同測(cè)試在 CI/CD 中扮演的角色和作用。

應(yīng)用場(chǎng)景

冒煙測(cè)試

基本概況

  • 在程序設(shè)計(jì)和軟件測(cè)試領(lǐng)域 , 冒煙測(cè)試 (也包括信心測(cè)試 、健全性測(cè)試、 [1] 構(gòu)建驗(yàn)證測(cè)試 ( BVT ) [2] [3]、構(gòu)建驗(yàn)收測(cè)試 )是指初步地進(jìn)行測(cè)試,并以此展示一些簡(jiǎn)單但足以影響發(fā)布軟件版本的這一高級(jí)別的錯(cuò)誤。—— Wikipedia

在 Trip.com 實(shí)際應(yīng)用場(chǎng)景中,冒煙測(cè)試所擔(dān)任的角色主要是 Merge Request 卡點(diǎn)檢測(cè),其主要作用是對(duì) Trip.com App 的集成編譯以及運(yùn)行時(shí)閃退的預(yù)先校驗(yàn)。比如,對(duì)于多模塊并行開(kāi)發(fā)的情況下,不同團(tuán)隊(duì)的某些改動(dòng)就會(huì)造成符號(hào)名找不到的問(wèn)題,而冒煙測(cè)試就可以預(yù)先對(duì)此進(jìn)行卡點(diǎn),避免集成打包失敗降低試錯(cuò)成本和時(shí)間成本。

而對(duì)于 Trip.com iOS 的冒煙測(cè)試具體實(shí)踐,就是在主項(xiàng)目中創(chuàng)建 UITest Target 編寫(xiě)簡(jiǎn)單的 UI 視圖校驗(yàn)程序,并接入 GitLab Runner Pipeline,利用 xcodebuild 工具鏈對(duì)編譯過(guò)程和運(yùn)行時(shí)健壯性進(jìn)行初步校驗(yàn),以保證合入主分支的代碼,不會(huì)使 App 出現(xiàn)明顯的重大閃退等問(wèn)題。

數(shù)據(jù)體現(xiàn)

冒煙測(cè)試在 Trip.com 快速迭代開(kāi)發(fā)的過(guò)程中,作為 Merge Request 的卡點(diǎn)任務(wù),利用多臺(tái) GitLab Runner 實(shí)現(xiàn)并發(fā)執(zhí)行六個(gè)冒煙測(cè)試任務(wù),大大縮減了卡點(diǎn)校驗(yàn)的時(shí)間,單個(gè)冒煙測(cè)試時(shí)間控制在 6min 之內(nèi),不僅達(dá)到了驗(yàn)證集成包的編譯構(gòu)建和健壯性的目的,還大大節(jié)省了測(cè)試驗(yàn)證的時(shí)間成本。

探索測(cè)試

基本概況

探索性測(cè)試(Exploratory Testing)是軟件測(cè)試方法的一種,它的特點(diǎn)為在進(jìn)行測(cè)試時(shí),同時(shí)探索開(kāi)發(fā)更多不同型態(tài)的測(cè)試方式,以便改善測(cè)試流程。—— Wikipedia

探索測(cè)試在 Trip.com App 實(shí)際應(yīng)用場(chǎng)景中,主要擔(dān)任的角色是 App 頁(yè)面隨機(jī)測(cè)試,主要用于驗(yàn)證集成打包 App 的質(zhì)量,隨機(jī)點(diǎn)擊頁(yè)面,并收集和統(tǒng)計(jì) Page View 以及 Crash 數(shù)據(jù),最終整理成報(bào)告發(fā)給相關(guān)開(kāi)發(fā)同學(xué)。

Trip.com iOS 探索測(cè)試是基于 Google eDistantObject 和 EarlGrey 開(kāi)源項(xiàng)目開(kāi)發(fā)的白盒/灰盒 UI 測(cè)試框架。區(qū)別于 XCUITest 編寫(xiě) Test Case 并且必須結(jié)合 Accessibility 的測(cè)試方式,白盒/灰盒的探索測(cè)試框架,則是利用 Test App 和 Host App 進(jìn)程間通信,使 Test App 驅(qū)動(dòng) Host App 進(jìn)行 UI 自動(dòng)化測(cè)試,而 App 的元素審查、用戶交互以及數(shù)據(jù)收集則都是在 Host App 進(jìn)程中完成。 沒(méi)有了 Accessibility 的限制,白盒/灰盒的探索測(cè)試元素審查更全面,穩(wěn)定性更高,測(cè)試數(shù)據(jù)也相應(yīng)更全面。

數(shù)據(jù)體現(xiàn)

Trip.com 探索測(cè)試是用于驗(yàn)證 App 集成包穩(wěn)定性的日常 Jenkins 任務(wù),收集全部觸達(dá)頁(yè)面,可有效預(yù)先發(fā)現(xiàn) Crash 問(wèn)題,并發(fā)送測(cè)試結(jié)果的報(bào)告郵件給研發(fā)組。iOS 的探索測(cè)試在并發(fā)數(shù)為 5 的情況下,2 小時(shí)測(cè)試有效觸達(dá)非重復(fù)頁(yè)面可達(dá) 180 個(gè),場(chǎng)景涉及首頁(yè) Feed 流、玩樂(lè)旅拍、訂單頁(yè)面等場(chǎng)景。探索測(cè)試收集的 Crash 問(wèn)題,會(huì)收集崩潰調(diào)用棧整理成表格,分配給相關(guān)研發(fā)同學(xué),推動(dòng)產(chǎn)線修改相關(guān)問(wèn)題代碼。

UI 自動(dòng)化測(cè)試平臺(tái)

基本概況

Trip.com App UI 自動(dòng)化測(cè)試平臺(tái),是由 IBU 公共測(cè)試團(tuán)隊(duì)和 IBU 公共無(wú)線共同設(shè)計(jì)搭建的可視化、數(shù)據(jù)統(tǒng)一管理的質(zhì)量保證平臺(tái)。在 App 快速迭代的開(kāi)發(fā)過(guò)程中,為提高測(cè)試效率,利用多臺(tái)機(jī)器,搭建 Jenkins 集群,實(shí)現(xiàn)用例并發(fā)執(zhí)行 Case,進(jìn)行 App 回歸測(cè)試,減少人力測(cè)試成本,并將測(cè)試問(wèn)題報(bào)告反饋給相關(guān)開(kāi)發(fā)同學(xué),推動(dòng)開(kāi)發(fā)同學(xué)完善功能,從而,保證 App 上線前的質(zhì)量。而選用的測(cè)試框架主要是 Macaca,并且將逐步向 Appium 遷移改造。

數(shù)據(jù)體現(xiàn)

UI 自動(dòng)化平臺(tái)目前處于開(kāi)發(fā)的一階段,日?;貧w測(cè)試中,對(duì)于復(fù)雜業(yè)務(wù)場(chǎng)景的測(cè)試,機(jī)器性能穩(wěn)定且并發(fā)數(shù)目 6 的情況下,測(cè)試總耗時(shí)可控制在 40 分鐘,測(cè)試總用例數(shù)可達(dá) 209 個(gè),Step總數(shù) 3077 步,F(xiàn)eature 通過(guò)率達(dá) 97.14% ,Case 通過(guò)率達(dá) 98.56%。

以上不同的自動(dòng)化測(cè)試應(yīng)用實(shí)踐,接入不同的 CI/CD 流程中,都為 Trip.com App 快速開(kāi)發(fā)迭代過(guò)程中提供了質(zhì)量保證。

總結(jié)

對(duì)于 iOS 平臺(tái)下的 UI 自動(dòng)化測(cè)試技術(shù),Apple 官方提供的兩個(gè)核心技術(shù)是 XCUITest 和 Accessibility。而為了能夠增強(qiáng)復(fù)用性,更利于分布式進(jìn)行自動(dòng)化測(cè)試,不同廠商又在此基礎(chǔ)上設(shè)計(jì)實(shí)現(xiàn)了基于 Web Service 的自動(dòng)化測(cè)試平臺(tái),優(yōu)點(diǎn)是具有易部署、跨平臺(tái)等特性,可以更大程度上利用分布式增強(qiáng)并發(fā)性,提高測(cè)試效率,減少人力測(cè)試成本。

當(dāng)然,市面上 UI 自動(dòng)化框架還有很多,例如 STF 和 Airtest,這類框架底層驅(qū)動(dòng)利用圖形圖像識(shí)別進(jìn)行 App 元素的定位。而對(duì)于目前 Trip.com iOS 的自動(dòng)化測(cè)試應(yīng)用實(shí)踐,則更多是基于 XCUITest 框架實(shí)現(xiàn)的,所以本文暫不討論此類測(cè)試框架。但不論何種驅(qū)動(dòng)進(jìn)行 App 的自動(dòng)化測(cè)試,整體的架構(gòu)設(shè)計(jì)都會(huì)以文中介紹的 Web Service 進(jìn)行設(shè)計(jì),以達(dá)到跨平臺(tái)、易集成、高復(fù)用等目的。

本文轉(zhuǎn)載自微信公眾號(hào)「Swift社區(qū)」

 

責(zé)任編輯:姜華 來(lái)源: Swift社區(qū)
相關(guān)推薦

2022-04-14 18:01:24

QUICTrip.com服務(wù)端

2024-07-17 09:22:17

2021-09-03 09:56:18

鴻蒙HarmonyOS應(yīng)用

2011-04-18 12:52:37

自動(dòng)化測(cè)試功能測(cè)試軟件測(cè)試

2012-05-08 16:40:36

Android

2011-10-11 09:56:59

PhoneGapSelenium

2019-07-18 11:00:45

自動(dòng)化運(yùn)維測(cè)試

2024-05-06 08:08:31

2011-06-03 17:24:48

自動(dòng)化測(cè)試

2009-12-23 16:33:34

WPF UI自動(dòng)化測(cè)試

2020-08-03 15:40:57

Web自動(dòng)化工具測(cè)試

2012-03-29 10:57:12

Web自動(dòng)化測(cè)試

2017-04-10 12:25:32

iOS自動(dòng)化測(cè)試

2022-09-12 16:02:32

測(cè)試企業(yè)工具

2021-06-30 19:48:21

前端自動(dòng)化測(cè)試Vue 應(yīng)用

2016-09-07 13:49:11

AppiumAndroid UI應(yīng)用

2022-02-16 09:01:13

iOSS開(kāi)發(fā)XCode

2014-04-16 14:15:01

QCon2014

2021-06-26 07:40:21

前端自動(dòng)化測(cè)試Jest

2024-01-08 13:31:00

Rust自動(dòng)化測(cè)試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)