I have recently encoutered an interesting problem in my work which you might have in the future as well. I write up quickly this blog post to save you some times and also to remind me to recheck the issue again when new version of Xcode is released.
By default when you create a new Xcode, two build configurations
Release will be created.
We can easily add new configurations to build different variations of our app, such as to control the backend server the the app should connect to: development, staging, or production.
If you are following the new modern way to modularise your apps by using Swift Package Manager, you will end up with something like the following
The caveat of this combination is that you will not be able to run the unit tests anymore when buiding the app using the
Staging configuration. Xcode will show the following error:
This only happens when you use
testable to import the internal symbols from the main package into your test bundle.
The tests work fine when building using
Release configurations though.
After half a day debuging and trying to understand the problem, I finally found this thread in the Swift forum.
This is an internal limitation of Swift Package Manager currently that the compiler only fowards the
Enable Testability flag to Swift Packages when the main app is built with
Debug configuration. In all other cases, the packages will be built in Release mode, which is not avaialbe for
@testable import in our tests.
There are some solutions for this problem:
- Run tests only in Debug Configuration in Staging and Release Schemes.
-enable-testingexplicitly into the target definition in the Swift Package as shown in this Stack Overflow question.
- Create different targets for different app variations, instead of using the same target with different build configurations.
Swift Package is a great way to modularise our code. Build configurations are a great way to configuration the build to have different variations of our apps. Unfortunalte, the combination of two is leading to an unwanted problem with our unit tests.
I have pushed the sample project in Github and will retest again when new Xcode version gets released.