在 Linux 上测试 封面
Vapor 大型教程

在 Linux 上测试

部署到 Linux 与本地 Mac 的 Foundation 实现不同,必须保证在 Linux 上也能跑通测试。本文讲 LinuxMain 手动登记测试用例,以及用 Docker 本地模拟 Linux 跑全套。

为什么要在 Linux 上跑测试

对于服务端应用,在 Linux 上跑测试用例是很重要的。当我们部署到 Vapor Cloud 上时,其实部署的操作系统(Linux)和我们开发使用的系统(MacOS)是不同的。Linux 上的 Foundation 库不同于 MacOS 上的 Foundation,MacOS 上的 Foundation 已经被测试使用多年,并且可以使用 Objective-C 运行时特性,但 Linux 上的 Foundation 是纯 swift 实现的,有一些特性还没有完成实现,相对不稳定,有时会引起崩溃,所以我们必须确保在 Linux 环境下也能成功跑完所有测试用例。

在 MacOS 上,可以利用 Objective-C 的运行时特性,通过检查函数名称前缀为 test 来识别测试用例。但是在 Linux 上,由于没有 Objective-C 运行时特性支持,所有我们必须手动指定哪些函数是测试用例。

Tests 目录下有一个名为 LinuxMain.swift 的文件,它不是 Xcode 工程的一部分,我们需要在这个文件中手动列出哪些函数是测试用例。

import XCTest

@testable import AppTests

XCTMain([
    testCase(AcronymTests.allTests),
    testCase(CategoryTests.allTests),
    testCase(UserTests.allTests),
])
...
static let allTests = [
    ("testUsersCanBeRetrievedFromAPI", testUsersCanBeRetrievedFromAPI),
    ("testUserCanBeSavedWithAPI", testUserCanBeSavedWithAPI),
    ("testGettingASingleUserFromTheAPI", testGettingASingleUserFromTheAPI),
    ("testGettingAUsersAcronymsFromTheAPI", testGettingAUsersAcronymsFromTheAPI)
]
...
static let allTests = [
    ("testAcronymsCanBeRetrievedFromAPI", testAcronymsCanBeRetrievedFromAPI),
    ("testAcronymCanBeSavedWithAPI", testAcronymCanBeSavedWithAPI),
    ("testGettingASingleAcronymFromTheAPI", testGettingASingleAcronymFromTheAPI),
    ("testUpdatingAnAcronym", testUpdatingAnAcronym),
    ("testDeletingAnAcronym", testDeletingAnAcronym),
    ("testSearchAcronymShort", testSearchAcronymShort),
    ("testSearchAcronymLong", testSearchAcronymLong),
    ("testGetFirstAcronym", testGetFirstAcronym),
    ("testSortingAcronyms", testSortingAcronyms),
    ("testGettingAnAcronymsUser", testGettingAnAcronymsUser),
    ("testAcronymsCategories", testAcronymsCategories),
]
...
static let allTests = [
    ("testCategoriesCanBeRetrievedFromAPI", testCategoriesCanBeRetrievedFromAPI),
    ("testCategoryCanBeSavedWithAPI", testCategoryCanBeSavedWithAPI),
    ("testGettingASingleCategoryFromTheAPI", testGettingASingleCategoryFromTheAPI),
    ("testGettingACategoriesAcronymsFromTheAPI", testGettingACategoriesAcronymsFromTheAPI),
]

使用 Docker 模拟在 Linux 上运行测试用例

编辑 Dockerfile

FROM swift:4.1

WORKDIR /package

COPY . ./

RUN swift package resolve
RUN swift package clean

CMD ["swift", "test"]

编辑 docker-compose.yml 文件:

version: '3'

services:
    til-app:
        depends_on:
            - postgres
        build: .
        environment:
            - DATABASE_HOSTNAME=postgres
            - DATABASE_PORT=5432
    postgres:
        image: "postgres"
        environment:
            - POSTGRES_DB=vapor-test
            - POSTGRES_USER=vapor
            - POSTGRES_PASSWORD=password

configure.swift 文件中作一下测试端口的修改,以适应测试环境变量设定:

if let testPort = Environment.get("DATABASE_PORT") {
    databasePort = Int(testPort) ?? 5433
} else {
    databasePort = 5433
}

上面都配置好后,在工程目录下,可以在终端运行 Linux 上的测试用例了:

$ docker-compose build
$ docker-compose up --abort-on-container-exit

本系列其他文章