We are using a standalone wiremock instance as a mock server for our Xcode UI tests. We have an test observer class which is responsible for spinning up this instance (if required) and tearing it down upon completion of the test run. The code for the observer is as follows:
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()
}
}
All was well until I moved to macOS 10.14. Formerly, we were not code signing the UITest target. Upon moving to 10.14, running tests now fails with a bootstrap error before the tests even begin to run. I discovered that turning on automatic code-signing for on the tests gets around this problem.
ただし、これにより2番目の問題が発生します。launchedProcess
上記の行で、ワイヤーモックサーバーを起動しようとすると失敗しjava.lang.RuntimeException: java.net.SocketException: Operation not permitted
ます。テストを実行する前にサーバーを(コマンドラインなどで)起動すると、すべて正常に動作します。
では、どうすればこのキャッチ22から抜け出すことができますか?10.13ではすべてがうまく機能しました。コード署名がモックサーバーの起動と何の関係があるのかは私にはわかりません。
質問に対する直接の回答は得られませんでしたが、回避策は見つかりました。TestObserverを使用してWireMockサーバーを起動する代わりに、テストで事前アクションを使用できます。
これを行うには、UIテストプロジェクトのスキームを編集します。
Test
、をクリックしますPre-actions
+
てアクションスクリプトを追加します/bin/sh
)Provide build settings from
, choose your test targetFor the script, I used the following code:
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}" &
Here's what the script does:
/tmp/preaction-log.txt
, for debugging, as pre-action scripts do not get logged to the build log.これで、テストケースを実行するたびにこのスクリプトが実行されます。TestObserver内での実行の最後に、サーバーをシャットダウンします。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加