Ios XCTest测试套件中的共享测试

Ios XCTest测试套件中的共享测试,ios,objective-c,unit-testing,xctest,Ios,Objective C,Unit Testing,Xctest,我有一个类,可以配置为做2件稍有不同的事情。我想测试两条路径。该类是UIViewController的子类,大多数配置在Interface Builder中进行。我需要验证故事板场景和它们的插座是否以相同的方式连接,但还需要检查行为的差异 为此,我想使用共享的XTest套件 一个用于左手,一个用于右手。在使用应用程序时,这两个选项都会相继出现。第一个(右手)触发到另一个的序列。最后一个(左手)应该触发另一个序列。例如,这就是它的不同之处 现在我想用测试来验证这些序列。我想创建一个和sharedt

我有一个类,可以配置为做2件稍有不同的事情。我想测试两条路径。该类是UIViewController的子类,大多数配置在Interface Builder中进行。我需要验证故事板场景和它们的插座是否以相同的方式连接,但还需要检查行为的差异

为此,我想使用共享的XTest套件

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

现在我想用测试来验证这些序列。我想创建一个
和sharedtests
套件,这两个视图控制器实例测试都使用它来验证它们的共同点。然而,
BothHandSharedTests
类被视为一个自包含的测试套件,而它显然不是

我提出了以下策略:

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

你将如何解决这个问题?

我没有一个结论性的答案,但以下是我最后做的

我首先尝试了子类化的方法。在父测试(“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来执行必要的特定于类的设置

然而——这是一个糟糕的解决方案,原因有两个:

  • 它混淆了Xcode测试UI。您无法真正看到正在运行的内容的实时表示,测试有时也无法按预期显示。这使得通过点击调试测试失败变得困难或不可能
  • 它混淆了XCTest本身——我发现即使我没有问他们也会运行测试(如果我只是尝试运行一个测试),因此测试输出不是我所期望的
  • 老实说,拥有那个宏感觉有点不舒服——重定向流控制的宏从来都不是一个好主意
  • 相反,我现在使用的是一个共享对象,
    testcaseheloper
    ,它为每个测试类实例化,并且具有一个所有测试用例都通用的协议/委托模式。它不那个么枯燥——大多数测试用例只是其他测试用例的复制品——但至少它们很简单。这样,Xcode就不会混淆,调试失败仍然是可能的


    更好的解决方案可能必须来自苹果,除非你有兴趣放弃你的整个测试套件去做其他事情。

    以下是Swift中的一个解决方案:

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

    谢谢你能分享一下你的helper协议的功能和外观吗?我不能,但是它对于被测试的类来说是非常特殊的,所以我担心它不会有多大帮助。很抱歉您可以在测试导航器中禁用
    AbstractTestCase
    ,而不是
    DONT\u RUN\u test\u,如果\u PARENT
    我继承的测试也没有像您在(1)中提到的那样显示,但重新启动Xcode修复了它。没想到!好主意,很好用,谢谢。值得注意的是,这种方法有一个弱点:运行实现它的任何测试类都会在抽象类中注释失败,如果同时运行多个测试类,它们的错误将重叠。不调用super是一个非常糟糕的主意。不要这样做。