Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Asynchronous Testing in XCTest
Search
Shingo Tamaki
December 21, 2018
Technology
0
420
Asynchronous Testing in XCTest
This document explain about asynchronous testing in XCTest
Shingo Tamaki
December 21, 2018
Tweet
Share
More Decks by Shingo Tamaki
See All by Shingo Tamaki
AIエージェントを使ったiOSアプリ開発を試してみた
tamaki
0
66
沖縄モバイルアプリ開発勉強会#1
tamaki
0
110
iOSアプリ開発を始めよう
tamaki
0
170
詳解xcresult.pdf
tamaki
0
340
メルペイでのリグレッションテスト自動化推進のこれまでとこれから
tamaki
0
730
What do you want to test with UI Test v2
tamaki
2
880
JPQRによって変わる日本のQRコード決済
tamaki
0
290
What's New in Testing
tamaki
1
58
What do you want to test with UI Test
tamaki
5
1.9k
Other Decks in Technology
See All in Technology
Datadog のトライアルを成功に導く技術 / Techniques for a successful Datadog trial
nulabinc
PRO
0
140
AIによるコードレビューで開発体験を向上させよう!
moongift
PRO
0
430
encoding/json v2を予習しよう!
yuyu_hf
PRO
0
120
続・やっぱり余白が大切だった話
kakehashi
PRO
3
320
MCPを理解する
yudai00
14
10k
Как мы автоматизировали интеграционное тестирование с Gonkey и не пожалели. Паша Егорычев, Кирилл Поляков
lamodatech
0
2.1k
名単体テスト 禁断の傀儡(モック)
iwamot
PRO
1
230
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
5.5k
LLM アプリケーションのためのクラウドセキュリティ - CSPM の実装ポイント-
osakatechlab
0
410
OPENLOGI Company Profile for engineer
hr01
1
26k
既存の開発資産を活かしながら、 《新規開発コスト抑制》と《開発体験向上》 を両立する拡張アーキテクチャ事例
kubell_hr
0
150
Computer Use〜OpenAIとAnthropicの比較と将来の展望〜
pharma_x_tech
6
1k
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
512
110k
A designer walks into a library…
pauljervisheath
205
24k
Site-Speed That Sticks
csswizardry
6
540
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
34
2.2k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Agile that works and the tools we love
rasmusluckow
329
21k
The World Runs on Bad Software
bkeepers
PRO
68
11k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
47
2.7k
Making Projects Easy
brettharned
116
6.2k
The Pragmatic Product Professional
lauravandoore
33
6.6k
Gamification - CAS2011
davidbonilla
81
5.3k
Transcript
Asyncronous Testing in XCTest
XCTestʹ͓͚Δඇಉظॲཧͷςετ ඇಉظͷςετͷͨΊʹXCTestExpectationͱXCTWaiter༻ҙ͞ Ε͍ͯ·͢ɻ XCTestExpectationͷfulfillͷ࣮ߦΛ࣋ͬͯඇಉظॲཧͷྃͱ͠ waitͰࢦఆͨ͠expectationͷྃʹػ͢Δͷ͕جຊతͳྲྀΕ Ͱ͢ɻ • XCTestExpectation • XCTWaiter
XCTestExpectation func test_fetchPilot() { // 1.XCTestExpectationΛ࡞ let expectation = XCTestExpectation(description:
"pilot") PilotApiClient.fetchPilot(of: "new_type") { (result) in switch result { case .success(let user): XCTAssert(user.name == "REI") case .failure(_): break } // 2.ඇಉظॲཧͷ࣮ߦϒϩοΫͰfulfillΛ࣮ߦ expectation.fulfill() } // 3.waitؔʹexpectationΛࢦఆ wait(for: [expectation], timeout: 2) //<- 1ඵະຬͰςετࣦഊ }
XCTestExpectation • expectedFulfillmentCount • isInverted
XCTestExpectation expectedFulfillmentCountʹճΛࢦఆ͢ΔͱࢦఆճҎԼ λΠϜΞτͰςετࣦഊͱ͞Ε·͢ɻ /// RadarAPIClient͔Β·ͣ1ඵޙʹɺͦͯͦ͠Ε͔Β5ඵޙʹίʔϧόοΫ͕ฦ͖ͬͯ·͢ɻ /// ෳճίʔϧόοΫ͕࣮ߦ͞ΕΔΛߟྀͯ͠Έ·͠ΐ͏ ! let expectation
= XCTestExpectation(description: "radar") expectation.expectedFulfillmentCount = 2 let here = MyLocation(latitude: 35.664584, longitude: 139.730852) RadarApiClient.observeEnemy(from: here) { [expectation] (result) in switch result { case .success(let enemies): XCTAssert(enemies.count > 0) case .failure(_): break } expectation.fulfill() } wait(for: [expectation], timeout: 10)
XCTestExpectation isInvertedΛࢦఆ͢ΔͱfulfillΛ"࣮ߦ͞Εͳ͍߹"ʹςετ͕ ޭ͠·͢ɻ let expectation = XCTestExpectation(description: "inverted") expectation.isInverted =
true // fulfill͕ى͖ͳ͔ͬͨ߹ʹςετޭͱ͢Δ wait(for: [expectation], timeout: 1)
XCTWaiter
XCTWaiter ͔͜͜ΒXCTWaiterͷΛ͠·͢ɻ XCTWaiterwaitϝιουͳͲͷΑ͏ͳඇಉظॲཧͷྃΛ ͭͨΊͷॲཧʹ͍ͭͯͷػೳΛ୲͠·͢ɻ ྫ͑waitXCTWaiterDelegateͰఆٛ͞Ε͓ͯΓɺ XCTestCase͕͜Εʹ४ڌ͍ͯ͠·͢ɻ
wait(or waitForExpectations) • ॲཧྃ࣌ʹಛఆͷॲཧΛ࣮ߦ͍ͨ͠߹ • ඇಉظॲཧͷλΠϜΞτ͕ҟͳΔ߹ • ඇಉظॲཧͷऴྃॱ͕݅ͱͳΔ߹(enforceOrder)
wait(or waitForExpectations) ॲཧྃ࣌ʹಛఆͷॲཧΛ࣮ߦ͍ͨ͠߹ let expectation = self.expectation(description: "waitExpectations") DispatchQueue.main.asyncAfter(deadline: .now()
+ 0.5) { expectation.fulfill() //fulfillͳͩ͠ͱ.timeoutWhileWaitingʹͳΔ } // ίʔϧόοΫͷҾError?Ͱ͋Γɺਖ਼ৗ࣌λΠϜΞτ࣌XCTestError͕ฦ٫͞ΕΔ waitForExpectations(timeout: 1) { (error) in guard let error = error as? XCTestError else { return } switch error.code { case .failureWhileWaiting: print(" ! ࣦഊ࣌ͪ͜Β") //ਖ਼ίϨͷى͜͠ํ͕Θ͔ͬͯͳ͍ break case .timeoutWhileWaiting: print(" ! λΠϜΞτͷ߹ͪ͜Β") } }
wait(or waitForExpectations) ඇಉظॲཧͷλΠϜΞτ͕ҟͳΔ߹ ҰͭͷwaitͰॲཧͤͣʹෳͷwaitΛ͏ࣄͰλΠϜΞτͷ࣌ ؒΛ͚Δ͜ͱ͕Ͱ͖Δɻ let expForPilot = XCTestExpectation(description: "pilot")
fetchPilot(expForPilot) let expForColony = XCTestExpectation(description: "colony") fetchColony(expForColony) // λΠϜΞτͷ͕࣌ؒҧ͏ͷͰ͋ΕwaitؔΛෳʹ͚࣮ͯߦ͢Δࣄग़དྷΔɻ wait(for: [expForPilot], timeout: 2) wait(for: [expForColony], timeout: 4)
wait(or waitForExpectations) ಛఆͷॱ൪Λظͯ͠ςετ͢Δ߹enforceOrderΛtrueʹ͢ ΔࣄͰ࣮ߦྃॱग़ͳ͍߹ʹςετࣦഊͱ͢Δ͜ͱ͕Ͱ͖ Δɻ let expForPilot = XCTestExpectation(description: "pilot")
let expForColony = XCTestExpectation(description: "colony") // ྫ͑fetchColonyͷޙʹfetchPilot͠ͳ͚Ε͍͚ͳ͍ཁ͕݅͋ͬͨ߹ fetchColony(expForColony) { fetchPilot(expForPilot) } wait(for: [expForColony, expForPilot], timeout: 10, enforceOrder: true) //<- enforceOrderΛࢦఆ͢ΔࣄͰexpectationͷॱং·ͰݟΔ͜ͱ͕Ͱ͖Δ
৭ʑͳExpectationୡ
৭ʑͳExpectationୡ • XCTKVOExpectation • XCTNSNotificationExpectation • XCTNSPredicateExpectation • XCTDarwinNotificationExpectation
XCTKVOExpectation KVO(Key Value Observe)Λར༻ͨ͠Expectation KeyPathʹࢦఆͨ͠ϓϩύςΟͷࢹΛߦ͏ࣄͰར༻Մೳ let noobPilot = Pilot(id: "noob",
name: "Arbeo", abilities: []) let battleField = BattleField(pilots: [noobPilot]) let expectation = XCTKVOExpectation(keyPath: "mind", object: noobPilot) battleField.startBattle() wait(for: [expectation], timeout: 3)
XCTNSNotificationExpectation NSNotificationΛར༻ͨ͠Expectation ࢦఆ໊ͨ͠લͷ௨Λ࣋ͬͯྃͱ͢Δࣄ͕Ͱ͖Δɻ let noobPilot = Pilot(id: "noob", name: "Arbeo",
abilities: []) let battleField = BattleField(pilots: [noobPilot]) let expectation = XCTNSNotificationExpectation(name: Notification.Name("ͬͯΔʂͬͯΔͧʂ")) battleField.startBattle() wait(for: [expectation], timeout: 3)
XCTNSPredicateExpectation NSPredicateΛར༻ͨ͠Expectation ݅ʹ߹கΛॲཧྃͱ͢Δ͜ͱ͕Ͱ͖Δ let noobPilot = Pilot(id: "noob", name: "Arbeo",
abilities: []) let battleField = BattleField(pilots: [noobPilot]) let predicate = NSPredicate(format: "mind == 1") let expectation = XCTNSPredicateExpectation(predicate: predicate, object: noobPilot) battleField.startBattle() wait(for: [expectation], timeout: 3)
XCTDarwinNotificationExpectatio n Darwin NotificationΛར༻ͨ͠Expectation NSNotificationͱಉ͘͡ࢦఆ໊ͨ͠લͷ௨Λ࣋ͬͯྃͱ͢Δ ࣄ͕Ͱ͖Δɻ let noobPilot = Pilot(id:
"noob", name: "Arbeo", abilities: []) let battleField = BattleField(pilots: [noobPilot]) let expectation = XCTDarwinNotificationExpectation(notificationName: "ͬͯΈΔ͞ʂ") battleField.startBattle() wait(for: [expectation], timeout: 3)
͓·͚ Darwin Notify͏ͱΞϓϦؒແࢹͯ͠௨͕Ͱ͖·͢ɻ ϦδΣΫτϦεΫݱࡏௐࠪதɺ·ͨվΊͯ͠·͢ɻͯ࣍ ճ
Ҏ্