What’s New in Testing

概述

Session-409的主題為[What’s New in Testing]梳星,主要包括:

  • Enhancement
    優(yōu)化了macOS、xcodebuild在UT中的性能
  • New Asynchronous Testing API
    提供新的接口和新的等待方式膨更,讓異步測試更加靈活
  • Multiple App Testing
    編寫測試代碼着裹,實現在多個App間自動跳轉幢尚、測試
  • Implements For UITesting
    改進UITest茫负,優(yōu)化element選取的算法
  • New Technologies
    新的Activities磁浇、attachments、screenshot技術

demo地址

Enhancement

  1. Xcode8:XCUISiriTest用于便攜SiriKit的Unit Test朽褪;支持Touchbar的UITest
  2. Xcode9:改良了swift4的接口,基于block的 Teardown API
  3. 改進macOS的菜單欄的UI test
  4. 使用命令行進行測試无虚,直接啟動core simulator進行測試缔赠,不會再看到在測試過程中啟動模擬器了
  5. 持續(xù)集成場景下,Xcodebuild支持多個設備平行測試友题,Xcode server可以取代macOS server嗤堰,進行持續(xù)化集成,App測試
  6. 對于有國際化需求的App度宦,在Xcode9的scheme中可以選擇語言和地區(qū)踢匣。應用場景:寫UI Test case生成不同國家對應的截圖,用于App Store的圖片介紹界面戈抄,可以節(jié)約大量的時間离唬,否則只能統一是用一種展示方式:


    Xcode scheme中選擇語言和地區(qū)

New Asynchronous Testing API

新老API比較

早在Xcode6中就已經有了異步測試API,使用上也比較簡單划鸽,性能方面也算可以输莺,但是有幾個缺點:

  • 等待超時會被視為測試失敗,在某些情況下我們想對超時的情況做一些特殊的邏輯處理時裸诽,老API無法滿足這個需求

  • 等待代碼中需要持有XCTestExpectation對象嫂用,等待的代碼往往與測試邏輯的代碼混雜在一起,想要把測試代碼與支持代碼變得困難

[[Downloader new] downloadWithCompletion:^(BOOL success, NSError *err) {
    XCTAssert(success, @"failed");
     [_exception fulfill];
}];
// 隱式等待丈冬,內部可能持有了expectation對象
[self waitForExpectationsWithTimeout:10 handler:^(NSError * _Nullable error) {
    NSLog(@"timeout");
}];
  • 需要等到所有處于活躍XCTestExpectation對象全部執(zhí)行 fulfill后才會返回
  • 老的設計模式不支持嵌套waiting

所以嘱函,Apple推出了新的API: XCTWaiter,它將waiting埂蕊、XCTestCase往弓、XCTestExpectation解耦疏唾,除此之外:

  • 指明等待的XCTestExpectation對象,
 [XCTWaiter waitForExpectations:@[donwloadException] timeout:0.5 enforceOrder:NO];
  • delegate回調, 返回結果XCTWaiterResult亮航,允許指定順序
 XCTWaiterResult result = [[XCTWaiter alloc] initWithDelegate:self] waitForExpectations:@[donwloadException] timeout:0.5 enforceOrder:YES];
  • 支持嵌套
    新的異步測試API
- (void)test_asyncDownload_newAPI {

   Downloader *loader = [Downloader new];
 
     // download 時間為1s
     XCTestExpectation *donwloadException = [[XCTestExpectation alloc] initWithDescription:@"download"];
     [loader downloadWithCompletion:^(BOOL success, NSError *err) {
         [donwloadException fulfill];
     }];

     // upload 時間為3s
     XCTestExpectation *uploadException = [[XCTestExpectation alloc] initWithDescription:@"upload"];
     [loader uploadWithCompletion:^(BOOL success, NSError *err) {
         [uploadException fulfill];
     }];
 
     XCTWaiterResult result = [XCTWaiter waitForExpectations:@[donwloadException, uploadException] timeout:4 enforceOrder:NO];
 XCTAssert(result == XCTWaiterResultCompleted, @"failed: %ld", (long)result);
}

Multiple app test

Xcode9允許通過Bundle ID 和 fileURL(macOS)來創(chuàng)建一個XCUIApplication對象荸实,以便于多個App測試。launchactivate可用來將APP從后臺拉到前臺缴淋,區(qū)別在于:如果app在運行中准给,activate不會打斷app

'' - (void)testMutipleApp { 
''    XCUIApplication *readApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.sohu.TestRead"];
''     // 啟動read app
''     [readApp launch];
'' 
''     XCUIApplication *writeApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.sohu.TestWrite"];
''     // 激活
''     [writeApp activate];
'' 
''     XCUIElement *writeTextField = writeApp.textFields[@"Input"];
''     [writeTextField tap];
''     [writeTextField typeText:@"Using Testing New API To Do Multiple App UI Test"];
''     [writeApp.buttons[@"return"] tap];
''     [writeApp.buttons[@"Send"] tap];
'' 
''     // back to read
''     [writeApp.alerts[@"success"].buttons[@"OK"] tap];
''     [writeApp.statusBars.buttons[@"Return to TestRead"] tap];
'' 
''     // 等待readApp變成活躍狀態(tài)
''     NSPredicate *readAppPredicate = [NSPredicate predicateWithFormat:@"state == %d", XCUIApplicationStateRunningForeground];
''     XCTNSPredicateExpectation *expection = [[XCTNSPredicateExpectation alloc] initWithPredicate:readAppPredicate object:readApp];
''     expection.expectationDescription = @"Waiting read app to become active";
''     XCTWaiterResult result = [XCTWaiter waitForExpectations:@[expection] timeout:5];
'' 
''     NSLog(@"wait result:%ld", (long)result);
'' 
''     XCUIElement *contentLabel = readApp.staticTexts[@"Using Testing New API To Do Multiple App UI Test"];
''     XCTAssert(contentLabel.exists);
'' }

Implements For UITesting

UITesting往往通過獲取到某個UI控件才能進行相關測試重抖,與voiceover相似露氮,需要根據控件顯示的內容、語義來查找钟沛,涉及生成快照畔规,快照解包和進程間的通訊等等。Xcode9之前恨统,采用的是快照(snapshots)技術來實現叁扫,在使用過程中,當當前屏幕下有大量控件時畜埋,例如有上千行的tableviewCell莫绣,從內存和耗費的時間兩個維度來看,耗費的時間和內存占用有些大悠鞍,甚至會有超時導致測試失敗对室、內存占用過大導致閃退的情況出現…于是就有了FirstMatch

First Match

First Match:就像字面上的意思一個,只要有一個匹配到了就會馬上return咖祭。
這樣的話掩宜,在寫查詢代碼的時候需要多考慮考慮怎么發(fā)揮FirstMatch的功能。
假設現在要查找navigationBar上的返回按鈕:
app.buttons.firstMatch顯然不是一個好的寫法么翰,這樣得到的element可能不是你想要查詢的牺汤;
app.buttons[@"Done"].firstMatch這樣寫好多了,縮小了范圍硬鞍,
而最好的寫法則是app.navigationBars.buttons[@"Done"].firstMatch

New Technologies

Activities

用于將散落的Testing語句整理在一個Group中

attachments

測試報告中可以包含更多的信息慧瘤,如:截屏

screenshots

新增XCUIScreenshotProviding,遵循了這個協議的固该,即可調用screenshot方法獲取屏幕截圖

'' - (void)testNewTechnoligies {
'' 
''     // 創(chuàng)建Launch Activity
''     [XCTContext runActivityNamed:@"Launch" block:^(id<XCTActivity>  _Nonnull activity) {
''         XCUIApplication *app = [[XCUIApplication alloc] init];
''         app.launchArguments = @[@"-StartFromSlate", @"YES"];
''         [app launch];
''     }];
'' 
''     // 創(chuàng)建ScreenShots Activity
''     [XCTContext runActivityNamed:@"ScreenShots" block:^(id<XCTActivity>  _Nonnull activity) {
''         // 生成主屏幕截圖
''         XCUIScreenshot *screenShot = [[XCUIScreen mainScreen] screenshot];
''         // 將截屏添加到附件中
''         XCTAttachment *attachment = [XCTAttachment attachmentWithScreenshot:screenShot];
''         // 確保測試成功后attachment不會被自動刪除, 這個同樣可以在Xcode的中設置
''         attachment.lifetime = XCTAttachmentLifetimeKeepAlways;
''         // attachment添加到activity中
''         [activity addAttachment:attachment];
''     }];
'' }

測試報告中锅减,生成了兩個activity,screenshots activity還包含一張屏幕截圖:

activity生成測試報告group
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末伐坏,一起剝皮案震驚了整個濱河市怔匣,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖每瞒,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件金闽,死亡現場離奇詭異,居然都是意外死亡剿骨,警方通過查閱死者的電腦和手機代芜,發(fā)現死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浓利,“玉大人挤庇,你說我怎么就攤上這事〈矗” “怎么了嫡秕?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長苹威。 經常有香客問我昆咽,道長,這世上最難降的妖魔是什么牙甫? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任掷酗,我火速辦了婚禮,結果婚禮上窟哺,老公的妹妹穿的比我還像新娘汇在。我一直安慰自己,他們只是感情好脏答,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亩鬼,像睡著了一般殖告。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上雳锋,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天黄绩,我揣著相機與錄音,去河邊找鬼玷过。 笑死爽丹,一個胖子當著我的面吹牛,可吹牛的內容都是我干的辛蚊。 我是一名探鬼主播粤蝎,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼袋马!你這毒婦竟也來了初澎?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤虑凛,失蹤者是張志新(化名)和其女友劉穎碑宴,沒想到半個月后软啼,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡延柠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年祸挪,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贞间。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡贿条,死狀恐怖,靈堂內的尸體忽然破棺而出榜跌,到底是詐尸還是另有隱情闪唆,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布钓葫,位于F島的核電站悄蕾,受9級特大地震影響,放射性物質發(fā)生泄漏础浮。R本人自食惡果不足惜帆调,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望豆同。 院中可真熱鬧番刊,春花似錦、人聲如沸影锈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸭廷。三九已至枣抱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辆床,已是汗流浹背佳晶。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留讼载,地道東北人轿秧。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像咨堤,于是被迫代替她去往敵國和親菇篡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容