Share Extension の UI Test / UI Test for Share Extension

Af64bc38c0ffcfcabdf430759ee491ce?s=47 Elvis Shi
January 24, 2020

Share Extension の UI Test / UI Test for Share Extension

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

Af64bc38c0ffcfcabdf430759ee491ce?s=128

Elvis Shi

January 24, 2020
Tweet

Transcript

  1. 2.

    } 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. 3.
  3. 4.
  4. 5.
  5. 6.
  6. 8.

    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") } }
  7. 9.

    6*5FTUͱ6OJU5FTUͷҧ͍ w 6OJU5FTUɿϝιου౳ͷॲཧʹର͢ΔϩδοΫͷςετ w ΞϓϦຊମΛ@testable import͠ɺϝιου΍ΦϒδΣΫτ ౳ͷςετର৅Λ࣮ࡍʹݺͼग़ͯ͠ಈ࡞Λ֬ೝ w ඞཁʹԠͯ͡ςετର৅ʹςετ޲͚ͷґଘΛ஫ೖՄೳ w

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

    ς ε τ ର ৅ ͷ  ຊ ମ Ξ

    ϓ Ϧ ࣮ ࡍ ͷ  ς ε τ λ ʔ ή ỽ τ ͔ Β  Ϗ ϧ υ ͠ ͨ Ξ ϓ Ϧ
  9. 14.
  10. 17.

    .staticTexts["Some Text"] .textFields["Placeholder Text"] .buttons["Button Title"] .images["Accessibility Identifier"] .otherElements["Identifier"] .exists

    .waitForExistence(timeout: 2) .tap() .typeText("Some Typing") // etc... ͜ΕΒͷ"1*Λ૊Έ߹Θͤͯ ΞϓϦʹରͯ͠র߹΍ૢ࡞Λ༩͑Δ
  11. 20.

    // ϒϥ΢βը໘ͷ্ʹ͋Δϒϥ΢βόʔΛ୳͢ let urlBar = app.otherElements["topBrowserBar"] // ͦͷϒϥ΢βόʔΛԡ͢ urlBar.tap() //

    ϒϥ΢βόʔʹࢦఆͷจࣈΛೖΕΔ urlBar.typeText("about:blank") // ΩʔϘʔυͷ `Go` ΩʔΛԡ͢ app.buttons["Go"].tap()
  12. 21.
  13. 24.
  14. 26.

    // ڞ༗ϝχϡʔΛ୳͢ let shareList = app.otherElements["ActivityListView"] // ڞ༗ϝχϡʔ͕දࣔ͞ΕΔ·Ͱ࠷େ 2 ඵ଴ͭ

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

    // 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 ͕ඞཁ
  17. 30.
  18. 31.

    // ڞ༗ϝχϡʔΛ୳͢ let shareList = app.otherElements["ActivityListView"] // ڞ༗ϝχϡʔ͕දࣔ͞ΕΔ·Ͱ࠷େ 2 ඵ଴ͭ

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

    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) } } ςΩετҎ֎ͰଞਓͷΞϓϦͳΒ      
  20. 39.

    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) } } ଞਓͷΞϓϦͳΒ
  21. 41.

    // ڞ༗ϝχϡʔΛ୳͢ let shareList = app.otherElements["ActivityListView"] // ڞ༗ϝχϡʔ͕දࣔ͞ΕΔ·Ͱ࠷େ 2 ඵ଴ͭ

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

    // ͢΂ͯͷηϧ͔Β૸ࠪ let cell = shareList.cells // `Activity` ͷηϧΛநग़ .matching(identifier:

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