title: When do app sources need to be included in test targets?
body: <p>In a new project I have this simple test</p>
  
  <pre><code>#import &lt;XCTest/XCTest.h&gt;
  #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
  </code></pre>
  
  <p>ViewController.h is <strong>not</strong> part of the test target yet this compiles and runs the tests with no issues.  </p>
  
  <p><img src="https://i.stack.imgur.com/grOly.png" alt="enter image description here"></p>
  
  <p>I think this is because the application is built first (as a dependancy) then the tests.  The linker then figures it out what the ViewController class is. </p>
  
  <p>However, on an older project, with exactly the same test and ViewController file, the build fails at the linker phase: </p>
  
  <blockquote>
  <pre><code>Undefined symbols for architecture i386:
  "_OBJC_CLASS_$_ViewController", referenced from:
    objc-class-ref in ViewControllerTests.o
  </code></pre>
  </blockquote>
  
  <p>This linker error occurs even if when a fresh XCTest unit testing target is created. </p>
  
  <p>To get around this instead, it is possible to include the sources in both the app and the test targets (tick both boxes in the image above).  This causes build warnings for duplicate symbols, in the simulator's system log (open the simulator and press cmd-/ to see this):</p>
  
  <blockquote>
  <pre><code>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.
  </code></pre>
  </blockquote>
  
  <p>These warnings occasionally cause issues illustrated by the following example:</p>
  
  <pre><code> [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
  </code></pre>
  
  <p>So the question is what setting(s) in the older project are requiring application source files to be included in the test target?</p>
  
  <hr>
  
  <h2>Summary of comments</h2>
  
  <p>Between the working and the non-working project:</p>
  
  <ol>
  <li>There is no difference in the linker output (the command starting with <code>Ld</code>).</li>
  <li>There is no difference in the target dependancies (there is 1 dependancy to the test target,which is the app) </li>
  <li>There is no difference in the linker settings.</li>
  </ol>