为什么在实施单元测试时我的 postgres table 不存在?

Why is my postgres table not existing when implementing Unit Tests?

我开始在 Vapor 4 项目中实施单元测试,但是 users postgres table 在每次测试后都没有 deleted/created。它仅适用于 1 次测试,然后才会全部崩溃。

即使我没有执行任何测试,编译器也会因以下错误而停止:

caught error: "previousError(server: table "users" does not exist (DropErrorMsgNonExistent))"

我的数据库是 Docker 容器中的 运行 PostgreSQL。当我手动删除这个容器并再次 运行 测试时,没有错误。当我第二次 运行 时,错误又回来了。

为什么我的table每次测试后都没有被删除?

这是我的测试文件,我已经实施了一个简单的测试来测试管道:

import XCTVapor
@testable import App

class BaseXCTestCase: XCTestCase {

  var app: Application!

  override func setUpWithError() throws {
    try super.setUpWithError()
    app = Application(.testing)
    try configure(app).  // The error is caught here.
  }

  override func tearDownWithError() throws {
    app.shutdown()
    try super.tearDownWithError()
  }

  // This test crashes if everything goes well, but it
  // doesn't even run as the crashes appears in configure.swift.
  func test_zero() {
    XCTFail("Tests not yet implemented")
  }
}

这是我的 users table:

import Fluent

struct UserModelMigration_v1_0_0: Migration {

  func prepare(on database: Database) -> EventLoopFuture<Void> {
    
    database.schema("users")
      .id()
      .field("email", .string, .required)
      .field("password", .string, .required)
      .field("appleID", .string)
      .unique(on: "email")
      .create()
  }

  func revert(on database: Database) -> EventLoopFuture<Void> {
    database.schema("users").delete()
  }
}

这是我的 configure.swift 文件的一部分,我在其中设置了测试迁移:

import Fluent
import FluentPostgresDriver
import Vapor

public func configure(_ app: Application) throws {
  // MARK: Database
  let databaseName: String
  let databasePort: Int

  if app.environment == .testing {
    databaseName = "db_testing"
    databasePort = 5434
  }
  else {
    databaseName = "db_development"
    databasePort = 5433
  }

  app.databases.use(.postgres(
    hostname: "localhost",
    port: databasePort,
    username: "username",
    password: "password",
    database: databaseName
  ), as: .psql)

  // MARK: Migrations
  app.migrations.add(UserModelMigration_v1_0_0())

  // MARK: Clear Database
  if app.environment == .testing {
    try app.autoRevert().wait()
  }

  if !app.environment.isRelease {
    try app.autoMigrate().wait()
  }
}

还有两个文件,我在其中向 运行 Docker 容器中的测试添加了代码。

文件:docker-compose-testing.yml

version: '3'
services:
  serverside-app:
    depends_on:
      - postgres
    build:
      context: .
      dockerfile: testing.Dockerfile
    environment:
      - DATABASE_HOST=postgres
      - DATABASE_PORT=5434
  postgres:
    image: "postgres"
    environment:
      - POSTGRES_DB=db_testing
      - POSTGRES_USER=username
      - POSTGRES_PASSWORD=password

文件:testing.Dockerfile

FROM swift:5.3
WORKDIR /package
COPY . ./
CMD ["swift", "test", "--enable-test-discovery"]

如果 table 不存在,您的还原将失败。 将其更改为 try? app.autoRevert().wait() 并自动迁​​移到 try? app.autoMigrate().wait() 将忽略任何错误。