【问题标题】:Is it possible to run XCTest tests in an iOS app?是否可以在 iOS 应用程序中运行 XCTest 测试?
【发布时间】:2017-09-28 15:18:22
【问题描述】:

我们有一个用 XCTest 编写的后端测试套件。该套件在 Xcode 中运行良好,但出于各种原因,如果我们也可以在 iOS 应用程序中运行该套件,那对我们来说会很好。那可能吗?我不介意为它写一些胶水代码,但我什至不能在非测试目标中导入 XCTest 框架:

SomeController.swift:2:8: Cannot load underlying module for 'XCTest'

【问题讨论】:

  • 你想达到什么目的?
  • 这将是我们的工程师根据调试应用程序按需运行后端测试套件的一种简单方便的方式。
  • 这是相当不寻常的事情。我会根据需要运行 Jenkins(或任何其他 CI),而不是应用程序本身。
  • 澄清一下,测试不是被测试应用程序的一部分。他们测试服务器组件。我也认为在 CI 服务器上运行它们是正确的解决方案,但在我们获得 CI 服务器之前,我希望有一种无需开发人员机器即可运行测试的简单方法。
  • 好的,那么它不应该是 XCTest 测试,而是一些自定义代码和自定义 UI 来显示结果。

标签: ios testing xctest


【解决方案1】:

有可能!关键是获取 XCTest 框架链接的副本,然后使用公共 XCTest API 运行测试。这将为您提供通过 Xcode 运行测试时看到的相同控制台输出。 (使用公共 API 连接您自己的自定义报告器看起来是可行的,但询问如何这样做本身就是一个好问题 - 使用 XCTest API 的人并不多,因为 Xcode 为我们完成了繁琐的工作。)

在 XCTest.framework 中复制

您可以从目标平台的平台框架中将 XCTest.framework 包复制到您的项目中,而不是解开任何破坏模块加载的问题:

mkdir Frameworks && mkdir Frameworks/iphonesimulator
PLATFORMS=/Applications/Xcode.app/Contents/Developer/Platforms
FRAMEWORKS=Developer/Library/Frameworks
cp -Rp \
    "$PLATFORMS/iPhoneSimulator.platform/$FRAMEWORKS/XCTest.framework" \
    Frameworks/iphonesimulator/

链接到您自己的 XCTest

然后,弹出打开主应用目标的目标编辑器,然后将副本从 Finder 拖放到“链接框架和库”列表中。

将您的测试构建到主应用目标中

现在,转到您的测试文件,弹出文件检查器,然后勾选这些文件的主应用目标旁边的框。现在,您正在构建测试文件作为主应用程序的一部分,这会将所有 XCTestCase 子类放入二进制文件中。

运行这些测试

最后,将“运行测试”按钮连接到如下操作:

import UIKit
import XCTest

class ViewController: UIViewController {
    @IBAction func runTestsAction() {
        print("running tests!")
        let suite = XCTestSuite.default()
        for test in suite.tests {
            test.run()
        }
    }
}

当您点击按钮时,您会在控制台中看到:

running tests!
Test Suite 'RunTestsInApp.app' started at 2017-05-15 11:42:57.823
Test Suite 'RunTestsInAppTests' started at 2017-05-15 11:42:57.825
Test Case '-[RunTestsInApp.RunTestsInAppTests testExample]' started.
2017-05-15 11:42:57.825 RunTestsInApp[2956:8530580] testExample()
Test Case '-[RunTestsInApp.RunTestsInAppTests testExample]' passed (0.001 seconds).
Test Case '-[RunTestsInApp.RunTestsInAppTests testPerformanceExample]' started.
/Users/jeremy/Workpad/RunTestsInApp/RunTestsInAppTests/RunTestsInAppTests.swift:34: Test Case '-[RunTestsInApp.RunTestsInAppTests testPerformanceExample]' measured [Time, seconds] average: 0.000, relative standard deviation: 122.966%, values: [0.000002, 0.000001, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[RunTestsInApp.RunTestsInAppTests testPerformanceExample]' passed (0.255 seconds).
Test Suite 'RunTestsInAppTests' passed at 2017-05-15 11:42:58.081.
     Executed 2 tests, with 0 failures (0 unexpected) in 0.256 (0.257) seconds
Test Suite 'RunTestsInApp.app' passed at 2017-05-15 11:42:58.081.
     Executed 2 tests, with 0 failures (0 unexpected) in 0.256 (0.258) seconds

【讨论】:

  • 这看起来很棒,迫不及待地想测试一下。谢谢!
  • :0: error: -[MyProjectTests testExample] : failed: 捕获“NSInternalInconsistencyException”,“没有通过测试配置指定目标应用程序路径:(null)”
  • 这对我有用,如果有人遇到问题,我在此答案中描述了一些调整:stackoverflow.com/questions/54147582/…
  • 在 Xcode 11.3.1 上,我们还需要复制和链接 XCTAutomationSupport.framework。我们可以在脚本中添加:cp -Rp \ "$PLATFORMS/iPhoneSimulator.platform/$FRAMEWORKS/../PrivateFrameworks/XCTAutomationSupport.framework" \ Frameworks/iphonesimulator/ 并拖放XCTAutomationSupport.framework
  • 在 Xcode 11.5 上,我们还需要复制和链接 libXCTestSwiftSupport.dylib,位于 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib 文件夹中。
猜你喜欢
  • 2011-06-12
  • 1970-01-01
  • 2014-01-28
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
相关资源
最近更新 更多