将 XCTests measure() 限制为一个 运行

Limiting XCTests measure() to one run only

作为我正在编写的 UI 测试的一部分,我想衡量一个功能的性能。测试本身需要一段时间,而且我要测量的部分很小,而且测试足够频繁 运行,每次 运行 只需一次测量就可以获得我需要的数据。不过,XCTestCase 的 measure(_:) 会 运行 10 次。

是否有任何选项我可以给它或 measureMetrics(_:automaticallyStartMeasuring:for:) 到 运行 测量一次,或者我有什么方法可以自己进行测量并将其反馈到测试中 运行ner 所以它与 Xcode 集成的方式与 measure(_:) 一样?

这很烦人。

尽管在Xcode11中,您可以将XCTMeasureOptions when calling self.measure { }, i.e., measure(options: XCTMeasureOptions, block: () -> Void). In the options, you can set iterationCount指定为1。

但是!

设置 iterationCount 为 1,Xcode 实际上 运行 测量块两次,根据 iterationCount:

的文档

A performance test runs its block iterationCount+1 times, ignoring the first iteration and recording metrics for the remaining iterations. The test ignores the first iteration to reduce measurement variance associated with “warming up” caches and other first-run behavior.

它在实践中做了 运行 两次。

同时将 iterationCount 设置为 0 不会产生任何结果,根据文档原因:

... iterationCount+1 times, ignoring the first iteration and recording metrics for the remaining iterations

不知道改变测量次数能不能去掉预热运行

解决方法

设置一个计数器...

  1. 跳过第一个 运行:
    func testYourFunction() {
        let option = XCTMeasureOptions()
        option.iterationCount = 1
        var count = 0
        self.measure(options: option) {
            if count == 0 {
                count += 1
                return
            }
            // Your test code...
        }
    }
  1. 回滚更改:
    func testYourFunction() {
        let option = XCTMeasureOptions()
        option.iterationCount = 1
        var count = 0
        self.measure(options: option) {
            defer {
                if count == 0 {
                    try? setUpWithError()
                    // call `setUpWithError` manually
                    // or run your custom rollback logic
                }
                count += 1
            }
            // Your test code...
    }