Keeping Swift Tests on Linux Sync’d

Max Howell
3 min readJan 25, 2019

--

If your Swift project uses swift test on Linux then you are aware that you need to run swift test --generate-linuxmain in order to get for free what you get on Apple platforms, ie. for XCTest to know which tests it runs. The command generates several extra files that are only used on Linux and must be committed to your repository if you want test your product on Linux in CI.

A pain point in Swift’s early life for sure, but for now it’s just extra boilerplate. Well almost, since you have to re-run that command every time you add new tests, it’s easy to forget and then you aren’t testing on Linux properly.

So let’s add a CI hook to do it. Using Travis’s build stages it’s pretty easy to add a single stage that all tests depend on:

# these defaults are used unless we override them in individual jobs
os: osx
language: swift
osx_image: xcode10.1

jobs:
include:
- stage: pretest
name: Check Linux tests are sync’d
install: swift test --generate-linuxmain
script: git diff --exit-code
- stage: test
name: macOS / Swift 4.2.1
script: swift test --parallel
- env: SWIFT_VERSION=4.2.1
os: linux
name: Linux / Swift 4.2.1
language: generic
install: |
eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
script: swift test --parallel

The pretest is simple, we run swift test --generate-linuxmain and then ask git if there’s a diff. If there’s any differences then we (or a contributor) forgot to run swift test --generate-linuxmain before committing.

It would be neat to automate running swift test --generate-linuxmain and then committing those changes, and perhaps GitHub Actions (when final) will get us there, but until then having our CI commit to the repo it is testing against is a really bad idea (infinite CI cycles are not a future I want for you). So adding a check is the best we can get.

We are using Kyle Fuller’s excellent Swift Version Manager to install a specific version of Swift on Linux. The image Travis provides does not have Swift available via APT .

This gives us a matrix that will look similar to this:

This is the matrix for Path.swift

If the pretest fails, the tests don’t run and the pull-request will be blocked.

Hey there!

I’m Max Howell and I want to be full-time making, writing and being all about open source. I’ve been doing open source for more than 15 years, and you probably already use some of it (Homebrew anyone?). I need your help to continue, any contribution is most welcome. Thanks so much.

https://patreon.com/mxcl

--

--