TL;DR: Is it possible to invoke XCTFail dynamically without importing XCTest?
We're developing an SPM package that ships with a test support module that has a helper that invokes XCTFail. Unfortunately, it turns out that SPM does not support the use case where a MyLibraryTestSupport library product depends on a MyLibrary library product, because downstream apps that import the library into their app and the test support library in tests will break due to duplicate symbols.
We could move our test support library to its own package/repository, but this seems like a non-starter, as it makes package maintenance and consumption more burdensome.
What we'd like to do instead is merge the libraries, but the test helper's call to import XCTest immediately causes problems. So we're wondering if it's somehow possible to get a dynamic handle on XCTFail so that our test helper can be invoked on test runs but not cause any problems for applications that link to our library.
Does anyone know if this is possible or have another solution given the above?
I donât think the problem would have occurred in the first place if none of the products were dynamic. Iâve certainly never encountered issues importing this XCTestâdependent module from all over the place.
If the main library needs to be dynamic, then having a second library thatâs also dynamic and shares any modules would cause duplicate symbols. The current inability to split out the shared symbols into their own dynamic library without having a separate package seems to be the real root of the issue. To do that, we would need the ability to depend on products from the same package.
It happens to be what I asked about on my very first post on these forums a long time ago, but nothing has ever come of it.
This is indeed some black magic on display ^^ Nicely done but can't this be a reason for apps rejection by Apple ? In theory they just reject apps that give random strings to these dlopen/dlsym methods but it seems they have done it even for apps that used fixed strings (https://github.com/nicklockwood/GZIP/issues/24)
I'm not sure if I'm missing something, but I've updated the libraries to be static and still need the workaround. If I try to import XCTest in the library then any app that depends on it fails to compile with the following log:
ld: warning: Could not find or use auto-linked library 'XCTestSwiftSupport'
ld: warning: Could not find or use auto-linked framework 'XCTest'
Undefined symbols for architecture arm64:
"XCTest.XCTFail(_: Swift.String, file: Swift.StaticString, line: Swift.UInt) -> ()", referenced from: âŚ
The problem would still exist for app-hosted tests. The app and the test bundle would contain the same symbols and the test bundle will be loaded in the app's address space when using TEST_HOST.
I have managed this issue in a ugly way but itâs working for xcode preview and testing.
I have forked the project and split it into two libraries with different names one dynamic linking for test(that is the one available on point free but renamed) and one static linking for the main project(without the test utilities).
Itâs working pretty well but itâs ugly, cumbersome to maintain and might definitively not be what you want to support.