【问题标题】:Shared tests in XCTest test suitesXCTest 测试套件中的共享测试
【发布时间】:2014-06-22 19:08:06
【问题描述】:

我有一个类可以配置为做两件稍微不同的事情。我想测试两条路径。该类是UIViewController 的后代,并且大部分配置都在Interface Builder 中进行。我需要验证 Storyboard Scenes 和它们的 Outlets 是否以相同的方式连接,但还需要检查行为上的差异。

我想为此使用共享的 XCTest 套件。

一个用于左手,一个用于右手。使用该应用程序时,两者都会出现。第一个(右手)触发到另一个的segue。最后一个(左手)应该触发不同的转场。例如,这就是它的不同之处。

现在我想通过测试来验证转场。我想创建一个BothHandSharedTests 套件,两个视图控制器实例测试都使用它来验证它们的共同点。但是,BothHandSharedTests 类被视为一个自包含的测试套件,显然不是。

我想出了这些策略:

  • 从抽象的 XCTest 后代继承,如上所述(似乎没那么容易),
  • 为通用属性编写一个测试套件,并使用两者之一作为被测对象,并为差异添加两个较小的套件。

你会如何解决这个问题?

【问题讨论】:

    标签: ios objective-c unit-testing xctest


    【解决方案1】:

    这是 Swift 中的一个解决方案:

    class AbstractTests: XCTestCase {
    
        // Your tests here
    
        override func perform(_ run: XCTestRun) {
            if type(of: self) != AbstractTests.self {
                super.perform(run)
            }
        }
    }
    

    【讨论】:

    • 效果很好,谢谢。值得注意的是,这种方法有一个弱点:运行任何实现它的测试类都会在抽象类中注释失败,如果同时运行多个测试类,它们的错误会重叠。
    • 不调用 super 是一个非常糟糕的主意。不要这样做。
    【解决方案2】:

    我没有确凿的答案,但这就是我最终要做的。

    我首先尝试了子类化路线。在父测试(“AbstractTestCase”)中,我实现了将由 AbstractTestCase 子类执行的所有测试,但添加了一个宏,因此它们不会被实际的父测试运行:

    #define DONT_RUN_TEST_IF_PARENT if ([[self className] isEqualToString:@"AbstractTestCase"]) { return; }
    

    然后我将此宏添加到每个测试的开头,如下所示:

    - (void)testSomething
    {
        DONT_RUN_TEST_IF_PARENT
    
        ... actual test code ...
    }
    

    这样,在继承自 AbstractTestCase 的 ConcreteTestCase 类中,所有这些测试将被共享并自动运行。当然,您可以覆盖 -setUp 以执行必要的特定于类的设置。

    然而——这被证明是一个糟糕的解决方案,原因有以下几点:

    1. 它混淆了 Xcodes 测试 UI。您并没有真正看到正在运行的实时表示,并且测试有时不会按预期显示。这使得点击调试测试失败变得困难或不可能。
    2. 它使 XCTest 本身感到困惑 – 我发现即使我没有问它们也经常会运行测试(如果我只是尝试运行单个测试),因此测试输出不会是我想要的期待。
    3. 老实说,拥有那个宏感觉有点笨拙 - 重定向流控制的宏从来都不是一个好主意。

    相反,我现在使用共享对象TestCaseHelper,它为每个测试类实例化,并且具有所有测试用例通用的协议/委托模式。它不那么 DRY——大多数测试用例只是其他测试用例的重复——但至少它们很简单。这样Xcode就不会糊涂了,调试失败还是有可能的。

    一个更好的解决方案可能必须来自 Apple,除非您有兴趣放弃整个测试套件以换取其他东西。

    【讨论】:

    • 谢谢!您能分享一下您的辅助协议的作用和外观吗?
    • 我不能,但它非常特定于正在测试的类,所以我担心无论如何它不会有太大帮助。对不起!
    • 您可以在测试导航器中禁用 AbstractTestCase 而不是 DONT_RUN_TEST_IF_PARENT
    • 我继承的测试也没有像您在 (1) 中提到的那样显示,但重新启动 Xcode 修复了它。
    • 没想到!好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 2023-03-09
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    相关资源
    最近更新 更多