Unit Tests in Swift Package and custom build configurations

September 29, 20213 min read#iOS, #Swift, #SPM, #Tests

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.

configuration

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

arc

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:

error

This only happens when you use testable to import the internal symbols from the main package into your test bundle.

testable

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.


Profile picture

Personal blog by An Tran. I'm focusing on creating useful mobile apps.
#Swift #Mobile #MachineLearning #Minimalist

© An Tran - 2021