iOS UITest 自動化測試開發

關于iOS的UI自動化測試,是從Xcode7之后才支持的比較好,使用XCTest.framework,Xcode可以自動錄制UI測試的動作流,還有就是可以使用XCTest UI testing API。

本文主要講的是如何進行自動化測試的開發,即XCTest UI testing API的使用

Unit Tests選項,就是測試業務邏輯等單元測試

UI Tests選項,才是我們要重點講的UI自動化測試

在創建項目的時候,這兩個建議都勾選上。

1.核心的三個類

XCUIApplication

XCUIElement

XCUIElementQuery

1.1 XCUIApplication類是Application的代理,就像我們項目工程中的AppDelegate,這個對象用來啟動或者是終止UI測試程序,還可以在啟動的時候設置一些啟動參數,在獲取程序中的UI元素的時候,就是通過這個類的實例。這個類繼承自XCUIElement類

1.2? XCUIElement類是XCTest.framework對應用中的所有UI控件的抽象,在UI測試中,沒有UIKit中的UI類型,只是用這個類的實例表示所有的UI控件,以及相應的交互方法,例如:執行手勢(tap,press,swipe),滑動控件交互,拾取器交互,這個類采取了XCUIElementAttributes協議(描述UI元素的屬性:Identity,Value,Interaction State,Size),XCUIElementTypeQueryProvider協議(為指定類型的子代元素提供ready-made查詢,子代元素查詢包含button,具體實現是:@property(readonly, copy) XCUIElementQuery *buttons;等一系列對UIKit中元素的映射)

1.3 XCUIElementQuery類是定位UI元素的查詢,這個類使用類似key-value的機制得到XCUIElement的實例,使用Type(XCUIElementType枚舉),Predicate,Identifier創建query,使用elementAtIndex:, elementMatchingPredicate,elementMatchingType: identifier:方法訪問匹配到的UI元素,此類采用XCUIElementTypeQueryProvider協議





此處原文 鏈接:http://www.itnose.net/detail/6507467.html

1. 單元測試簡介

1.1 ?UnitTest: 單元測試

單元是指應用程序中可以測試的最小單元。測試源代碼,一般要求有明確的輸入與輸出。因此一般來說源代碼中明確的包含輸入輸出的每一個方法被認為一個測試的單元(一個case)。當然,這里的輸出并不局限于方法的返回值對輸入參數的改變,也包括方法在執行過程中改變的任何數據。

單元測試在程序里面可以理解一個模塊一個方法,在每個可能存在的模塊都進行測試,確保每個模塊都沒有問題,從而提高整體程序的質量。

1.2 ?單元測試的目的

我們進行單元測試的目的是將程序中所有的源代碼劃分成最小的單元進行測試,來確保每個單元的正確性,如果每個單元都能保證正確,就能保證應用程序整體相當程度的正確性。另一方面測試腳本本身就是被測試代碼的實際使用代碼,這對于開發者理解被測試單元的使用是用幫助的。

測試是分黑盒測試和白盒測試(概念此處不在解釋),單元測試其實就是一種白盒測試,開發者對現有已經實現的模塊自己寫對應測試腳本進行測試,這中間還包含測試用例的設計。相對來說還是由開發者自己來完成白盒測試,然后在交由測試團隊進行黑盒測試,這樣也更加有助于提升測試流程的完整性,最終提高產品的質量。

單元測試的內容:

單元測試的測試目的

模塊接口測試

局部數據結構測試

路徑測試

錯誤處理測試

邊界測試

在現有的開發工作中,我們一般都會忽略掉單元測試的重要性,功能開發完成以后開發者拿到現有的測試用例,直接針對每條用例進行手工的測試,測試通過就進行提測,之后測試人員還是重復手工測試的流程、數據的mock、專項測試等,這樣以來白盒測試的流程有時間份量會變的很低,開發人員不知道自己模塊代碼的覆蓋路問題,更多的時間可能某些代碼一直到到上線都從來沒有跑過,以至于到了真實環境下會產生一些意想不到的問題,這樣以來風險極高,整體來說單元測試還是至關重要的。

下面介紹一下Xcode7 中現有的一些測試工具:

2. Xcode7中的UnitTest

2.1 ?XCTest介紹

本文主要基本Xcode7來講解,至于xcode 新功能的歷史各位自己去趴去,此處只講解如何使用,廢話少說,下面直接入正題。

最新的Xcode7中是包含了UITest UnitTest工具的,這個可以在你創建工程的時間勾選對應的選項,也可以直接通過addTarget的形式來完成,

2.1 ?XCTestCase簡介

如果項目創建的時間勾選了UnitTest(從名字上看就是Apple提供的官方的一個單元測試工具) ,我們可以看到工程里面是多了一個目錄,默認多了一個類

選擇XCTest

XCTest是Apple官方提供一個測試工具,一個內置的測試框架,從工程里面可以看到,一個“應用名稱”的group,我們直接可以使用commond+R 來運行,一個測試的target我們可以使用commond+U來運行測試target,在測試target的目錄下會有一個默認的“應用名稱”+Test的類,這個類只有.m沒有.h,繼承于XCTestCase,使用commond+U即可運行。

默認測試類里面有以下方法:

//方法在XCTestCase的測試方法調用之前調用,可以在測試之前創建在test case方法中需要用到的一些對象等

- (void)setUp ;

//當測試全部結束之后調用tearDown方法,法則在全部的test case執行結束之后清理測試現場,釋放資源刪除不用的對象等

- (void)tearDown ;

//測試代碼執行性能

- (void)testPerformanceExample

2.2 XCTestCase使用

XCTestCase的初始化不是用戶控制的,開發者無需手動針對XCTestCase的subclass進行 alloc 、init或者調用靜態方法初始化的操作,針對一個功能塊的單元測試(針對某個class),只需要單獨給為這個類創建一個繼承于XCTestCase,在這個文件內實現上述基本函數以后(一半系統會默認創建這三個函數),其實的邏輯只需要開發者自行定義以“test"開頭的函數,然后在內部實現自己針對某個函數、返回數值結果、操作等的測試腳本即可,commond+U執行的時間,單元測試會自動執行這些test打頭的函數,當函數頭上出現藍色的標記則表明測試通過,否則直接報紅色錯誤。

XCTest測試范疇:

基本邏輯測試處理測試

異步加載數據測試

數據mock測試

XCTest常用基本測試工具

XCTest常用的一些判斷工具都是以XCT開頭的,如:

//斷言,最基本的測試,如果expression為true則通過,否則打印后面格式化字符串

XCTAssert(expression, format...)

//Bool測試:

XCTAssertTrue(expression, format...)

XCTAssertFalse(expression, format...)

//相等測試

XCTAssertEqual(expression1, expression2, format...)

XCTAssertNotEqual(expression1, expression2, format...)

//double float 對比數據測試使用

XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, format...)

XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy, format...)

//Nil測試,XCTAssert[Not]Nil斷言判斷給定的表達式值是否為nil

XCTAssertNil(expression, format...)

XCTAssertNotNil(expression, format...)

//失敗斷言

XCTFail(format...)

XCTest異步測試

Xcode單元測試中加入的最令人興奮的功能也許就是類XCTestExpression類帶入的異步測試了。現在測試可以等待指定長度的時間,一直到某些條件符合的時候在開始測試。而不用再寫很多的GCD代碼控制。

要使用異步測試,首先用方法expectationWithDescription創建一個expection

let expectation = expectationWithDescription("...")

之后,在方法的最后添加方法waitForExpectationsWithTimeout,指定等待超時的時間和指定時間內條件無法滿足時執行的closure。

waitForExpectationsWithTimeout(10) { (error) in

// ...

}

剩下的就是在異步測試剩下的回調函數中告訴expectation條件已經滿足。

expectation.fulfill()

如果在測試中有多個expectation,則每個expectation都必須fulfill,否則測試不通過。

- (void)testFetchRequestWithMockedManagedObjectContext

{

MockNSManagedObjectContext *mockContext = [[MockNSManagedObjectContext alloc] initWithConcurrencyType:0x00];

let mockContext = MockNSManagedObjectContext()

NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"User"];

let fetchRequest = NSFetchRequest(entityName: "User")

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"email ENDSWITH[cd] apple.com"];

fetchRequest.predicate = NSPredicate(format: "email ENDSWITH[cd] %@", "apple.com")

fetchRequest.resultType = NSDictionaryResultType;

fetchRequest.resultType = NSFetchRequestResultType.DictionaryResultType

var error: NSError?

NSError *error = nil;

NSArray *results = [mockContext executeFetchRequest:fetchRequest error:&error];

let results = mockContext.executeFetchRequest(fetchRequest, error: &error)

XCTAssertNil(error, @"error應該為nil");

XCTAssertEqual(results.count, 2, @"fetch request應該只返回一個結構");

NSDictionary * result = results[0];

XCTAssertEqual(result[@"name"], @"張三", @"name應該是張三");

NSLog(@"email : %@",result[@"email"]);

XCTAssertEqual(result[@"email"], @"zhangsaan@apple.com", @"email應該是zhangsan@apple.com");

}

XCTest Mock

數據mock

2.3、Xcode7 Code Coverage介紹

談的單元測試此處不免要聊起一個新的概念,代碼覆蓋率,最早最一次聽到這個詞的時間覺得很可笑(難道這個也需要統計),故名思義 代碼覆蓋率 = 實際執行的代碼行數 / 整個工程總代碼行數,直白來講就是這樣一個數值,上述談過,單元測試的目的除了講程序分成各個最小的單元獨立去測試確保正確以外,還有一個就是代碼覆蓋率問題,如果說發到線上的產品有相當一部分代碼從來都沒有執行過,這個問題是相當危險的(問題大家可以各自猜測,相信這個問題不是很陌生)。

Code Coverage工具使用

下面說下Xcode中代碼覆蓋率的問題,Xcode7以前代碼覆蓋率統計比較麻煩,Xcode7以后Apple推出了更為人性化的工具,既然學習就學習最為流行的,過去的麻煩就當隨之過去吧,何必留在痛苦回憶里(有興趣的可以參考Apple DOCXcode代碼覆蓋率測試工具)

注: 傳統統計覆蓋率的方法會做一部分Xcode配置,最終打出一個叫“插莊包”的包,這個包僅為做統計使用,如果要上生產環境,切忌將配置一定要關掉在從新打包上傳,否則后患無窮...

Xcode7 提供了一個內置的Code Coverage工具組件,廢話不說,下面看使用方法:

1、首先需要在product->scheme->Edit Scheme里面將Code Coverage模式打開,選中為debug模式,如圖:

Edit Scheme

Edit Scheme

2、打開Code Coverage模式之后,打開某個測試類,commond+U 運行,如果測試通過,測試腳本的函數頭上會出現一個綠色的標志(相反如何哪一個方法測試沒有通過,則會提示一個紅色錯誤),如下:

Edit Scheme

3、打開Xcode左邊窗口的Report Navigator,找到 Project Log,選擇最近一次的log選項,最近一次是剛才的一個Test Log,選擇中這個Log實例,可以看到一下界面,

如圖:

Edit Scheme

然后在tab中選中 Coverage,此時你可以看到大致的代碼執行覆蓋情況,如果指示條是滿的則代表該類代碼全部跑過一遍。

Edit Scheme

4、雙擊你想要查看的類,此處選擇查看UATrackDao,打開后既可以看到剛剛的測試中有哪些代碼是執行過的,那些代碼時未執行的,橘黃色的代表還未執行的,執行過的每一行后面會有一個序號代表這行代碼在剛才的測試過程中執行的次數。如果有未執行的,可根據具體的情況調整對應的測試腳本,繼續測試,最終確保每一行代碼都能正確執行,如圖:

Edit Scheme

Edit Scheme

3. Xcode7中的UITest

UnitTest簡介

任何軟件開發中,自動化UI測試都是很重要的(UI自動化測試的好處此處就不再多說了),iOS平臺在以往是通過UIAutomation來完成自動化UI測試的,它的測試用例是javascript寫的(Instruments中提供了該功能),這個過程深奧繁瑣,需要自行編寫對應的測試腳本,速度慢,學習成本高(關于Automation自動化測試概念大家可以查看相關的資料,Automation自動化測試在各大平臺都有應用,在大型的軟件開發測試過程的確的確可以節省大量的手工測試人員,大大提高軟件測試的成本與效率,在最新Xcode7本文推薦使用Apple提供的最新的工具UITest)。

Apple在Xcode 6中又新增了UnitTest之外,到了Xcode 7 Apple從新提供了一個新的框架UITest,這個主要是用來測試UI的,UnitTest涌來測試功能邏輯代碼,UITest專門用來測試UI。

Xcode 7已經集成了UITest,UITest允許你找到UI元素并與之交戶,還能檢查UI的屬性和狀態,并且UITest也已經集成在Xcode 的測試報告了,可以和單元測試一起執行,和UnitTest一樣我們可以在檢查UI的時間執行斷言。

創建UITest target,同樣會生成一個“項目名稱”+UITest的group,UITest target可以在創建工程的時間勾選,也可以在工程中手動添加,在 “項目名稱”+UITest 分組下,我們可以看到系統會幫我們默認生成一個UI測試類,這個類也同樣是繼承于XCTestCase的。由此可見,在iOS中無論是單元測試還是UI測試,都是基于XCTestCase的。

UnitTest UI測試

創建模態視圖,我們選擇從第一個VC通過點擊按鈕的形式push到第二個VC

Edit Scheme

創建UITest target,我們對上述UI進行測試 如圖選項:

Edit Scheme

Edit Scheme

打開UATrackDemoUiTest.m,創建 - (void)testUI,同時將光標留在函數內

Edit Scheme

點擊下面的紅色按鈕,開始recorder操作,程序運行起來后,點擊界面上的按鈕,程序會push到一個新的頁面,這個時間會看到到剛才的鼠標光標處自動生成了一部分代碼,重復操作,每次都會生成新的代碼,如圖:

Edit Scheme

從新點擊小紅點按鈕,此時結束recorder操作,commond+U 運行測試,此時剛才的一連串動作會一步一步連續執行下來:

Edit Scheme

此處聲明: 第一次點擊紅色的recorder按鈕,然后手動操作會自動生成測試腳本,第二次commond+U是進行測試UI

UnitTest工具拓展

XCTest一共提供了三種UI測試對象

XCUIApplication 當前測試應用target

XCUIElementQuery 定位查詢當前UI中xctuielement的一個類

XCUIElement UI測試中任何一個item項都被抽象成一個XCUIElement類型

當我們獲取了錄制生成的代碼以后,根據UITest提供的三種對象,我可以在此來對測試代碼進行修改,調試

UITest中同樣適用以下斷言等:

XCTAssert(expression, format...)

//Bool測試:

XCTAssertTrue(expression, format...)

XCTAssertFalse(expression, format...)

//相等測試

XCTAssertEqual(expression1, expression2, format...)

XCTAssertNotEqual(expression1, expression2, format...)

//double float 對比數據測試使用

XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, format...)

XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy, format...)

//Nil測試,XCTAssert[Not]Nil斷言判斷給定的表達式值是否為nil

XCTAssertNil(expression, format...)

XCTAssertNotNil(expression, format...)

//失敗斷言

XCTFail(format...)

.....

關于Xcode 7 UnitTest的問題就講到此處,希望有興趣的同學大家共同交流...

4. 小結

1.總結現有問題,分享心得

Xcode6的內置工具終于足夠的好了。也就是說即使是很大的APP也沒有必要為了單元測試的代碼覆蓋率而排斥Xcode內置的測試工具。無論什么樣的測試,XCTest的各種斷言、expectation和性能測試都足夠應對。但是無論多好的工具,都需要用好才行。

如果你在測試iOS或者OS X的APP,開始為自動添加的測試類添加一些斷言并按下Command+U。你一定會發現感覺這些工具讓你的測試方便不少 。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,237評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,957評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,248評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,356評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,081評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,485評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,534評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,720評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,263評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,025評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,204評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,787評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,461評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,874評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,105評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,945評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,205評論 2 375

推薦閱讀更多精彩內容