我可以 运行 多次使用 XCTest 套件吗?

Can I run an XCTest suite multiple times?

是否可以Xcode 运行 你的单元测试多次?

我在几个单元测试中遇到了导致间歇性故障的问题。现在我 认为 我已经修复了它,我唯一的选择似乎是混搭 + U 直到我有 95% 的信心错误已经消失。

我知道其他单元测试框架可以很容易地多次 运行 单个测试、测试用例或测试套件。我们在 XCTest 中有这种奢侈吗?

它可能会帮助你使用

func testMultiple() {
    self.measureBlock() {
            ...
            XCTAssert(errMessage == nil, "no error expected")        
    }
}

这会多次运行 self.measureBlock() 中的代码以测量平均时间。

更改代码是工作,但无论如何您可能想知道执行时间。

这个答案可能很接近你想要的,而且很容易做到。

尝试使用 for 循环:

func testMultiple() {
    for _ in 0...100 {
            ...
            XCTAssert(errMessage == nil, "no error expected")        
    }
}

请注意,这在 self.measureBlock() 中不起作用。你会得到一个 NSInternalConsistencyException: Cannot measure metrics while already measuring metrics

但是,您可以在 measureBlock():

内调用它
func testMultiple() {
    for _ in 0...100 {
            ...
            XCTAssert(errMessage == nil, "no error expected")        
    }
}

func testPerformance() {
    self.measureBlock() {
        self.testMultiple()
    }
}

Xcode 8 运行 measureBlock 代码 10 次。

一种替代方法是通过命令行执行此操作。您可以 运行 使用 -only-testing 参数进行单个测试,并避免使用 test-without-building 进行构建,即(为清楚起见添加了新行)

for i in {1..10}; \
  do xcodebuild \
    test-without-building \
    -workspace MyApp.xcworkspace \
    -scheme Debug \
    -destination 'platform=iOS Simulator,OS=11.2,name=iPhone 8' \
    -only-testing:MyApp.Tests/TestFile/myTest;
done

尝试覆盖调用测试:https://developer.apple.com/documentation/xctest/xctestcase/1496282-invoketest?language=objc

- (void)invokeTest
{
    for (int i=0; i<100; i++) {
        [super invokeTest];
    }
}

对我来说它适用于 swift

override func invokeTest() {
    for time in 0...15 {
        print("this test is being invoked: \(time) times")
        super.invokeTest()
    }
}

我过去曾使用 invokeTest() 覆盖 (Xcode 10) 并取得了巨大成功。但是现在 Xcode 11 它不起作用(至少对我而言)。我最终做的是:

func test99Loop() {
    for i in 0..<LOOP_COUNT {
        if i > 0 { tearDown(); sleep(1); setUp() }
        test3NineUrls()
        do { tearDown(); sleep(1) }
        setUp()
        test6NineCombine()

        print("Finished Loop \(i)")
    }
}

我显然使用 setup/teardown,这是多次执行这些操作的正确方法(因为第一个和最后一个被 Xcode 调用)。