IOS UI测试 - 如何编写用于打开相机和文件选择器的测试用例

时间:2018-02-19 12:29:40

标签: xctest ios-ui-automation xctestcase

我正在使用XCTest框架为IOS编写测试用例。我想选择一张用于设置用户个人资料的照片,可以通过两种方式完成: 1.使用相机拍摄图像。 2.从文件选择器中选择图像。

我遇到以下问题: 我正在模拟器上运行这个测试。那么,如何访问相机? 2.我可以通过点击“选择相册”打开页面文件选择页面。但是,无法检测页面文件选择页面上的点击。

我的代码如下:

app.buttons["Choose from Photo Album"].tap()
app.tables.firstMatch.cells.element(boundBy: 0).tap()

第2行给出了错误:     NSInternalInconsistencyException无效参数不满足

没有找到上述案例的单一文件。

2 个答案:

答案 0 :(得分:2)

我对@ deepak-terse的答案有所补充:

您可以使用索引而不是字符串文件名,因此您不依赖于模拟器。

func selectFromCameraRoll(_ app: XCUIApplication, index: Int = 1) {
    app.tables.cells.element(boundBy: 1).tap()
    app.collectionViews.cells.element(boundBy: index).tap()
}

您甚至可以使用arc4random_uniform()

随机化所选照片

<强>更新

如果有人发现这个可用,这里是在我在真实设备上测试时使用的UI测试中Camera的帮助函数:

 func addPhotoCamera(_ app: XCUIApplication) {
   let pleaseSelectSheet = app.sheets.element

   // Take Picture button, it is first:
   pleaseSelectSheet.buttons.element(boundBy: 0).tap()

   // this monstrosity finds Capture button
   let element = app
       .children(matching: .window).element(boundBy: 0)
       .children(matching: .other).element
       .children(matching: .other).element
       .children(matching: .other).element
       .children(matching: .other).element

   let photoCapture = element.children(matching: .other).element
       .children(matching: .other).element(boundBy: 1)
       .children(matching: .other).element

   photoCapture.tap()

   // I have slow computer, so I need this so test does not fail
   sleep(5)

   app.buttons["Use Photo"].tap()
 }

更新2

在设备上,上面的相机胶卷无法正常工作,因为通常会有很多照片,因此首先点击不在屏幕上的照片不会有帮助。我最终使用了以下代码段:

let photoCells = app.collectionViews.cells
if Platform.isSimulator {
    photoCells.element(boundBy: index).tap()
} else {
    photoCells.allElementsBoundByIndex.last!.firstMatch.tap()
}

其中Platform.isSimulator部分来自https://stackoverflow.com/a/30284266/2875219

import Foundation

struct Platform {
   static var isSimulator: Bool {
      return TARGET_OS_SIMULATOR != 0
   }
}

将整段代码放在一起:

struct Platform {
    static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0
    }
}


extension XCUIElement {
    func tapIfExists() {
        if exists {
            tap()
        }
    }
}

// MARK: - Helper functions
extension XCTestCase {
  func addPhotoCamera(_ app: XCUIApplication) {
    let pleaseSelectSheet = app.sheets.element

    //        ["Take Picture"].tap()
    pleaseSelectSheet.buttons.element(boundBy: 0).tap()

    // use coordinates and tap on Take picture button
    let element = app
        .children(matching: .window).element(boundBy: 0)
        .children(matching: .other).element
        .children(matching: .other).element
        .children(matching: .other).element
        .children(matching: .other).element

    let photoCapture = element.children(matching: .other).element
        .children(matching: .other).element(boundBy: 1)
        .children(matching: .other).element

    photoCapture.tap()

    sleep(5)

    app.buttons["Use Photo"].tap()
  }

  func addPhotoLibrary(_ app: XCUIApplication, index: Int = 0) {
    let pleaseSelectSheet = app.sheets["Add Photo"]

    pleaseSelectSheet.buttons.element(boundBy: 1).tap()

    sleep(10)

    // Camera Roll
    app.tables.cells.element(boundBy: 1).tap()

    sleep(2)

    let photoCells = app.collectionViews.cells
    if Platform.isSimulator {
        photoCells.element(boundBy: index).tap()
    } else {
        photoCells.allElementsBoundByIndex.last!.firstMatch.tap()
    }

    sleep(2)

    app.buttons["Choose"].tapIfExists()
  }
}

答案 1 :(得分:0)

我能够解决第二个用例的问题,即使用文件选择器设置图像。这是我的代码。

app.tables.cells.element(boundBy: 1).tap()
app.collectionViews["PhotosGridView"].cells["Photo, Landscape, March 13, 2011, 5:47 AM"].tap()
app.buttons["Choose"].tap()
app.buttons["Confirm"].tap()

第1行选择两个选项中的一个,即“Moments”和“Camera Roll” 第2行从列表中选择1个图像 第3行和第4行确认并设置图像。

但是我想知道它是否适用于不同的模拟器,因为图像的日期和时间可能在该模拟器上有所不同。