【问题标题】:XCTestCase for opening camera and photo libraryXCTestCase 用于打开相机和照片库
【发布时间】:2021-05-20 12:59:20
【问题描述】:

我编写了一个可重用的类,用于打开相机和照片库,如下所示

class CameraAndPhotoManager: NSObject {
    var currentVC: UIViewController!
    
    func camera(vc: UIViewController) {
            currentVC = vc
            if UIImagePickerController.isSourceTypeAvailable(.camera){
                let myPickerController = UIImagePickerController()
                myPickerController.delegate = self
                myPickerController.sourceType = .camera
                myPickerController.mediaTypes = [kUTTypeImage as String, kUTTypeMovie as String]
                currentVC.present(myPickerController, animated: true, completion: nil)
            }
        }
        
    func photoLibrary(vc: UIViewController) {
            currentVC = vc
            if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
                let myPickerController = UIImagePickerController()
                myPickerController.delegate = self
                myPickerController.sourceType = .photoLibrary
                myPickerController.mediaTypes = [kUTTypeImage as String, kUTTypeMovie as String, kUTTypeVideo as String]
                currentVC.present(myPickerController, animated: true, completion: nil)
            }
        }
}

我需要编写 TestCases 来打开相机和照片库。有关编写与相机或照片库相关的测试用例的任何信息?任何示例代码都会有所帮助。

【问题讨论】:

  • 最复杂的(一般情况下可能不可能)是获取权限。此外,您应该为这种情况编写 XCUITest,而不是 XCTest。我为 PHPhotoLibrary API 编写了一堆单元测试 (XCTest),它只有在为应用程序手动添加权限时才有效。此外,它没有任何对 UI 的访问权限(例如 UIImagePickerController)
  • 同意,我也有同感,但我认为可能有一种方法可以访问相机或照片库以进行测试。让我们看看有没有人知道这方面的任何信息。

标签: ios swift xctest xctestcase


【解决方案1】:

您可以对此进行单元测试,但不能使用直接依赖于全局状态的代码。相反,我认为这些是我们想要控制的界限。然后设计测试,让您指定可用的源类型。生产代码需要进行一些更改以支持此边界。

例如,CameraAndPhotoManager 可以定义一个闭包属性。默认情况下,闭包具有生产代码的正常行为:

var isSourceTypeAvailable: (UIImagePickerController.SourceType) -> Bool =
    { UIImagePickerController.isSourceTypeAvailable($0) }

调用这个闭包而不是直接调用UIImagePickerController.isSourceTypeAvailable(_:)。单元测试不会检查默认闭包,因此请务必进行手动测试以确认此更改有效。

现在测试代码可以替换闭包。要测试present(_:animated:completion),请使用ViewControllerPresentationSpy。然后我们可以为每个函数编写两个测试。

func test_camera_withCameraUnavailable_shouldRememberCurrentVCButNotPresentImagePicker() throws {
    let presentationVerifier = PresentationVerifier()
    let sut = CameraAndPhotoManager()
    sut.isSourceAvailable = {
       guard case $0 == .camera else { return false } // Make sure it's camera
       return false // camera unavailable
    }
    let vc = UIViewController()

    sut.camera(vc: vc)

    XCTAssertTrue(sut.currentVC === vc, "Expected currentVC \(vc), but was \(sut.currentVC)"
    XCTAssertEqual(presentationVerifier.presentedCount, 0, "presented count")
}

func test_camera_withCameraAvailable_shouldRememberCurrentVCAndPresentImagePicker() throws {
    let presentationVerifier = PresentationVerifier()
    let sut = CameraAndPhotoManager()
    sut.isSourceAvailable = {
       guard case $0 == .camera else { return false }
       return true // camera available
    }
    let vc = UIViewController()

    sut.camera(vc: vc)

    XCTAssertTrue(sut.currentVC === vc, "Expected currentVC \(vc), but was \(sut.currentVC)"
    let nextVC: UIImagePickerController? = presentationVerifier.verify(
        animated: true,
        presentingViewController: vc
    )
    // Now examine the properties of nextVC. For example:
    XCTAssertEqual(nextVC?.sourceType, .camera, "sourceType")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 2021-07-08
    • 1970-01-01
    相关资源
    最近更新 更多