在 Xcode 8 中,如何在给定的 XCTestCase class 中以特定顺序制作测试方法 运行?

In Xcode 8, what is the way to make test methods run in a particular order within a given XCTestCase class?

在 Xcode 8 之前,您可以通过在给定的 XCTestCase class 中按字母顺序排列测试方法的名称(如所述在 this answer)。例如,测试 运行 如:testA、testB、testC、testD 等。

然而在Xcode8中,情况不再如此。例如,我有名为 test1、test2、test3、test4 和 test4 的测试方法将首先 运行(见下面的屏幕截图)。然后我可以重新运行,test2会先运行下一个运行-through.

那么我如何在 Xcode 8 上按顺序获得 运行 的测试?

所以我解决这个问题的方法如下。

问题回顾:

我需要连续进行几次测试 运行:test1test2test3test4。每个测试都设置了一个期望,测试的最后一步将满足期望,然后测试结束,下一个测试将 运行.

不过在Xcode8中,现在测试运行在运行dom命令中。虽然从这样的角度来看这很好,如果它们是单元测试,它们 应该 能够 运行 在 运行dom 顺序中,它会破坏你的测试,如果它们是设计不是作为单元测试,而是作为 端到端 测试。

例如,在我的例子中,它破坏了测试,因为在第一个测试中,用户登录并设置了一些数据等。然后,第二个测试检查数学,然后第三个测试将数据同步到服务器,然后第四个将其全部删除并从服务器同步下来。当第一次测试 运行s 时,在构建时,shell 脚本从 MSYQL 文件初始化服务器的数据库,然后在应用程序启动时,AppDelegate 为应用程序安装一个新的核心数据数据库.因此,如果我必须在每次测试后重新启动应用程序,shell 脚本将重新初始化服务器数据库并导致应用程序的本地核心数据数据库也重新初始化。这将破坏后续测试(这是一个端到端测试,后续测试取决于应用程序和服务器的状态,在上一次测试之后运行)。

而不是设置四个不同的核心数据启动数据库和四个不同的服务器初始化脚本(这将是一个巨大的痛苦,并且每当我们有模式更改时,端到端测试的管理时间就会成倍增加),或者必须记住 运行 无需连续手动构建每个测试,而是使用以下策略将所有四种测试方法合并为一个非常长的测试方法。

解决方案

首先,在 XCTestCase class 中,我设置了一个测试期望 属性:

@property (nonatomic, strong) XCTestExpectation *endOfTestExpectation;

在我的 XCTestCase class 中 test1 的末尾,我用这个新期望替换了它现有的期望,如下所示:

self.endOfTestExpectation = [self expectationWithDescription:
                                  @"endOfTestExpectation"];

[self waitForExpectationsWithTimeout:900 
                             handler:^(NSError * _Nullable error) {
    /* Code moved from test4's expectation completion block goes here */
}

对于每个 test1test3,我将测试的原始期望完成块内的代码移动到一个名为 completion1completion3 的新方法中。对于 test4,我将其原始期望完成块中的代码移动到 test1 方法末尾的 endOfTestExpectation 的完成块中。

然后我将方法 test2test4 重命名为 t3st2t3st4你让它工作)。在 completion1 方法的末尾,我调用 t3st2;在 completion2 结束时,我调用 t3st3;在 completion3 结束时,我调用 t3st4;在 completion4 结束时我调用 [self.endOfTestExpectation fulfill];.

这实际上比旧方法更好,因为在旧方法中,即使第一次测试失败,后续测试仍然运行!现在,无论 XCTFail 发生在哪里,整个事情都会停止,如果我被选中 SO,我们不会浪费时间 运行 剩下的 :D