As the Swift on Linux and Swift Package Manager ecosystems mature, many authors of Swift packages want to enable their packages on Linux as well as Apple platforms. The growth of Server-Side Swift makes Linux an important target for many packages.
The first step is to run a package's unit tests on Linux, to verify it behaves as expected.
Because Swift on Linux does not use the Objective-C runtime, the dynamic features that the XCTest
unit testing framework uses to automatically discover testcases are not available.
However, you can easily enable your XCTest
unit tests for Linux by following these steps:
-
In the
Tests
directory of your Swift package, create a new file. By convention this is namedLinuxMain.swift
. -
In it, call
XCTMain()
, passing in an array of all your testcase classes:XCTMain([ testCase(TestOne.allTests), testCase(TestTwo.allTests), ])
-
Add an additional property in each of your testcase classes, named
allTests
by convention. This array should contain all your unit tests.class TestOne : XCTestCase { static var allTests = { return [ ("test_a", test_a), ("test_b", test_b), // etc ] }() func test_a() { XCTAssertEqual(2+2, 4) } func test_b() { XCTAssertEqual(2*2, 4) } }
To run your tests, type swift test
as normal.
Even if you don't have access to a Linux machine, it's still easy to run a Swift package's unit tests on Linux by using Docker.
After installing Docker for Mac on your desktop machine you can run the following commands to easily execute unit tests on Linux:
$ cd MyPackage
$ docker run --rm -v "$(pwd):/pkg" -w "/pkg" swift:latest /bin/bash -c "swift test --build-path ./.build/linux"
The docker run
arguments mean as follows:
--rm
: automatically remove the Docker container from disk when it exits.-v "$(pwd):/pkg"
: bind mount the current working directory to/pkg
in the Docker container, so that your package files are visible inside the container.-w "/pkg"
: when the container starts, change to the/pkg
working directory.swift:latest
: use the latest version of the Swift image from Docker Hub. This image packages the latest version of Swift and is based on Ubuntu 16.04 LTS./bin/bash -c "swift test --build-path ./.build/linux"
: execute theswift test
command in the container, using a custom build path. This ensures that the Linux build artifacts are kept separate from any macOS binaries you may have already created.
Assuming the tests all pass, you should see:
Total executed 1 test, with 0 failures (0 unexpected) in 0.0 (0.005) seconds
Once a Swift package runs on Linux, it's best practice to advertise this in the project's README.md
file. You might also consider adding a badge from shields.io.
If your project uses a Continuous Integration service like Travis CI you should add automated Linux testing, to avoid regressions.
You can also submit your package to the IBM Swift Package Catalog.