Dealing with linux tests in SPM packages can be annoying, because any additon to your tests or a change to a test name requires you to manually update
LinuxMain.swift and/or the
The following short, one-time setup will autogenerate all required stubs whenever you run
git commit (in the CLI or via a git GUI) and ensure your Linux tests are always up to date.
- Install sourcery: https://github.com/krzysztofzablocki/Sourcery
brew install sourcery
- Add a stencil file template to
curl -s -o .sourcery/LinuxMain.stencil https://gist.githubusercontent.com/finestructure/d8b9098e7ba8ecb505c24db5684c7744/raw/f482858186650107f56a007236b285a45bf37d07/LinuxMain.stencil
Add a git commit hook
TESTABLE_IMPORT_NAME=AppTests cat <<EOF > .git/hooks/pre-commit #!/bin/sh sourcery \ --templates ./.sourcery \ --sources Tests \ --args testimports='@testable import '"$TESTABLE_IMPORT_NAME" \ --output Tests/LinuxMain.swift \ &>/dev/null if [[ -n \$(git diff) ]]; then echo "Linux tests were out of date." echo "Your files have been updated, please review and add them to the commit." exit 1 fi EOF
TESTABLE_IMPORT_NAMEneeds to be set to your test module, which is then imported as
LinuxMain.swift. Usually this is called
- Make sure you remove any
static var allTestsdeclarations that may exists in your test classes. These will now be autogenerated.
And that's it. With these things set up,
git commit will have your back and alert you whenever your linux tests are out of sync.
Alternative: Xcode "Run Script" build phase
Instead of setting up a commit hook, the call to run
sourcery can also be triggered from an Xcode "Run Script" build phase.
While this has the nice advantage of making sure your files are updated sooner in the development cycle and not just when you are getting ready to commit a change, I've found this comes with a couple of drawbacks:
- does not work with other code editors
swift package generate-xcodeproj(or tools that make use of it, like for instance
vapor update) will likely overwrite your changes to the project file
I tried using a script phase for a while but eventually got tired of having it overwritten all the time.