Server-Side Swift: Testing on Linux

In this tutorial, you’ll test your server-side Swift apps on Linux, learning the differences between testing on macOS and Linux, and how to use Docker and Docker Compose. By Christian Weinberger.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 2 of 2 of this article. Click here to view the first page.

Generating a Dockerfile

Well, you’ve already used Linux for the PostgreSQL test database using Docker! So you can also use Docker to run your tests in a Linux environment. In the top level project starter directory, create a new file called Dockerfile (with no extension). Open the file in a text editor and add the following:

# 1
FROM swift:5.3
# 2
WORKDIR /package
# 3
COPY . ./
# 4
CMD ["swift", "test", "--enable-test-discovery"]

The Dockerfile:

  1. Uses the official Swift 5.3 image.
  2. Sets the working directory to /package.
  3. Copies the contents of the current directory into /package in the container.
  4. Fetches the dependencies and cleans up the project’s build artifacts.
  5. Sets the default command to swift test --enable-test-discovery. This will also fetch dependencies and clean up the project’s build artifacts.

Using Docker Compose

As described earlier, the tests need a PostgreSQL database to run. By default, Docker containers can’t see each other. However, Docker has a tool, Docker Compose, designed to link different containers for testing and running apps. Create a new file called docker-compose.yml in the top level starter project directory. Open the file in an editor and add the following:

# 1
version: '3'
# 2
services:
  # 3
  til-app:
    # 4
    depends_on:
      - postgres
    # 5
    build: .
    # 6
    environment:
      - DATABASE_HOST=postgres
      - DATABASE_PORT=5432
  # 7
  postgres:
    # 8
    image: "postgres"
    # 9
    environment:
      - POSTGRES_DB=vapor-test
      - POSTGRES_USER=vapor_username
      - POSTGRES_PASSWORD=vapor_password

This code:

  1. Specifies the Docker Compose version.
  2. Defines the services for this app.
  3. Defines a service for the TIL app.
  4. Sets a dependency on the Postgres container, so Docker Compose starts the Postgres container first.
  5. Builds the Dockerfile in the current directory — the Dockerfile you just created.
  6. Injects the DATABASE_HOST and DATABASE_PORT environment variable. Docker Compose has an internal DNS resolver. This
    allows the til-app container to connect to the postgres container with the hostname postgres and port 5432.
  7. Defines a service for the Postgres container.
  8. Uses the standard Postgres image.
  9. Sets the same environment variables as were used at the start of the tutorial for the test database.

To test your app on Linux, in Terminal, type the following:

# 1
docker-compose build
# 2
docker-compose up --abort-on-container-exit

This:

  1. Builds the different Docker containers.
  2. Spins up the different containers and run the tests. --abort-on-container-exit tells Docker Compose to stop the postgres container when the til-app container stops. The postgres container used for this test is different from, and doesn’t conflict with, the one you ran earlier for testing on macOS.

When the tests finish running, you’ll see the output in Terminal with all tests passing:

Result of running the tests in docker using `docker-compose`

Note: You could also run the tests on a real Linux machine. You can move the whole starter folder to the Linux machine. Remember to remove the .build folder so dependencies are recompiled correctly when you run swift test --enable-test-discovery. Your Linux machine will need PostgreSQL (as configured in the Docker example above) and the following packages installed: libssl-dev, libz-dev and pkg-config, which you can install via sudo apt install libssl-dev libz-dev pkg-config.

To clean up, in Terminal, run the following commands from the root folder of your project:

# 1
docker-compose down
# 2
docker-compose rm

These commands:

  1. Stop all containers and networks created by docker-compose.
  2. Delete the previously created containers now that they are stopped.

Where to Go From Here?

Writing tests and running them on the platforms you’ll use in production is important. It gives you confidence your code will work when you deploy your application. Having a good test suite allows you to evolve and adapt your apps quickly.

In this tutorial, you’ve learned how to test your server-side Swift apps on Linux to ensure that they work correctly. Using Docker and Docker Compose makes testing on Linux simple. You can add different dependencies and services as needed, such as Redis or other databases.

Feel free to take a look at the final project using the Download Materials button at the top or bottom of this tutorial. If you have any questions, join us on the forums below!