Wann müssen App-Quellen in Testziele aufgenommen werden?

In einem neuen Projekt, das ich mit diesem einfachen test

#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 ist nicht Teil des test-target noch das kompiliert und läuft der Test ohne Probleme.

Wann müssen App-Quellen in Testziele aufgenommen werden?

Ich denke, das ist, weil die Anwendung erst gebaut (als Abhängigkeit) dann die tests. Der linker dann zahlen Sie es aus, was die ViewController-Klasse ist.

Jedoch auf ein älteres Projekt, mit genau den gleichen test und ViewController-Datei, die build schlägt fehl, bei der linker-phase:

Undefined symbols for architecture i386:
"_OBJC_CLASS_$_ViewController", referenced from:
  objc-class-ref in ViewControllerTests.o

Diese linker-Fehler tritt auf, selbst wenn eine frische XCTest unit-Test-target erstellt.

Dies zu umgehen, stattdessen ist es möglich, die Quellen in die app und der test-targets (Zecken beide Boxen im Bild oben). Dies bewirkt, dass build-Warnungen für doppelte Symbole in der simulator-system-log (öffnen Sie den simulator und drücken Sie cmd-/um dies zu sehen):

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.

Diese Warnungen, die gelegentlich zu Problemen führen, illustriert das folgende Beispiel:

 [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

Die Frage ist also, welche Einstellung(en) in der älteren Projekts sind, die anwendungsquelldateien in die test-target?


Zusammenfassung der Kommentare

Zwischen der arbeitenden und der nicht arbeitenden Projekt:

  1. Es gibt keinen Unterschied in der linker-Ausgabe (beginnend mit Ld).
  2. Es gibt keinen Unterschied in der target-Abhängigkeiten (es ist 1 Abhängigkeit der test-target,das ist die app)
  3. Es gibt keinen Unterschied in den linker-Einstellungen.

InformationsquelleAutor der Frage Robert | 2014-02-20

Schreibe einen Kommentar