Xcode not respecting canImport(XCTest)?

This is a weird one, but say we have a Swift Package with a file that contains a snippet like:

#if canImport(XCTest)
    import XCTest
    /* code using XCTest */
#endif

Unfortunately, if I try to pull this library into my app target, it fails to compile with the following warnings/errors:

(Warning) Could not find or use auto-linked library 'XCTestSwiftSupport'
(Warning) Could not find or use auto-linked framework 'XCTest'
(Error) Undefined symbol: _OBJC_CLASS_$_XCTestCase
(Error) Undefined symbol: __swift_FORCE_LOAD_$_XCTestSwiftSupport

To work around this problem, we end up with two packages: Foo and Foo_XCTestSupport, and we only add the latter to UI and Unit testing projects. However, this comes with the unfortunate complexity of Xcode's SPM static/dynamic linking issues (see here and here) causing unexpected problems, so I was really hoping to just have it be one singular package with smart canImport macros or otherwise.

So I have a few questions...

  1. Why does XCTest behave so differently here? I'm assuming it's because some aspect of the library is available during compilation because there might be underlying setup needed for Unit / UI testing, but I don't really know.
  2. Is there another condition/macro I should be using here?
  3. Can anyone think of any better solutions than what I've defined above? I don't mind having multiple modules for varying cases of support, and this might be the "preferred" pattern.

Thanks in advance, just looking to understand more about the linking process and why it's hit a hiccup here!

1 Like

We open sourced xctest-dynamic-overlay to solve this exact problem.

Apart from your workaround (thanks a lot)… since it's still a problem in 2023 (Xcode 14.3), any idea whether Apple people are aware of that problem and interested in fixing it?

No idea, but we'd for sure love for some better support from Apple here!

1 Like

This is further complicated because Xcode 14.3's module verifier doesn't like linking XCTest into modules are that aren't test targets (like a reusable set of test utilities used for multiple test targets). It really seems like XCTest's peculiar linking limitations haven't kept up with the other tools or community.

1 Like