【问题标题】:How do I unit test iOS view controllers?如何对 iOS 视图控制器进行单元测试?
【发布时间】:2015-11-16 03:59:25
【问题描述】:

我应该如何在 iOS 应用程序中对我的视图控制器(UIViewController 子类)进行单元测试?

在过去的几天里,我一直在广泛地搜索这个主题,但我仍然不明白这样做的正确方法是什么。

看来单元测试视图控制器逻辑至少有三种方式:

  • 公开您想要进行单元测试的私有操作和 IBOutlets(在头文件中声明它们)。

  • 使用Tests 等类别从单元测试中访问私有操作和IBOutlets。

  • 不要暴露任何东西,而是通过标题或其他公共属性查找按钮和其他视图,并通过公共 UIView 方法模拟用户交互(例如,模拟用户点击按钮);然后观察可见状态。

    我没有找到很多关于这个的来源,但是objc.io上有一个例子。

现在,老实说,我不太喜欢前两个,因为据我了解,单元测试不应该测试对象的内部结构(即私有方法),并且仅为了测试而将它们声明为公开并不这似乎不是最佳做法。我通常将 IBActions 和 IBOutlets 保留在实现中,但现在我突然不得不公开所有内容,只是因为我要添加测试......

我认为可能还有另一种选择:将尽可能多的逻辑从我的视图控制器转移到独立的组件中,然后测试它们(让控制器未经测试或大部分未经测试)。这似乎是个好主意,但我必须进行大量重构(我目前正在为一个没有考虑测试的项目添加单元测试)。

所以我想知道,测试视图控制器的最佳方法是什么?

【问题讨论】:

    标签: ios unit-testing uiviewcontroller


    【解决方案1】:

    这个问题可能主要是基于意见的,应该关闭,但无论如何我都会发表一些我的意见。

    IBActionIBOutlet 并不是真正的私有方法/属性。您可以将它们声明为私有方法/属性,但从概念上讲,它们是您的视图控制器的公共接口。它们是与视图交流的方式。因此,我更喜欢第二种方式,使用一个类别,如UI,从单元测试中访问私有操作和 IBOutlets。

    我完全反对单元测试的第三种方式。因为根据定义,您正在编写集成测试而不是单元测试。它严重依赖于实现细节并且很容易崩溃。您可能需要其中一些,但您应该先完成单元测试。

    如您所知,真正的解决方案是重构代码以使其可测试。理想情况下,控制器应该非常小,并且只充当视图和模型之间的绑定。如果您有非常大的控制器,您应该将 UI 逻辑重构为视图/视图模型,并将业务逻辑重构为模型/模型助手。

    【讨论】:

    • 您应该如何通过类别测试按钮和 IBAction?在测试文件中声明类别,然后是函数,然后调用它?然后如何验证 UI 是否已更改?
    • 您将 IBActions 放在类别中,以便您可以在测试中调用它们。要验证 UI,您可以检查视图的框架,也可以使用截图测试工具,如 github.com/facebook/ios-snapshot-test-case
    • 有没有更好的方法来测试 IBActions?我不想仅为测试用例向我的模型添加代码,即使它只是包含在测试目标中的一个类别。我是否应该尝试对 IBActions 进行单元测试?我应该改用 UI 测试吗?
    • 视图控制器在大多数情况下都不是单元测试的好目标。 UI 测试大大简化了它。
    猜你喜欢
    • 2012-04-24
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    相关资源
    最近更新 更多