code-signing - 如何在 Xcode 10 和 macOS 10.14 下为 XCTest UI 测试启动 WireMock?

标签 code-signing xctest xcode10 macos-mojave wiremock

我们使用独立的 wiremock 实例作为 Xcode UI 测试的模拟服务器。我们有一个测试观察者类,它负责启动这个实例(如果需要)并在测试运行完成后将其拆除。观察者的代码如下:

import AppKit
import XCTest
import WiremockClient

class SSUITestObserver: NSObject, XCTestObservation {

    enum TestObserverError : Error {
        case MockServerStartupError(String)
    }

    lazy var testBundleURL: URL = Bundle(for: SSUITestCase.self).bundleURL
    lazy var testBundleBinURL: URL = self.testBundleURL.appendingPathComponent("..", isDirectory: true)
    lazy var mockServerHomeURL: URL = self.testBundleURL.appendingPathComponent("Contents/Resources/", isDirectory: true)
    lazy var mockServerJarURL: URL = self.mockServerHomeURL.appendingPathComponent("wiremock-standalone-2.18.0.jar", isDirectory: false)

    override init() {
        super.init()

        NSLog("UI Test Observer Initialized")
        XCTestObservationCenter.shared.addTestObserver(self)
    }

    func testBundleWillStart(_ testBundle: Bundle) {
        NSLog("***Test Bundle starting")
        do {
            // Start the Wiremock server
            try ensureMockServerIsRunning()
        } catch {
            fatalError("\n Failed during test bundle setup: \(error)\n")
        }


    }

    public func testBundleDidFinish(_ testBundle: Bundle) {
        NSLog("***Test Bundle completed")
        stopMockServer()
    }

    func ensureMockServerIsRunning() throws {
        WiremockClient.baseURL = SSUIIntegrationTestCase.mockServerAddress

        guard !WiremockClient.isServerRunning() else { return }

        let args = ["-jar",
                    self.mockServerJarURL.path,
                    "--port", "3000",
                    "--root-dir", self.mockServerHomeURL.path]

        _ = Process.launchedProcess(launchPath: "/usr/bin/java", arguments: args)

        for _ in 1...9 {
            if WiremockClient.isServerRunning() { return }
            sleep(1)
        }

        throw TestObserverError.MockServerStartupError("Error staring up the mock server instance!")
    }

    func stopMockServer() {
        WiremockClient.shutdownServer()
    }

    func resetMockServerStubs() {
        WiremockClient.reset()
    }
}

在我迁移到 macOS 10.14 之前,一切都很好。以前,我们没有对 UITest 目标进行代码签名。迁移到 10.14 后,运行测试现在会在测试开始运行之前失败并出现引导错误。我发现为测试打开自动代码签名可以解决这个问题。

但是,这会导致第二个问题:在上面的 launchedProcess 行中,启动 wiremock 服务器的尝试将失败并显示 java.lang.RuntimeException: java.net.SocketException:不允许操作。如果在我执行测试之前启动了服务器(例如在命令行上),则一切正常。

那么我怎样才能摆脱这个第 22 条军规呢?在 10.13 下一切正常。我不清楚代码签名与启动模拟服务器有什么关系。

最佳答案

我没有收到我的问题的直接答案,但我确实找到了解决方法。与其使用 TestObserver 启动 WireMock 服务器,不如在测试中使用预操作。

为此,您需要为 UI 测试项目编辑方案:

Edit Scheme

  1. 点击测试旁边的披露箭头,然后点击Pre-actions
  2. 点击+添加 ActionScript
  3. 使用您选择的 shell(我保留了默认值,/bin/sh)
  4. Provide build settings from 下,选择您的测试目标
  5. 输入启动模拟服务器的脚本。

对于脚本,我使用了以下代码:

exec > /tmp/preaction-log.txt 2>&1

# Attempt to connect to an existing wiremock server, and exit if we succeed:
curl http://localhost:3000/__admin/mappings > /dev/null 2>&1 && exit 0 || echo "Attemmpting to spin up a Wiremock Server:"

# No existing server, so spin one up:
WIREMOCK_DIR=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME}-Runner.app/Contents/PlugIns/${TARGET_NAME}.xctest/Contents/Resources/

/usr/bin/java -jar "${WIREMOCK_DIR}"wiremock-standalone-2.18.0.jar --port 3000 --root-dir "${WIREMOCK_PATH}" &

这是脚本的作用:

  1. 将所有输出记录到 /tmp/preaction-log.txt 以进行调试,因为操作前脚本不会记录到构建日志中。
  2. 检查所需端口(在我们的示例中为 3000)上是否有正在运行的服务器。我使用了 WireMockClient 使用的相同方法:尝试访问“映射”API。如果成功,我们将退出脚本。
  3. 如果我们到了这一步,我们可以假设我们需要启动一个服务器。所以我们这样做,使用一些 XCode 环境变量来指向我们在项目中存储服务器可执行文件的位置(如果您始终在系统上安装 WireMock 客户端,您可以将路径更改为您喜欢的任何路径)。

现在,只要您运行测试用例,此脚本就会运行。我们仍然在 TestObserver 中运行结束时关闭服务器。

关于code-signing - 如何在 Xcode 10 和 macOS 10.14 下为 XCTest UI 测试启动 WireMock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54136011/

相关文章:

ios - iOS 静态库的代码签名

ios - XCTest 中 viewDidLoad 的设置值

xcode - 将环境变量传递给 XCUITest

objective-c - 通过 Coregraphic : crash at renderInContext 画线

swift - 如何修复 Xcode 10.0 调试器,它没有完全运行?

ios - 当我使用 xcode10 时,iOS9 崩溃

windows - SignerSignEx 用于签署 .exe 文件的示例源代码?

ios - Xcode 7 错误 : "Missing iOS Distribution signing identity for ..."

iphone - Xcode 失败并出现 "Code Signing"错误

Xcode 单元测试 : Xcode doesn't stop at breakpoints