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

iOS9 UI Tests探索筆記

移動(dòng)開發(fā) iOS
在實(shí)際的開發(fā)過(guò)程中,隨著項(xiàng)目越做越大,功能越來(lái)越多,僅僅靠人工操作的方式來(lái)覆蓋所有測(cè)試用例是非常困難的,尤其是加入新功能以后,舊的功能也要重新測(cè)試一遍,這導(dǎo)致了測(cè)試需要花非常多的時(shí)間來(lái)進(jìn)行回歸測(cè)試,這里產(chǎn)生了大量重復(fù)的工作,而這些重復(fù)的工作有些是可以自動(dòng)完成的,這時(shí)候UI Tests就可以幫助解決這個(gè)問(wèn)題了。

UI Tests是什么?

UI Tests是一個(gè)自動(dòng)測(cè)試UI與交互的Testing組件

UI Tests有什么用?

它可以通過(guò)編寫代碼、或者是記錄開發(fā)者的操作過(guò)程并代碼化,來(lái)實(shí)現(xiàn)自動(dòng)點(diǎn)擊某個(gè)按鈕、視圖,或者自動(dòng)輸入文字等功能。

UI Tests的重要性

在實(shí)際的開發(fā)過(guò)程中,隨著項(xiàng)目越做越大,功能越來(lái)越多,僅僅靠人工操作的方式來(lái)覆蓋所有測(cè)試用例是非常困難的,尤其是加入新功能以后,舊的功能也要重新測(cè)試一遍,這導(dǎo)致了測(cè)試需要花非常多的時(shí)間來(lái)進(jìn)行回歸測(cè)試,這里產(chǎn)生了大量重復(fù)的工作,而這些重復(fù)的工作有些是可以自動(dòng)完成的,這時(shí)候UI Tests就可以幫助解決這個(gè)問(wèn)題了。

使用方法

***步:添加UI Tests

如果是新項(xiàng)目,則創(chuàng)建工程的時(shí)候可以直接勾選選項(xiàng),如下圖

如果是已有的項(xiàng)目,可以通過(guò)添加target的方式添加一個(gè)UI Tests,點(diǎn)擊xcode的菜單,找到target欄

在Test選項(xiàng)中選擇Cocoa Touch UI Testing Bundle

這時(shí)候test組件添加成功,它在項(xiàng)目中的位置如下圖所示

第二步:創(chuàng)建測(cè)試代碼

手動(dòng)創(chuàng)建測(cè)試代碼

打開測(cè)試文件,在testExample()方法中添加測(cè)試代碼

如果不知道如何寫測(cè)試代碼,則可以參考自動(dòng)生成的代碼樣式

自動(dòng)生成測(cè)試步驟

選擇測(cè)試文件后,點(diǎn)擊錄制按鈕

這時(shí)候開始進(jìn)行操作,它會(huì)記錄你的操作步驟,并生成測(cè)試代碼

下圖就是在一些操作后自動(dòng)生成的測(cè)試代碼

這時(shí)候可以分析測(cè)試代碼的語(yǔ)法,以便你自己手動(dòng)修改或者手寫測(cè)試代碼

開始測(cè)試

點(diǎn)擊testExample方法旁邊的播放按鈕,它就開始進(jìn)行自動(dòng)測(cè)試了,這時(shí)候你會(huì)看到app在自動(dòng)操作

 

下面介紹一下測(cè)試元素的語(yǔ)法

XCUIApplication:

繼承XCUIElement,這個(gè)類掌管應(yīng)用程序的生命周期,里面包含兩個(gè)主要方法

launch():

啟動(dòng)程序

terminate():

終止程序

XCUIElement:

繼承NSObject,實(shí)現(xiàn)協(xié)議XCUIElementAttributes, XCUIElementTypeQueryProvider

可以表示系統(tǒng)的各種UI元素

exist:

可以讓你判斷當(dāng)前的UI元素是否存在,如果對(duì)一個(gè)不存在的元素進(jìn)行操作,會(huì)導(dǎo)致測(cè)試組件拋出異常并中斷測(cè)試

descendantsMatchingType(type:XCUIElementType)->XCUIElementQuery:

取某種類型的元素以及它的子類集合

childrenMatchingType(type:XCUIElementType)->XCUIElementQuery:

取某種類型的元素集合,不包含它的子類

這兩個(gè)方法的區(qū)別在于,你僅使用系統(tǒng)的UIButton時(shí),用childrenMatchingType就可以了,如果你還希望查詢自己定義的子Button,就要用descendantsMatchingType

另外UI元素還有一些交互方法

tap(): 點(diǎn)擊

doubleTap(): 雙擊

pressForDuration(duration: NSTimeInterval): 長(zhǎng)按一段時(shí)間,在你需要進(jìn)行延時(shí)操作時(shí),這個(gè)就派上用場(chǎng)了

swipeUp(): 這個(gè)響應(yīng)不了pan手勢(shì),暫時(shí)沒(méi)發(fā)現(xiàn)能用在什么地方,也可能是beta版的bug,先不解釋

typeText(text: String): 用于textField和textView輸入文本時(shí)使用,使用前要確保文本框獲得輸入焦點(diǎn),可以使用tap()函數(shù)使其獲得焦點(diǎn)

XCUIElementAttributes協(xié)議

里面包含了UIAccessibility中的部分屬性

如下圖

可以方便你查看當(dāng)前元素的特征,其中identifier屬性可用于直接讀取元素,不過(guò)該屬性在UITextField中有bug,暫時(shí)不清楚原因

XCUIElementTypeQueryProvider協(xié)議

里面包含了系統(tǒng)中大部分UI控件的類型,可通過(guò)讀屬性的方式取得某種類型的UI集合

部分屬性截圖如下

創(chuàng)建Demo

首先創(chuàng)建一個(gè)登錄頁(yè)面

點(diǎn)擊login按鈕進(jìn)行登錄驗(yàn)證,點(diǎn)擊clear按鈕會(huì)清除文本

登錄成功后可以去到個(gè)人信息頁(yè)面

個(gè)人信息頁(yè)面如下

點(diǎn)擊modify按鈕可以修改個(gè)人信息,點(diǎn)擊Message按鈕可以查看個(gè)人消息

***是消息界面

登錄頁(yè)面的測(cè)試

輸入一個(gè)錯(cuò)誤的賬號(hào)

驗(yàn)證結(jié)果

關(guān)閉警告窗

清除輸入記錄

輸入一個(gè)正確的賬號(hào)

驗(yàn)證結(jié)果

進(jìn)入個(gè)人信息頁(yè)面

測(cè)試代碼如下:

  1. func testLoginView() { 
  2. let app = XCUIApplication() 
  3. // 由于UITextField的id有問(wèn)題,所以只能通過(guò)label的方式遍歷元素來(lái)讀取 
  4. let nameField = self.getFieldWithLbl("nameField"
  5. if self.canOperateElement(nameField) { 
  6. nameField!.tap() 
  7. nameField!.typeText("xiaoming"
  8. let psdField = self.getFieldWithLbl("psdField"
  9. if self.canOperateElement(psdField) { 
  10. psdField!.tap() 
  11. psdField!.typeText("1234321"
  12. // 通過(guò)UIButton的預(yù)設(shè)id來(lái)讀取對(duì)應(yīng)的按鈕 
  13. let loginBtn = app.buttons["Login"
  14. if self.canOperateElement(loginBtn) { 
  15. loginBtn.tap() 
  16. // 開始一段延時(shí),由于真實(shí)的登錄是聯(lián)網(wǎng)請(qǐng)求,所以不能直接獲得結(jié)果,demo通過(guò)延時(shí)的方式來(lái)模擬聯(lián)網(wǎng)請(qǐng)求 
  17. let window = app.windows.elementAtIndex(0
  18. if self.canOperateElement(window) { 
  19. // 延時(shí)3秒, 3秒后如果登錄成功,則自動(dòng)進(jìn)入信息頁(yè)面,如果登錄失敗,則彈出警告窗 
  20. window.pressForDuration(3
  21. // alert的id和labe都用不了,估計(jì)還是bug,所以只能通過(guò)數(shù)量判斷 
  22. if app.alerts.count > 0 { 
  23. // 登錄失敗 
  24. app.alerts.collectionViews.buttons["確定"].tap() 
  25. let clear = app.buttons["Clear"
  26. if self.canOperateElement(clear) { 
  27. clear.tap() 
  28. if self.canOperateElement(nameField) { 
  29. nameField!.tap() 
  30. nameField!.typeText("sun"
  31. if self.canOperateElement(psdField) { 
  32. psdField!.tap() 
  33. psdField!.typeText("111111"
  34. if self.canOperateElement(loginBtn) { 
  35. loginBtn.tap() 
  36. if self.canOperateElement(window) { 
  37. // 延時(shí)3秒, 3秒后如果登錄成功,則自動(dòng)進(jìn)入信息頁(yè)面,如果登錄失敗,則彈出警告窗 
  38. window.pressForDuration(3
  39. self.loginSuccess() 
  40. else { 
  41. // 登錄成功 
  42. self.loginSuccess() 

這里有幾個(gè)需要特別注意的點(diǎn):

1. 當(dāng)你的元素不存在時(shí),它仍然可能返回一個(gè)元素對(duì)象,但這時(shí)候不能對(duì)其進(jìn)行操作

2. 當(dāng)你要點(diǎn)擊的元素被鍵盤或者UIAlertView遮擋時(shí),執(zhí)行tap方法會(huì)拋異常

詳細(xì)實(shí)現(xiàn)可參照demo: https://github.com/sunGd/demo/tree/master/iOS9/UITestDemo

個(gè)人信息頁(yè)測(cè)試

修改性別

修改年齡

修改心情

保存修改

測(cè)試代碼如下:

  1. func testInfo() { 
  2. let app = XCUIApplication() 
  3. let window = app.windows.elementAtIndex(0
  4. if self.canOperateElement(window) { 
  5. // 延時(shí)2秒, 加載數(shù)據(jù)需要時(shí)間 
  6. window.pressForDuration(2
  7. let modifyBtn = app.buttons["modify"]; 
  8. modifyBtn.tap() 
  9. let sexSwitch = app.switches["sex"
  10. sexSwitch.tap() 
  11. let incrementButton = app.buttons["Increment"
  12. incrementButton.tap() 
  13. incrementButton.tap() 
  14. incrementButton.tap() 
  15. app.buttons["Decrement"].tap() 
  16. let textView = app.textViews["feeling"
  17. textView.tap() 
  18. app.keys["Delete"].tap() 
  19. app.keys["Delete"].tap() 
  20. textView.typeText(" abc "
  21. // 點(diǎn)擊空白區(qū)域 
  22. let clearBtn = app.buttons["clearBtn"
  23. clearBtn.tap() 
  24. // 保存數(shù)據(jù) 
  25. modifyBtn.tap() 
  26. window.pressForDuration(2
  27. let messageBtn = app.buttons["message"
  28. messageBtn.tap(); 
  29. // 延時(shí)1秒, push view需要時(shí)間 
  30. window.pressForDuration(1
  31. self.testMessage() 

這里需要特別注意以下兩點(diǎn):

1. textview獲取焦點(diǎn)時(shí)無(wú)法選擇焦點(diǎn)的位置

2. tap事件的觸發(fā)位置是view的中心,所以當(dāng)view的中心被遮擋時(shí),要考慮使用其他view來(lái)代替

個(gè)人消息界面測(cè)試

單元格的點(diǎn)擊

測(cè)試代碼如下:

  1. func testMessage() { 
  2. let app = XCUIApplication() 
  3. let window = app.windows.elementAtIndex(0
  4. if self.canOperateElement(window) { 
  5. // 延時(shí)2秒, 加載數(shù)據(jù)需要時(shí)間 
  6. window.pressForDuration(2
  7. let table = app.tables 
  8. table.childrenMatchingType(.Cell).elementAtIndex(8).tap() 
  9. table.childrenMatchingType(.Cell).elementAtIndex(1).tap() 

這里需要注意一點(diǎn):

1. 暫時(shí)無(wú)法獲取到tableView的元素指針

總結(jié)

總的來(lái)說(shuō),UI Tests只能用于一些基礎(chǔ)功能的測(cè)試,驗(yàn)證app的功能是否可以正常使用,是否存在崩潰問(wèn)題。但它也有很多不足之處,編寫測(cè)試用例的過(guò)程非常繁瑣,自動(dòng)生成的代碼幾乎無(wú)法運(yùn)行,功能單一,很多用例無(wú)法覆蓋,而且bug很多,大大地限制了UI Tests在實(shí)際開發(fā)中的應(yīng)用。希望正式版出來(lái)的時(shí)候能夠修復(fù)這些問(wèn)題,并開放更多的功能。

責(zé)任編輯:chenqingxiang 來(lái)源: CocoaChina
相關(guān)推薦

2015-07-16 12:59:19

IOS9UIDynamics

2015-10-16 14:27:29

iOS9collectionV特性

2015-11-04 09:54:34

ios9人機(jī)界面ui

2015-09-16 09:55:12

ios9學(xué)習(xí)UIKit Dynam

2015-07-21 16:43:13

IOSUI

2015-09-25 09:44:24

ios9MapkitTrans

2015-08-20 09:00:23

ios9api

2015-08-24 09:24:21

ios學(xué)習(xí)contacts fr

2016-03-18 11:19:57

ios9replaykit入門

2015-09-09 15:51:54

2015-11-11 10:17:15

ios9聯(lián)系人框架干貨

2015-09-10 09:31:43

IOS9IOS9.1

2015-08-24 09:19:05

ios9split scree

2015-09-16 09:02:10

IOS9新功能搜索業(yè)務(wù)

2015-10-20 09:36:52

蘋果iOS 9字體

2015-07-27 09:04:33

ios9

2015-05-19 09:51:57

WWDCiOS9

2015-10-29 11:13:23

iOS9使用框

2015-08-03 10:03:09

iosuistack vie

2015-05-28 23:29:01

xy
點(diǎn)贊
收藏

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