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 allTests
array.
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
.sourcery
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_NAME
needs to be set to your test module, which is then imported as@testable
inLinuxMain.swift
. Usually this is called<YourTarget>Tests
.
- Make sure you remove any
static var allTests
declarations 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 instancevapor 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.