由于 otest 错误,无法从命令行运行 Xcode 单元测试

Posted

技术标签:

【中文标题】由于 otest 错误,无法从命令行运行 Xcode 单元测试【英文标题】:Unable to run Xcode unit tests from the command line due to otest error 【发布时间】:2013-06-05 05:29:02 【问题描述】:

我正在尝试从命令行运行单元测试,但它们在 Xcode 4.6 中运行完美时失败了。我无法弄清楚失败的原因是什么:

这是我正在使用的命令:

xcodebuild -sdk iphonesimulator -project myproject.xcodeproj 
    -scheme 'MyProjectApplicationTests' 
    -configuration Debug clean build 
    RUN_UNIT_TEST_WITH_ios_SIM=YES TEST_AFTER_BUILD=YES TEST_HOST=''

我在测试中没有使用 NSURL 或“initFileURLWithPath”。这是错误:

/Applications/Xcode.app/Contents/Developer/Tools/RunPlatformUnitTests.include:412: note: Started tests for architectures 'i386'
Run unit tests for architecture 'i386' (GC OFF)
/Applications/Xcode.app/Contents/Developer/Tools/RunPlatformUnitTests.include:419: note: Running tests for architecture 'i386' (GC OFF)
2013-06-04 22:09:57.605 otest[85321:707] Unknown Device Type. Using UIUserInterfaceIdiomPhone based on screen size
2013-06-04 22:09:57.624 otest[85321:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
*** First throw call stack:
(0xa05012 0x71ce7e 0xa04deb 0x2a9b1 0x2a93b 0x4d3c5c9 0x71d7cf 0x724a0d 0x71baeb 0x71be22 0x72e0e1 0x2010879a 0x20106ef5 0x20107124 0x20107196 0x2010624c 0x201063da 0x7305c8 0x2342 0x25ef 0x268c 0x2001 0x1f71)
libc++abi.dylib: terminate called throwing an exception
/Applications/Xcode.app/Contents/Developer/Tools/RunPlatformUnitTests.include: line 415: 85321 Abort trap: 6           "$THIN_TEST_RIG" "$OTHER_TEST_FLAGS" "$TEST_BUNDLE_PATH"
/Applications/Xcode.app/Contents/Developer/Tools/RunPlatformUnitTests.include:451: error: Test rig '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/Developer/usr/bin/otest' exited abnormally with code 134 (it may have crashed).

如果有办法打印出调用堆栈(英文),我也许可以找出错误的来源。

【问题讨论】:

您正在尝试运行应用程序测试而不是逻辑测试,不是吗?你已经正确安装了ios-sim 我有 iOS 模拟器应用程序,但当我在命令行输入“ios-sim”时,什么都没有。清单 /Applications/Xcode.app/Contents/Applications 显示我有“iPhone Simulator.app”。 关于应用程序测试与单元测试的区别,这是作为测试包创建的目标。我不确定是什么将测试区分为“逻辑测试”与“应用程序测试”——整个概念对我来说似乎很奇怪。尽管如此,测试都来自 SenTestCase。 正如@GayleDDS 所说,应用程序测试是作为应用程序的一部分执行的,这意味着 Xcode 将需要运行模拟器。逻辑测试只需要执行被 testet 的类。可以在TEST_HOST 构建配置变量中看到差异。如果它设置为您的应用程序可执行文件,则目标正在运行应用程序测试,如果它为空,它将运行逻辑测试。看看下面的帖子:Xcode 4: Run tests from the command line (xcodebuild)?。或者清除测试目标中的 TEST_HOST 变量。 【参考方案1】:

问题是 xcodebuild 本身不支持模拟器中的应用程序测试。要从命令行在模拟器中运行应用程序测试,您需要一个开源实用程序 ios-sim 和一个 tweek 到您的测试目标运行脚本。

1) 安装ios-sim https://github.com/phonegap/ios-sim

$ curl -L https://github.com/phonegap/ios-sim/zipball/1.9.0 -o ios-sim-1.9.0.zip
$ unzip ios-sim-1.9.0.zip 
$ cd phonegap-ios-sim-538ef1a/
$ sudo rake install prefix=/usr/local/

2) 编辑您的测试目标运行脚本。该脚本来自 Atlassian 的精彩文档。我喜欢 JIRA、Stash、Confluence 的 Atlassian 制造商,以及我最好的新朋友 SourceTree。完全披露他们收购了 SourceTree,它的开发者随后免费发布了它。

替换现有的:

# Run the unit tests in this test bundle.
"$SYSTEM_DEVELOPER_DIR/Tools/RunUnitTests"

有了这个:(来源https://confluence.atlassian.com/display/BAMBOO/Xcode)

if [ "$RUN_UNIT_TEST_WITH_IOS_SIM" = "YES" ]; then
    test_bundle_path="$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.$WRAPPER_EXTENSION"
    ios-sim launch "$(dirname "$TEST_HOST")" --setenv DYLD_INSERT_LIBRARIES=/../../Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection --setenv XCInjectBundle="$test_bundle_path" --setenv XCInjectBundleInto="$TEST_HOST" --args -SenTest All "$test_bundle_path"
    echo "Finished running tests with ios-sim"
else
    "$SYSTEM_DEVELOPER_DIR/Tools/RunUnitTests"
fi

3) 运行测试

xcodebuild \
    -sdk iphonesimulator6.1 \
    -project DC\ Wire\ Sizer.xcodeproj \
    -target DC\ Wire\ Sizer\ Tests \
    -configuration Debug \
    RUN_UNIT_TEST_WITH_IOS_SIM=YES 

...

Test Suite 'All tests' finished at 2013-06-06 16:03:35 +0000.
Executed 104 tests, with 0 failures (0 unexpected) in 0.991 (1.063) seconds

Finished running tests with ios-sim
Showing first 200 notices only


** BUILD SUCCEEDED **

有用的命令:

xcodebuild -showsdks

$ xcodebuild -showsdks
OS X SDKs:
    Mac OS X 10.7                   -sdk macosx10.7
    OS X 10.8                       -sdk macosx10.8

iOS SDKs:
    iOS 6.1                         -sdk iphoneos6.1

iOS Simulator SDKs:
    Simulator - iOS 4.3             -sdk iphonesimulator4.3
    Simulator - iOS 5.0             -sdk iphonesimulator5.0
    Simulator - iOS 5.1             -sdk iphonesimulator5.1
    Simulator - iOS 6.0             -sdk iphonesimulator6.0
    Simulator - iOS 6.1             -sdk iphonesimulator6.1

xcodebuild -list -project

$ xcodebuild -list -project DC\ Wire\ Sizer.xcodeproj
Information about project "DC Wire Sizer":
    Targets:
        DC Wire Sizer
        DC Wire Sizer Tests
        In Work Unit Test

    Build Configurations:
        Debug
        Release_AppStore
        Release_TestFlight

    If no build configuration is specified and -scheme is not passed then "Release_AppStore" is used.

    Schemes:
        DC Wire Sizer
        DC Wire Sizer - App Store
        InWorkUnitTest

应用测试与逻辑测试 为新项目创建的单元测试目标是应用程序单元测试。它通过在构建设置中设置 BUNDLE_LOADER 和 TEST_HOST 将您的测试代码注入应用程序。 您从 New Target 菜单创建的测试目标是逻辑测试。逻辑测试独立于您的应用程序。

这是我的 Bundle Loader 和测试主机值。

Bundle Loader: $(BUILT_PRODUCTS_DIR)/DC Wire Sizer.app/DC Wire Sizer
Test Host:     $(BUNDLE_LOADER)

潜在问题:如果您安装了多个 Xcode 版本。然后你需要检查你的 xcode-select 设置:

gdunham: ~$ xcode-select -print-path
/Applications/Xcode.app/Contents/Developer

【讨论】:

我仍在运行 10.8.3 并且没有任何 10.8.4 用户看到的模拟器崩溃。测试包是前一段时间创建的(不确定在哪个版本的 Xcode 中) - 有什么方法可以辨别项目是否有应用程序或逻辑测试? 是的,如果设置了捆绑加载器,请在链接部分检查测试目标的构建设置。这是一个应用程序单元测试。 @PaulHansen 更新了答案以检查您的 xcode-select 设置。 $ xcode-select -print-path 返回:/Applications/Xcode.app/Contents/Developer 在链接下:Bundle Loader 设置为:build/[Debug|Release]-iphoneos/MyApp.app/MyApp

以上是关于由于 otest 错误,无法从命令行运行 Xcode 单元测试的主要内容,如果未能解决你的问题,请参考以下文章

从 Jenkins 运行时 xcodebuild 失败(在终端中工作)

无法从 xampp 命令行运行 python 程序

仪器无法从命令行启动

如何使用多个包从命令行运行 Selenium testNG 文件?

为什么python无法读取环境变量并且无法运行Windows命令行?

由于以下错误,无法运行任何 npm 命令 - 错误:找不到模块“semver”