XCTMemoryMetric 未在 Xcode 12.5 (XCTest)

时间:2021-05-02 18:42:12

标签: ios swift xcode unit-testing xctest

背景

我已经实现了一个 Swift 算法,我想在该算法中在运行时消耗低内存(空间复杂度)。因此,我想使用 XCTMemoryMetric 作为“单元测试包”的一部分为大输入编写性能测试。我需要跟踪这个算法的回归和优化,所以我最初想跟踪基线指标,并希望这对我的 iOS 应用程序开箱即用。不幸的是,即使在阅读了 Performance Tests 的 Apple 文档后,我也没有找到任何潜在的修复或信息来帮助我解决我的特定问题。

我的主要目标(UIKitStoryboard)使用 iOS Base SDK,Xcode 中的“单元测试包”使用相同的 Base SDK。在 Xcode 中,我将默认的“仅构建活动架构”设置保留为“是”,并且主目标也编译,并且测试编译正常。但是,当我完成运行 measure 块并添加 XCTMemoryMetric()XCTClockMetric() 作为唯一参数时,内存指标不会显示在测试报告中。时钟指标也完全不可靠,即使使用相同的功能,由于高标准偏差,我的测试(几乎)每次都失败!无论如何,这个问题的重点是内存指标。

成功编译示例: example of successful compilation

注意:我还尝试了其他指标,例如 XCTCPUMetric 进行性能测试,但也没有显示结果。

缺少内存指标的示例: example of missing memory metrics

我没有在控制台中收到警告消息或异常。

我尝试过的:

  1. 将算法移至 Swift Package Target 并将性能测试移至 Package Unit Testing Bundle - 内存指标显示在测试日志中。尽管如此,它仍然非常不可靠(有时甚至会显示负面内存分配?!)。这个解决方案并不理想,因为我不想为单个算法创建一个包。
  2. 将算法移至具有相关 Mac-only TargetUnit Testing Bundle - 有效,但同样不适用于仅限 iOS 的应用。
  3. 使用 metric.reportMeasurements() 进行调试显示指标中缺少 _data 参数并在运行时崩溃:

example of runtime crash when reporting

  1. 运行单个测试用例而不是整个套件并没有什么区别。
  2. 测试更大的输入数组大小也没有什么区别。

有没有什么干净的方法可以在不更改我的基础 SDK 的情况下解决我的问题?我正在考虑放弃 XCTest 进行性能测试,因为它似乎不太好用,但理想情况下,我想坚持使用 Apple 推荐的 API。您还可以看到代码似乎完全运行在堆栈内存上(没有 static letvar),所以我不认为堆栈和堆内存之间的混淆是根本原因。

代码:

我已经发布了我正在测试性能的算法的 gist,因为代码行太多,无法包含在这里。即使在 measure 块中使用其他(较少内存密集型)代码,该问题对我来说也是可以重现的。

测试代码:

func testPerformanceExample() {
    let metric = XCTMemoryMetric()
    measure(metrics: [metric],
            block: {
      var sums: [[[Int]]] = []
      (1...100).forEach { _ in
        sums.append(QOneSolutionOne().fourSum([1, 0, -1, 0, -2, 2, 3, -3, 0, 4,
                                               -2, 5, -4, 6, -6, 7, -8, 8, -7],
                                              target: 0))
      }
    })
  }

我认为这可能是一个 XCTest 错误,但我想看看我是否遗漏了什么。欢迎任何建议,谢谢。

0 个答案:

没有答案