Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Share Extension の UI Test / UI Test for Share E...

Elvis Shi
January 24, 2020

Share Extension の UI Test / UI Test for Share Extension

Share Extension を対応したとき、共有メニューの UI テストをどうすればいいのか

Elvis Shi

January 24, 2020
Tweet

More Decks by Elvis Shi

Other Decks in Programming

Transcript

  1. } var employedBy = "YUMEMI Inc." var job = "iOS

    Tech Lead" var favoriteLanguage = "Swift" var twitter = "@lovee" var qiita = "lovee" var github = "el-hoshino" var additionalInfo = """ ཏখࠇઓهʢϩγϟΦϔΠηϯΩʣөը؍Α͏ʂ """ final class Me: Developable, Talkable {
  2. func testQRCodeGenerationFromSafari() { let app = XCUIApplication(bundleIdentifier: "com.apple.mobilesafari") app.launch() XCTContext.runActivity(named:

    "Go to about:blank page") { _ -> Void in let urlBar = app.otherElements["topBrowserBar"] urlBar.tap() urlBar.typeText("about:blank") app.buttons["Go"].tap() } XCTContext.runActivity(named: "Call Share menu") { _ -> Void in let shareButton = app.buttons["Share"] shareButton.tap() } XCTContext.runActivity(named: "Open QuickshaRe") { _ -> Void in let shareList = app.otherElements["ActivityListView"] XCTAssert(shareList.waitForExistence(timeout: 2)) let cell = shareList.cells.matching(identifier: "Activity").allElementsBoundByIndex[1] cell.tap() } XCTContext.runActivity(named: "Check label and image display") { _ -> Void in let view = app.otherElements["Share View"] let label = view.staticTexts["about:blank"] let image = view.images["QR Image"] XCTAssert(view.waitForExistence(timeout: 2)) XCTAssert(label.exists) XCTAssert(image.exists) let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil)! let qrCIImage = CIImage(image: image.screenshot().image)! let features = detector.features(in: qrCIImage) as! [CIQRCodeFeature] XCTAssertEqual(features[0].messageString, "about:blank") } }
  3. 6*5FTUͱ6OJU5FTUͷҧ͍ w 6OJU5FTUɿϝιου౳ͷॲཧʹର͢ΔϩδοΫͷςετ w ΞϓϦຊମΛ@testable import͠ɺϝιου΍ΦϒδΣΫτ ౳ͷςετର৅Λ࣮ࡍʹݺͼग़ͯ͠ಈ࡞Λ֬ೝ w ඞཁʹԠͯ͡ςετର৅ʹςετ޲͚ͷґଘΛ஫ೖՄೳ w

    ΞϓϦͷ࣮૷Λʢ͋Δఔ౓ʣ೺Ѳͨ͠ϗϫΠτϘοΫεςετ w 6*5FTUɿϏϧυࡁΈͷΞϓϦΛ௚઀ಈ͔͢ςετ w ΞϓϦຊମΛ@testable importͤͣʹ௚઀ΞϓϦΛૢ࡞ͯ͠ ಈ࡞Λ֬ೝ w ςετ޲͚ͷґଘ஫ೖ͸೉͍͠ w ΞϓϦͷ࣮૷Λશ͘೺Ѳ͠ͳ͍ϒϥοΫϘοΫεςετ
  4. ς ε τ ର ৅ ͷ  ຊ ମ Ξ

    ϓ Ϧ ࣮ ࡍ ͷ  ς ε τ λ ʔ ή ỽ τ ͔ Β  Ϗ ϧ υ ͠ ͨ Ξ ϓ Ϧ
  5. .staticTexts["Some Text"] .textFields["Placeholder Text"] .buttons["Button Title"] .images["Accessibility Identifier"] .otherElements["Identifier"] .exists

    .waitForExistence(timeout: 2) .tap() .typeText("Some Typing") // etc... ͜ΕΒͷ"1*Λ૊Έ߹Θͤͯ ΞϓϦʹରͯ͠র߹΍ૢ࡞Λ༩͑Δ
  6. // ϒϥ΢βը໘ͷ্ʹ͋Δϒϥ΢βόʔΛ୳͢ let urlBar = app.otherElements["topBrowserBar"] // ͦͷϒϥ΢βόʔΛԡ͢ urlBar.tap() //

    ϒϥ΢βόʔʹࢦఆͷจࣈΛೖΕΔ urlBar.typeText("about:blank") // ΩʔϘʔυͷ `Go` ΩʔΛԡ͢ app.buttons["Go"].tap()
  7. // ڞ༗ϝχϡʔΛ୳͢ let shareList = app.otherElements["ActivityListView"] // ڞ༗ϝχϡʔ͕දࣔ͞ΕΔ·Ͱ࠷େ 2 ඵ଴ͭ

    XCTAssert(shareList.waitForExistence(timeout: 2)) // ͦͷڞ༗ϝχϡʔ͔Β֘౰ΞϓϦͷΞΠίϯΛ୳͢ let cell = shareList.cells.matching(identifier: "Activity") .allElementsBoundByIndex[1] // ͦͷΞΠίϯΛԡ͢ cell.tap()
  8. // Share View Λ୳͢ let view = app.otherElements["Share View"] //

    ࢦఆͷςΩετදࣔΛ୳͢ let label = view.staticTexts["about:blank"] // QR ίʔυը૾දࣔΛ୳͢ let image = view.images["QR Image"] // Share View ͕දࣔ͞ΕΔ·Ͱ࠷େ 2 ඵ଴ͭ XCTAssert(view.waitForExistence(timeout: 2)) // ࢦఆͷ URL ςΩετද͕ࣔ͋Δ͜ͱΛ֬ೝ XCTAssert(label.exists) // QR ίʔυը૾ද͕ࣔ͋Δ͜ͱΛ֬ೝ XCTAssert(image.exists) // ͦͷը૾දࣔΛ QR ίʔυͱͯ͠ಡΈऔΕ͹ࢦఆͷ URL ςΩετͰ͋Δ͜ͱΛ֬ೝ let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil)! let qrCIImage = CIImage(image: image.screenshot().image)! let features = detector.features(in: qrCIImage) as! [CIQRCodeFeature] XCTAssertEqual(features[0].messageString, "about:blank") ౰વͳ͕Β JNQPSU$PSF*NBHF ͕ඞཁ
  9. // ڞ༗ϝχϡʔΛ୳͢ let shareList = app.otherElements["ActivityListView"] // ڞ༗ϝχϡʔ͕දࣔ͞ΕΔ·Ͱ࠷େ 2 ඵ଴ͭ

    XCTAssert(shareList.waitForExistence(timeout: 2)) // ͦͷڞ༗ϝχϡʔ͔Β֘౰ΞϓϦͷΞΠίϯΛ୳͢ let cell = shareList.cells.matching(identifier: "Activity") .allElementsBoundByIndex[1] // ͦͷΞΠίϯΛԡ͢ cell.tap() ͳΜ͡Ό͜Εʂʁ NBUDIJOHʁ "DUJWJUZʁ <>ʁ
  10. XCTContext.runActivity(named: "Search Elements") { (activity) -> Void in // app

    ͔ΒݟΕΔ͢΂ͯͷ otherElements Λ૸ࠪ app.otherElements.allElementsBoundByIndex.forEach { (element) in // ඞͣ element ͕ଘࡏ͠ɺ͔ͭαΠζ͕ zero ͡Όͳ͍͜ͱΛอূ guard element.exists, element.frame.size != .zero else { return } // ֘౰ element ͷεΫϦʔϯγϣοτΛࡱΔ let screenshot = element.screenshot() // εΫϦʔϯγϣοτ͔Βఴ෇Λ࡞Δ let attachment = XCTAttachment(screenshot: screenshot) // ݱࡏͷ activity ʹఴ෇Λ௥Ճ activity.add(attachment) } } ςΩετҎ֎ͰଞਓͷΞϓϦͳΒ      
  11. XCTContext.runActivity(named: "Search Elements") { activity -> Void in let shareList

    = app.otherElements["ActivityListView"] XCTAssert(shareList.waitForExistence(timeout: 2)) // ڞ༗ϝχϡʔ ͔ΒݟΕΔ͢΂ͯͷ cell Λ૸ࠪ shareList.cells.allElementsBoundByIndex.forEach { (cell) in guard cell.exists, cell.frame.size != .zero else { return } let screenshot = cell.screenshot() let attachment = XCTAttachment(screenshot: screenshot) activity.add(attachment) } } ଞਓͷΞϓϦͳΒ
  12. // ڞ༗ϝχϡʔΛ୳͢ let shareList = app.otherElements["ActivityListView"] // ڞ༗ϝχϡʔ͕දࣔ͞ΕΔ·Ͱ࠷େ 2 ඵ଴ͭ

    XCTAssert(shareList.waitForExistence(timeout: 2)) // ͦͷڞ༗ϝχϡʔ͔Β֘౰ΞϓϦͷΞΠίϯΛ୳͢ let cell = shareList.cells.matching(identifier: "Activity") .allElementsBoundByIndex[1] // ͦͷΞΠίϯΛԡ͢ cell.tap() ͳΜ͡Ό͜Εʂʁ NBUDIJOHʁ "DUJWJUZʁ <>ʁ
  13. // ͢΂ͯͷηϧ͔Β૸ࠪ let cell = shareList.cells // `Activity` ͷηϧΛநग़ .matching(identifier:

    "Activity") // ͦͷ 2 ൪໨ͷηϧ .allElementsBoundByIndex[1] ˞࣮ߦ͞ΕΔ୺຤ͷڞ༗ઃఆʹґଘ͢ΔͨΊ$*Ͱอূͤ͞Δ͜ͱ͸ݱࡏෆՄೳ