限制XCTests measure()仅限一次运行

时间:2018-02-21 11:29:42

标签: ios xcode xctest xctestcase

作为 UI 测试的一部分我写作,我想衡量一项功能的性能。测试本身需要一段时间,而我想要测量的部分很小,并且测试经常运行得足以得到我需要的数据,每次运行只需要一次测量。但是,XCTestCase的measure(_:)将运行10次。

有没有我可以给它的选项或measureMetrics(_:automaticallyStartMeasuring:for:)只运行一次测量,或者我有什么方法可以自己进行测量并将其反馈给测试运行器,以便它与Xcode集成方式measure(_:)呢?

1 个答案:

答案 0 :(得分:0)

这很烦人。

在Xcode 11中,您可以在调用self.measure { }时指定XCTMeasureOptions,即measure(options: XCTMeasureOptions, block: () -> Void)。在options中,您可以将iterationCount设置为1。

但是!

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

性能测试会运行其块迭代次数+ 1次,而忽略第一次迭代并记录其余迭代的指标。该测试忽略了第一次迭代,以减少与“预热”缓存和其他首次运行行为相关的测量差异。

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

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

... erationCount + 1次,忽略第一次迭代并记录其余迭代的指标

我不知道更改测量计数的Runtime Swizzling way是否可以摆脱预热过程。

解决方法

设置一个计数器来...

  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...
    }