Ste*_*ner 47 xcode unit-testing xcodebuild ocunit xcode4
我在Xcode 4中创建了一个全新的iOS项目,并包含了单元测试.默认应用程序有2个目标,主应用程序和单元测试包.使用"产品>测试"(Command-U)构建应用程序,构建单元测试包,启动iOS模拟器并运行测试.现在,我希望能够从命令行执行相同的操作.命令行工具(xcodebuild)没有"测试"操作,但似乎我应该能够直接构建单元测试包目标,因为它取决于应用程序本身.但是,运行:
xcodebuild -target TestAppTests -sdk iphonesimulator4.3 -configuration Debug build
Run Code Online (Sandbox Code Playgroud)
给出以下消息:
/Developer/Platforms/iPhoneSimulator.platform/Developer/Tools/Tools/RunPlatformUnitTests:95: warning: Skipping tests; the iPhoneSimulator platform does not currently support application-hosted tests (TEST_HOST set).
Run Code Online (Sandbox Code Playgroud)
这似乎是一个谎言,因为当我从GUI运行Command-U时,为我的单元测试包目标设置了测试主机.我之前看过有关逻辑测试和应用程序测试之间分离的帖子,但似乎Xcode 4消除了这种区别.我是如何从命令行运行测试的?
Sco*_*son 48
使用Xcode 5.1(也许早期的Xcode)test
是一个有效的构建操作.
我们能够使用test的构建操作和适当的-destination
选项调用xcodebuild来替换下面的整个hack . man xcodebuild
了解更多信息.
以下信息留给了后人
我试图破解Apple的脚本来运行单元测试
和
网上有很多类似的帖子.
但是,我遇到了这些解决方案的问题.我们的一些单元测试运行了iOS Keychain,当在errSecNotAvailable
恶意攻击Apple脚本的环境中运行时,这些调用失败并出现错误([-25291]对于病态的好奇).结果,测试总是失败......测试中的一个不良特征.
我根据我在网上其他地方找到的信息尝试了许多解决方案.例如,其中一些解决方案涉及尝试启动iOS模拟器的安全服务守护程序.在与这些人挣扎之后,我最好的选择似乎是在iOS模拟器中运行,充分利用了模拟器的环境.
我做了什么,然后得到了iOS模拟器启动工具ios-sim.此命令行工具使用私有Apple框架从命令行启动iOS应用程序.然而,对我来说特别有用的是,它允许我将环境变量和命令行参数传递给它正在启动的应用程序.
虽然环境变量,我能够将我的单元测试包注入我的应用程序.通过命令行参数,我可以传递"-SenTest All"以使应用程序运行单元测试并退出.
我为我的单元测试包创建了一个Scheme(我称之为"CommandLineUnitTests"),并检查了构建部分中的"运行"操作,如上面的帖子中所述.
不过,我没有攻击Apple的脚本,而是将脚本替换为使用ios-sim启动应用程序的脚本,并设置环境以将单元测试包单独注入应用程序.
我的脚本是用Ruby编写的,我比BASH脚本更熟悉.这是脚本:
if ENV['SL_RUN_UNIT_TESTS'] then
launcher_path = File.join(ENV['SRCROOT'], "Scripts", "ios-sim")
test_bundle_path= File.join(ENV['BUILT_PRODUCTS_DIR'], "#{ENV['PRODUCT_NAME']}.#{ENV['WRAPPER_EXTENSION']}")
environment = {
'DYLD_INSERT_LIBRARIES' => "/../../Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection",
'XCInjectBundle' => test_bundle_path,
'XCInjectBundleInto' => ENV["TEST_HOST"]
}
environment_args = environment.collect { |key, value| "--setenv #{key}=\"#{value}\""}.join(" ")
app_test_host = File.dirname(ENV["TEST_HOST"])
system("#{launcher_path} launch \"#{app_test_host}\" #{environment_args} --args -SenTest All #{test_bundle_path}")
else
puts "SL_RUN_UNIT_TESTS not set - Did not run unit tests!"
end
Run Code Online (Sandbox Code Playgroud)
从命令行运行它看起来像:
xcodebuild -sdk iphonesimulator -workspace iPhoneApp.xcworkspace/ -scheme "CommandLineUnitTests" clean build SL_RUN_UNIT_TESTS=YES
Run Code Online (Sandbox Code Playgroud)
在查找SL_RUN_UNIT_TESTS
环境变量之后,脚本在项目的源树中找到"启动器"(iOS-sim可执行文件).然后,它根据Xcode在环境变量中传递的构建设置构建单元测试包的路径.
接下来,我为正在运行的应用程序创建了一组运行时环境变量,它注入了单元测试包.我environment
在脚本中间的哈希中设置了这些变量,然后使用一些ruby grunge将它们连接到ios-sim
应用程序的一系列命令行参数中.
在底部附近,我TEST_HOST
从环境中抓取环境作为我想要启动的应用程序,system
命令实际执行ios-sim
传递应用程序,设置环境的命令参数,以及-SenTest All
运行应用程序的参数和测试包路径.
这个方案的优点是它在模拟器环境中运行单元测试,就像我相信Xcode本身一样.该方案的缺点是它依赖于外部工具来启动应用程序.该外部工具使用私有Apple框架,因此随后的操作系统版本可能会很脆弱,但它目前仍然有效.
PS由于叙述的原因,我在这篇文章中经常使用"我",但很多功劳归功于我的犯罪伙伴Pawel,他和我一起解决了这些问题.
我受到乔纳的帖子的启发,并找到了一种方法:
基本上,你需要Xcode 4,你必须破解脚本才能使它工作,但确实如此.
关键点在于说服Xcode 4运行你的iOS测试包,好像它是一个MacOS X包 - 这是平台的一个问题,Xcode不想在命令行上运行开箱即用的应用程序测试.有趣,因为它似乎工作.
网站上还有一个示例项目.
您正在寻找的是这个未记录的参数(您确实需要sdk和目标)来从终端运行您的OCUnit测试
xcodebuild -target MyTarget -sdk iphonesimulator TEST_AFTER_BUILD=YES
Run Code Online (Sandbox Code Playgroud)
这是一个不完整的解决方案,但我能够在自己的方案中运行逻辑测试的命令行构建并构建目标:http://blog.carbonfive.com/2011/04/06/running-xcode-4-unit-tests-从最命令行/
归档时间: |
|
查看次数: |
32106 次 |
最近记录: |