#import <XCTest/XCTest.h>
#import "ViewController.h"
@interface ViewControllerTests : XCTestCase
@end
@implementation ViewControllerTests
- (void)testExample
{
// Using a class that is not in the test target.
ViewController * viewController = [[ViewController alloc] init];
XCTAssertNotNil(viewController, @"");
}
@end
ViewController.h不是测试目标的一部分,但编译和运行测试没有任何问题。
我认为这是因为应用程序首先构建(作为依赖项),然后是测试。 链接器随后确定ViewController类是什么。
然而,在旧项目中,与完全相同的测试和ViewController文件相比,构建在链接器阶段失败:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_ViewController", referenced from:
objc-class-ref in ViewControllerTests.o
即使创建全新的XCTest单元测试目标,也会出现此链接器错误。为了绕过这个问题,可以将源文件包括在应用程序和测试目标中(在上面的图像中选中两个框)。这会导致重复符号的构建警告,在模拟器系统日志中显示(打开模拟器并按cmd-/键查看):
Class ViewController is implemented in both
[...]/iPhone Simulator/ [...] /MyApp.app/MyApp and
[...]/Debug-iphonesimulator/LogicTests.octest/LogicTests.
One of the two will be used. Which one is undefined.
偶尔这些警告会引起问题,下面是一个例子: [viewController isKindOfClass:[ViewController class]]; // = NO
// Memory address of the `Class` objects are different.
NSString * instanceClassString = NSStringFromClass([viewController class]);
NSString * classString = NSStringFromClass([ViewController class]);
[instanceClassString isEqualToString:classString]; // = YES
// The actual class names are identical
那么问题是,在旧项目中有哪些设置要求将应用程序源文件包含在测试目标中?
评论摘要
在可工作和不可工作的项目之间:
- 链接器输出没有任何区别(以
Ld
开头的命令)。 - 目标依赖项没有任何区别(测试目标有 1 个依赖项,即应用程序)。
- 链接器设置没有任何区别。
-framework XCTest
,另一个是ObjC
。我纠正了这个差异,但它仍然无法编译 :( 你还能想到其他什么吗? - Robert