В новом проекте у меня есть этот простой тест
#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 зависимость от тестовой цели, которая является приложением)
- В настройках компоновщика нет никакой разницы.