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.
The Problem
By default when you create a new Xcode, two build configurations Debug
and 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 Debug
and Release
configurations though.
Why?
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.
The Solution
There are some solutions for this problem:
- Run tests only in Debug Configuration in Staging and Release Schemes.
- Add
-enable-testing
explicitly 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.
Conclusion
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.