1

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

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

我的代码如下:

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

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

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

4

2 回答 2

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 测试中相机的辅助函数:

 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()
  }
}
于 2018-03-02T15:16:11.597 回答
1

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

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 行选择两个选项中的 1 个,即“时刻”和“相机胶卷” 第 2 行从列表中选择 1 个图像 第 3 行和第 4 行确认并设置图像。

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

于 2018-02-19T13:10:12.670 回答