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