rootViewController呈现视图时的单元测试?

时间:2018-02-16 20:19:26

标签: ios swift xctest presentviewcontroller rootviewcontroller

我试图对一个在viewController外面显示视图的函数进行单元测试:

public func presentInOwnWindow(animated: Bool, completion: (() -> Void)?) {
        let alertWindow = UIWindow(frame: UIScreen.main.bounds)
        alertWindow.rootViewController = UIViewController()
        alertWindow.windowLevel = UIWindowLevelAlert + 1;
        alertWindow.makeKeyAndVisible()
    alertWindow.rootViewController?.present(self, animated: animated, completion: completion)
    }

到目前为止,我所能考虑如何进行单元测试就像这样:

  func test_presentInOwnWindow () {

       let presented = sut.presentInOwnWindow(animated: true) {}

        XCTAssertNotNil(presented)
    }

我已经尝试通过bool完成块:

  

完成:((Bool) - > Void)

但是因为它调用了完成:

  

RootViewController的?.present

我收到错误:

  

无法转换类型'((Bool) - > Void)的值?'预期的论点   输入'(() - > Void)?'

知道如何正确地测试功能吗?

2 个答案:

答案 0 :(得分:0)

具有副作用的单元测试代码可能非常难,尤其是如果副作用涉及硬件,如设备屏幕。因此,UI组件不适合单元测试,因为它们通常涉及GPU操作。

现在,如果您真的想测试该组件,可以通过两种方式:

  • 你写快照测试
  • 将所有业务逻辑提取到专用类中并对其进行测试。

结论:对业务代码进行单元测试,并让QA测试UI的行为符合预期。

答案 1 :(得分:0)

尝试几种方法:

  1. Swizzle UIViewController' present(_, animated, completion)来捕捉所呈现的内容。我为UIAlertControllers https://qualitycoding.org/testing-uialertcontroller/执行此操作,但这是因为UIAlertControllers非常常见。您的自定义窗口可能不值得。
  2. 不确定这是否有效。 makeKeyAndVisiblepresent可能不会产生直接影响。相反,他们安排工作。因此,您可以尝试使用RunLoop.current.run(until: Date())来运行运行循环。这适用于激活文本字段,但我不知道它是否适合您。
  3. 同样,尝试添加XCTestExpectation和waitForExpectations以及超时。正如我在https://qualitycoding.org/asynchronous-tests/中所述,不要在期望处理程序中做任何断言。相反,捕获您想要的信息并fulfill期望。然后断言你已捕获的内容。
  4. 更改您编写的代码,以便更轻松地进行测试。通过调用保存在SUT中的属性中的块来替换最后一行。要进行测试,请更换此块。测试块可以调用完成处理程序,它为您提供了一种测试处理程序的方法。
  5. 手动测试此代码,令您满意。然后嘲笑它,所以你的测试检查这个方法是否被调用(但实际上并没有调用它)。