【问题标题】:IOS UI Testing - How to write test cases for opening camera and file chooserIOS UI 测试 - 如何编写打开相机和文件选择器的测试用例
【发布时间】:2018-07-29 16:38:33
【问题描述】:

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

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

我的代码如下:

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

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

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

【问题讨论】:

    标签: xctest ios-ui-automation xctestcase


    【解决方案1】:

    我对@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

    在设备上,上面的相机胶卷不起作用,因为通常有很多照片,所以先点击不在屏幕上的照片将无济于事。我最终使用了以下 sn-p:

    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()
      }
    }
    

    【讨论】:

    • 感谢@caffenium 的回答。
    • 非常感谢。会试试这个。
    • @caffeinum addPhotoCamera 功能不工作,在photoCapture.tap() Multiple matches found for Other. Sparse tree of matches: →Application, pid: 662 ↳Window (Main) ↳Other ↳Other ↳Other ↳Other ↳Other ↳Other ↳Other ↳Other ↳Other
    • @JibranSiddiQui 也许元素树比一年前有所改变。您看到的是使用 Xcode 中的 Record 功能生成的。您可以尝试重新录制,然后用新记录替换损坏的部分
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-10-14
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-26
      • 2015-12-08
      • 1970-01-01
      相关资源
      最近更新 更多