Catbird

Test GitHub license CocoaPods Compatible Platform SPM compatible

特性

安装

要在 UI 测试中使用 Catbird,您必须拥有 Catbird 服务器和 Catbird API 代码,以便与服务器进行通信。

类型 服务器 API 代码
手动
Homebrew 🚫
SPM 🚫
CocoaPods

手动

最新版本页面下载 catbird.zip 压缩包。

使用 Homebrew

运行以下命令

brew install RedMadRobot/formulae/catbird

使用 SPM

如果您有一个 Xcode 项目,请打开它并使用以下 URL 添加 Catbird Package

https://github.com/RedMadRobot/catbird.git

使用 CocoaPods

Catbird 添加到 UI 测试目标。

target 'App' do
  use_frameworks!

  target 'AppUITests' do
    inherit! :search_paths

    pod 'Catbird'
  end
end

在 Xcode 项目中设置

用法

import XCTest
import Catbird

enum LoginMock: CatbirdMockConvertible {
    case success
    case blockedUserError

    var pattern: RequestPattern {
        RequestPattern(method: .POST, url: URL(string: "/login")!)
    }

    var response: ResponseMock {
        switch self {
        case .success:
            let json: [String: Any] = [
                "data": [
                    "access_token": "abc",
                    "refresh_token": "xyz",
                    "expired_in": "123",
                ]
            ]
            return ResponseMock(
                status: 200,
                headers: ["Content-Type": "application/json"],
                body: try! JSONSerialization.data(withJSONObject: json))

        case .blockedUserError:
            let json: [String: Any] = [
                "error": [
                    "code": "user_blocked",
                    "message": "user blocked"
                ]
            ]
            return ResponseMock(
                status: 400,
                headers: ["Content-Type": "application/json"],
                body: try! JSONSerialization.data(withJSONObject: json))
        }
    }
}

final class LoginUITests: XCTestCase {

    private let catbird = Catbird()
    private var app: XCUIApplication!

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        app = XCUIApplication()

        // Base URL in app `UserDefaults.standard.url(forKey: "url_key")`
        app.launchArguments = ["-url_key", catbird.url.absoluteString]
        app.launch()
    }

    override func tearDown() {
        XCTAssertNoThrow(try catbird.send(.removeAll), "Remove all requests")
        super.tearDown()
    }

    func testLogin() {
        XCTAssertNoThrow(try catbird.send(.add(LoginMock.success)))

        app.textFields["login"].tap()
        app.textFields["login"].typeText("john@example.com")
        app.secureTextFields["password"].tap()
        app.secureTextFields["password"].typeText("qwerty")
        app.buttons["Done"].tap()

        XCTAssert(app.staticTexts["Main Screen"].waitForExistence(timeout: 3))
    }

    func testBlockedUserError() {
        XCTAssertNoThrow(try catbird.send(.add(LoginMock.blockedUserError)))

        app.textFields["login"].tap()
        app.textFields["login"].typeText("peter@example.com")
        app.secureTextFields["password"].tap()
        app.secureTextFields["password"].typeText("burger")
        app.buttons["Done"].tap()

        XCTAssert(app.alerts["Error"].waitForExistence(timeout: 3))
    }
}

请求模式

您可以指定一个模式来捕获 http 请求,并使用模拟数据生成响应。 模式匹配适用于请求中的 URL 和 http 标头。 请参阅 RequestPattern 结构体。

可以使用三种类型的模式

注意

如果要对 url 查询参数应用通配符模式,请不要忘记转义域名或路径后的 ? 符号。

Pattern.wildcard("http://example.com\?query=*")

通配符模式

“通配符”是您在命令行执行类似 ls *.js 的操作,或在 .gitignore 文件中放置 build/* 时输入的模式。

在我们的实现中,任何通配符模式都会转换为正则表达式,并应用于 URL 或标头字符串的匹配。

以下字符在模式中使用时具有特殊的魔法含义

您可以使用反斜杠 \ 转义特殊字符。

不支持组中的否定。

示例项目

$ cd Example/CatbirdX
$ bundle exec pod install
$ xed .

环境变量

Catbird 仅支持代理 HTTP 请求。 不支持 HTTPS 请求!

重定向示例

使用 CATBIRD_REDIRECT_URL 运行 catbird。

CATBIRD_REDIRECT_URL=https://api.github.com ./catbird

所有直接请求都将转发到 CATBIRD_REDIRECT_URL

curl http://127.0.0.1:8080/zen

响应将返回到请求 https://api.github.com/zen

代理示例

使用 CATBIRD_PROXY_ENABLED=1 运行 catbird。

CATBIRD_PROXY_ENABLED=1 ./catbird

通过启用此模式,catbird 将作为本地 http 代理服务器运行。 您可以将您的 http 客户端配置为使用此代理,所有请求都将通过 catbird 代理并重定向到实际主机。 如果您不想更改请求的基本 url,这可能会有所帮助。

curl http://api.github.com/zen --proxy http://127.0.0.1:8080

日志

可以在 Console.app 中查看具有子系统 com.redmadrobot.catbird 的日志

不要忘记在操作菜单中包含消息

没有这个,只有错误消息是可见的

网页

您可以在页面 http://127.0.0.1:8080/catbird 上查看所有拦截到的请求的列表

并行测试

对于并行测试,您需要满足几个条件。

final class LoginUITests: XCTestCase {

    private let catbird = Catbird(parallelId: UUID().uuidString)
    private var app: XCUIApplication!

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        app = XCUIApplication()

        app.launchArguments = [
            // Base URL in app `UserDefaults.standard.url(forKey: "url_key")`
            "-url_key", catbird.url.absoluteString,

            // `parallelId` in app `UserDefaults.standard.url(forKey: "parallelId")`
            "-parallelId", catbird.parallelId!
        ]
        app.launch()
    }
}