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!

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

Terms of Service

Privacy Policy

Cookie Policy