我正在将项目从Xcode 4.6.3迁移到Xcode 5.0.2。该项目的单元测试是使用SenTestingKit / OCUnit开发的。现在,当我在Xcode 5中运行测试时,我从RunUnitTests
脚本中收到错误告诉我
RunUnitTests已过时。
可能与Xcode 5发行说明中的注释相关:
不推荐使用SenTestingKit和OCUnit。使用迁移器移动到XCTest。
不幸的是,我无法找到更多关于这个神秘的“迁移者”的信息。可能我的google-fu缺乏[再次],所以我的主要问题是:如何将单元测试从SenTestingKit / OCUnit迁移到新的XCTest(有或没有“迁移器”)?
第二个问题,如果迁移是一项复杂的业务:是否有可能让Xcode 5运行仍基于SenTestingKit / OCUnit的单元测试?在所有这些仅仅被弃用之后,它们应该仍然存在并且功能正常。
答案 0 :(得分:58)
感谢Shaggy Frog的回答,我们知道Xcode发行说明中提到的神秘“迁移器”是通过选择“编辑>重构>转换为XCTest”启动的向导。我将分两部分介绍我对这个向导的体验。第一部分是对主要问题的不完整答案,第二部分回答了次要问题。
您需要意识到的第一件事是,要使向导工作,您需要选择单元测试目标。如果选择了主目标,则向导不会列出要转换的任何目标。
一旦我发现了这一点,我就可以逐步完成向导,但就我而言,最终结果仍然是一次惊人的失败!该向导声称不需要进行任何源更改,只需要更新构建设置以迁移到XCTest。最后,向导甚至没有设法正确地执行此操作:已删除对SenTestingKit框架的引用,但它确实不引入了对XCTest的引用框架。
无论如何,接下来是我必须手动制作的更改列表,因为向导无法为我制作这些更改。如果向导更适合您,您可能不需要做所有这些事情。
SenTestCase
更改为XCTestCase
<SenTestingKit/SenTestingKit.h>
更改为<XCTest/XCTest.h>
octest
更改为xctest
。ST*
重命名为XCT*
(例如STAssertTrue
变为XCTAssertTrue
)STAssertEquals
需要重命名为XCTAssertEqual
(注意最后缺少的“s”)。如果您收到此编译器警告,您将会忘记这一点:warning: implicit declaration of function 'XCTAssertEquals' is invalid in C99
nil
作为失败描述传递。例如,XCTAssertNotNil(anObject, nil)
是不可能的,必须更改为XCTAssertNotNil(anObject)
。当您收到此编译器错误时,您将知道存在此问题:error: called object type 'NSString *' is not a function or function pointer
。NSString
类方法stringWithFormat:
那样。当您收到此编译器错误时,您将知道存在此问题:error: expected ')'
。一些例子:NSString* formatSpecifier = @"%@";
NSString* failureDescription = @"foo";
// These are OK
XCTAssertNotNil(anObject, @"foo")
XCTAssertNotNil(anObject, @"%@", failureDescription)
// These are not OK
XCTAssertNotNil(anObject, failureDescription);
XCTAssertNotNil(anObject, formatSpecifier, failureDescription);
最后但并非最不重要的是,如前所述,需要将对XCTest框架的引用添加到单元测试目标中。如果您遇到Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo
等链接器错误,您就会知道已经忘记了这一点。
Xcode 6更新:Xcode 6中不再需要与XCTest链接(实际上XCTest甚至不再列为可用框架)。而是将构建设置CLANG_ENABLE_MODULES设置为YES(在UI中显示为“启用模块(C和Objective-C)”)。这会导致clang
在看到#import <XCTest/XCTest.h>
语句时自动链接到XCTest。有关详情,请参阅"Modules" section of the clang documentation。
此时我收到一个链接器错误,让我意识到我迁移到XCTest的任务失败了。原因:XCTest不是SDK 6.1的一部分,但我仍然使用基础SDK iOS 6.1构建我的项目(this SO answer解释了如何将SDK 6.1集成到Xcode 5中)。
由于我无法继续迁移,因此我目前的解决方案是基于SenTestingKit / OCUnit保持我的单元测试,直到我找到将我的应用程序升级到iOS 7的时间。这就是我所需要的为了让单元测试运行:
最终的解决方案不如Xcode 4.x那样好,每当我运行主目标的“运行”或“构建”动作时,单位测试就会自动执行。不幸的是,似乎在没有“运行脚本”构建阶段的情况下我无法工作。
答案 1 :(得分:14)
编辑 - &gt;重构 - &gt;转换为XCTest
OCUnit测试仍然有效,但您也可以迁移。这些变化最终很小。