为 AWS Device Farm 构建 XCTest UI 测试

Posted

技术标签:

【中文标题】为 AWS Device Farm 构建 XCTest UI 测试【英文标题】:Building XCTest UI tests for AWS Device Farm 【发布时间】:2016-07-26 07:59:50 【问题描述】:

我正在尝试将我们的 ios XCUITest 设置为在 AWS Device Farm 上运行,但似乎无论我如何构建和上传它们,测试都不会运行。它们在 XCode 中本地运行时执行并通过,但不在 AWS Device Farm 上运行。

我已经设置了一个绝对简单的应用程序,我可以设法隔离这个问题。它由一个带有单个标签的视图和一个验证标签是否存在的 UI 测试组成。

这是出现在 AWS Device Farm 界面中的错误。

挖掘日志文件会发现这一点(在“应用程序输出”日志文件中):

2016-04-03 19:07:39.842 XCTRunner[195:28521] Running tests...
2016-04-03 19:07:39.868 XCTRunner[195:28521] Unable to load configuration data from specified path ; error: The file name is invalid.
2016-04-03 19:07:39.872 XCTRunner[195:28521] Looking for test bundles in /var/mobile/Containers/Bundle/Application/883D7F70-E525-4478-9E5E-C87F72A83879/MyTestAppUITests-Runner.app/PlugIns
2016-04-03 19:07:39.875 XCTRunner[195:28521] Found test bundle at /var/mobile/Containers/Bundle/Application/883D7F70-E525-4478-9E5E-C87F72A83879/MyTestAppUITests-Runner.app/PlugIns/MyTestAppUITests.xctest
2016-04-03 19:07:39.878 XCTRunner[195:28521] Looking for configurations in /var/mobile/Containers/Bundle/Application/883D7F70-E525-4478-9E5E-C87F72A83879/MyTestAppUITests-Runner.app/PlugIns/MyTestAppUITests.xctest
2016-04-03 19:07:39.879 XCTRunner[195:28521] No configurations found, creating a default configuration that will run all tests.
2016-04-03 19:07:39.993 XCTRunner[195:28521] XCTestConfigurationHook: Using Test MyTestAppUITests/testExample
2016-04-03 19:07:39.995 XCTRunner[195:28521] XCTestConfigurationHook: Using Test MyTestAppUITests/testExample
2016-04-03 19:07:39.995 XCTRunner[195:28521] XCTestConfigurationHook: Using Test MyTestAppUITests/testExample
Test Suite 'Selected tests' started at 2016-04-03 19:07:40.008
Test Suite 'MyTestAppUITests' started at 2016-04-03 19:07:40.014
Test Case '-[MyTestAppUITests testExample]' started.
2016-04-03 19:07:40.021 XCTRunner[195:28521] *** Assertion failure in -[XCUIApplication init], /Library/Caches/com.apple.xbs/Sources/XCTest_iOS/XCTest-10112/XCTestFramework/UI Testing/XCUIApplication.m:72
2016-04-03 19:07:40.022 XCTRunner[195:28521] XCTestConfigurationHook: Ignoring skipped tests
2016-04-03 19:07:40.023 XCTRunner[195:28521] XCTestConfigurationHook: Using Test MyTestAppUITests/testExample
2016-04-03 19:07:40.025 XCTRunner[195:28521] XCTestConfigurationHook: Using Session ID 75B97C9E-6F14-4F88-A242-64B79C9A0F04
<unknown>:0: error: -[MyTestAppUITests testExample] : failed: caught "NSInternalInconsistencyException", "No target application path specified via test configuration: <XCTestConfiguration: 0x1652af60>
                      testBundleURL:file:///var/mobile/Containers/Bundle/Application/883D7F70-E525-4478-9E5E-C87F72A83879/MyTestAppUITests-Runner.app/PlugIns/MyTestAppUITests.xctest/
             testBundleRelativePath:(null)
                  productModuleName:(null)
                        testsToSkip:(null)
                         testsToRun:MyTestAppUITests/testExample
                 reportResultsToIDE:no
                  sessionIdentifier:<__NSConcreteUUID 0x1655e5c0> 75B97C9E-6F14-4F88-A242-64B79C9A0F04
         pathToXcodeReportingSocket:(null)
          disablePerformanceMetrics:no
    treatMissingBaselinesAsFailures:no
                    baselineFileURL:(null)
           baselineFileRelativePath:(null)
              targetApplicationPath:(null)
          targetApplicationBundleID:(null)
                   reportActivities:no
           testsMustRunOnMainThread:no
             initializeForUITesting:no
"
(
    0   CoreFoundation                      0x22c90123 <redacted> + 150
    1   libobjc.A.dylib                     0x22436e17 objc_exception_throw + 38
    2   CoreFoundation                      0x22c8ffe1 <redacted> + 0
    3   Foundation                          0x23463b19 <redacted> + 92
    4   XCTest                              0x002625a1 -[XCUIApplication init] + 216
    5   MyTestAppUITests                    0x01d8a4b7 -[MyTestAppUITests setUp] + 182
    6   XCTest                              0x002433bf __24-[XCTestCase invokeTest]_block_invoke_2 + 198
    7   XCTest                              0x00274661 -[XCTestContext performInScope:] + 308
    8   XCTest                              0x002432f3 -[XCTestCase invokeTest] + 184
    9   XCTest                              0x00243a4f -[XCTestCase performTest:] + 566
    10  XCTest                              0x00241375 -[XCTestSuite performTest:] + 460
    11  XCTest                              0x00241375 -[XCTestSuite performTest:] + 460
    12  XCTest                              0x0024e88d -[XCTestObservationCenter _observeTestExecutionForBlock:] + 716
    13  XCTest                              0x00275c7f _XCTestMain + 1150
    14  CoreFoundation                      0x22c535b1 <redacted> + 12
    15  CoreFoundation                      0x22c5306d <redacted> + 216
    16  CoreFoundation                      0x22c515e1 <redacted> + 784
    17  CoreFoundation                      0x22ba4bf9 CFRunLoopRunSpecific + 520
    18  CoreFoundation                      0x22ba49e5 CFRunLoopRunInMode + 108
    19  GraphicsServices                    0x23df0ac9 GSEventRunModal + 160
    20  UIKit                               0x26e34ba1 UIApplicationMain + 144
    21  XCTRunner                           0x000fa255 XCTRunner + 33365
    22  libdyld.dylib                       0x22853873 <redacted> + 2
)
Test Case '-[MyTestAppUITests testExample]' failed (0.239 seconds).
Test Suite 'MyTestAppUITests' failed at 2016-04-03 19:07:40.256.
     Executed 1 test, with 1 failure (1 unexpected) in 0.239 (0.242) seconds
Test Suite 'Selected tests' failed at 2016-04-03 19:07:40.259.
     Executed 1 test, with 1 failure (1 unexpected) in 0.239 (0.251) seconds

在我看来,MyAppUITests-Runner.app 应用程序没有包含允许它以正确应用程序为目标的配置文件。所以我怀疑这与我用来构建和上传应用程序及其 UI 测试的过程有关。

我用来生成Application ipa文件的过程是:

    在 Xcode 中,单击产品 > 存档 在管理器窗口中选择存档并单击导出按钮 选择“Save for Ad Hoc Deployment”并点击下一步 选择“使用本地签名资产”进行配置 选择“为所有兼容设备导出一个应用” “包括无线安装清单”未选中 选中“从位码重建” 将 ipa 导出到桌面上的文件夹

我用来生成 UITests ipa 文件的过程是(按照http://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-ios-xctest-ui.html 的说明):

    在 Xcode 中,选择“Generic iOS Device”作为构建目标 点击产品 > 构建 > 测试 打开项目的 XCode Derived Data 文件夹,转到 Build > Intermediates > Debug-iphoneos。这包含 2 个文件:MyTestApp.app 和 MyTestAppUITests-Runner.app 在桌面上创建一个名为“Payload”的新目录 将 MyTestAppUITests-Runner.app 文件复制到 Payload 目录中 右键单击 Payload 并选择“压缩'Payload'” 将生成的 Payload.zip 文件重命名为 mytestapp-uitests.ipa

我也尝试将 MyTestApp.app 和 MyTestAppUITests-Runner.app 都包含到 mytestapp-uitests.ipa 文件中,但这也不起作用。

在 Device Farm 中运行测试:

    在我的测试项目中,点击“新建运行” 选择安卓/iOS 上传之前生成的 MyTestApp.ipa 文件(通过导出存档),然后单击下一步 从列表中选择“XCTest UI”,然后上传 mytestapp-uitests.ipa 文件

    选择设备池,其中包含运行 iOS 9.2.1 的 iPad Air 2、iPad Air 和 iPad 2 将设备状态保留为默认设置 点击开始运行

请注意,如果我使用相同的应用程序 ipa 文件并运行内置的 Fuzz 测试,这些测试不会出现问题——我可以看到带有单个标签的测试应用程序的屏幕截图。

我看不到我遗漏的任何明显的东西。我需要做什么才能完成这项工作?

【问题讨论】:

嘿@telomere,我对生成 UITests 运行器的过程有疑问 - 当我尝试执行 Product > Build For > Testing 时,我遇到了代码签名问题。我收到 CodeSign 错误:SDK 'iOS 9.3' 中的产品类型 'UI Testing Bundle' 需要代码签名,尽管我在 UI 测试目标上选择了 Don't Code Sign。您是否必须创建一个新的应用 ID 才能使其正常工作? 发现问题 - 我缺少通配符开发者资料。 【参考方案1】:

我在 AWS Device Farm 团队工作。 您在下面引用的分析是正确的。

在我看来,MyAppUITests-Runner.app 应用程序没有包含允许它以正确应用程序为目标的配置文件。所以我怀疑这与我用来构建和上传应用程序及其 UI 测试的过程有关。

我们目前正在解决一个问题,即如果 .ipa 中缺少 .xctestconfiguration 文件,则无法提取测试。

在解决此问题以让您运行之前,解决此问题的方法是在本地运行测试,这将在您的 .app/Plugins 文件夹下生成 .xctestconfiguration 文件

在打包上传到设备场之前,只需确保 .xctestconfiguration 文件存在于 .app 捆绑包下

Fuzz 测试将起作用,因为它不使用您的测试代码。它只需要您的应用并针对它运行自定义模糊测试。

关于*-Runner.app 位置的另一个注意事项是,您应该能够在 Xcode 的 Products 文件夹下找到它,但只要您能找到它,一切都应该没问题。

更新 这个问题自发帖以来已得到修复,您的测试运行程序中不再需要 .xctestconfiguration 文件。

【讨论】:

谢谢。如果将来有其他人需要这样做,.xctestconfiguration 文件位于 UITests.xctests 包下,在 UITests-Runner.app 包的 PlugIns 文件夹内。 嘿。当你意识到它会被修复。谢谢! @NikofTime,为了在本地运行测试,我的意思是使用模拟器吗?因为这样做会在Debug-iphonesimulator而不是Debug-iphoneos下生成.xctestconfiguration。当我使用 xxd 检查生成的 .xctestconfiguration 文件时,我看到它引用了我的开发机器独有的路径。最后,当我将生成的文件复制到我的 *-Runner.app/PlugIns 文件夹时,它是在 .xctest 文件夹内还是在它旁边? @NikofTime,Xcode 9 似乎又出现了这个错误。运行使用 Xcode 9 构建的 TestRunner.app 时,你们制作的补丁是否可能被撤消? 这个问题仍然存在,我正在经历它,但我无法构建 xctestconfiguration 文件。我正在设备上运行测试,但我没有看到它完成。有什么想法吗?【参考方案2】:

我有类似的问题。我再挖一点,看来下面可能是测试失败的原因。

“无法从 testmanagerd 接收 XCTest 包就绪消息,错误代码 -7”

似乎 setup 和 teardown 方法默认运行并因此通过。我不确定。但是,我会尝试从日志中获取更多信息。

【讨论】:

您是否找到了更多相关信息?尝试在亚马逊设备场上运行 Ui 测试时,我不断收到此错误【参考方案3】:

一个更简单的解决方案是更改派生数据文件夹的位置 - (在 Xcode Preferences -> Locations 下。

例如,我把它放在我的用户文件夹中(类似于我的文档)

这个错误在战斗数小时后立即消失。 (看起来像一个 Xcode 错误)

【讨论】:

以上是关于为 AWS Device Farm 构建 XCTest UI 测试的主要内容,如果未能解决你的问题,请参考以下文章

AWS Device Farm 的 XCTest 单元和 UI 测试

AWS Device Farm目前支持iOS 10.3.3及更低版本的XCTest

如何在 AWS Device Farm CLI 上的设备池中添加单个设备?

AWS Device Farm - 使用 CLI 时上传失败

如何以编程方式为 AWS-Device Farm 设置 Appium --no-reset 标志

AWS Device Farm上的Appium测试未按指定顺序执行