gpt4 book ai didi

ios - XCode UI 测试 swizzle API 类方法

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:21:11 27 4
gpt4 key购买 nike

我有一个带有两个按钮的简单应用程序,它调用 JSON 网络服务并打印出结果消息。

我想尝试新的 XCode 7 UI 测试,但我不明白如何模拟 API 请求。

为简单起见,我构建了一个没有实际请求或任何异步操作的示例。

我在主要目标中有 ZZSomeAPI.swift 文件:

import Foundation
public class ZZSomeAPI: NSObject {
public class func call(parameter:String) -> Bool {
return true
}
}

然后是我的ZZSomeClientViewController.swift:

import UIKit
class ZZSomeClientViewController: UIViewController {
@IBAction func buttonClick(sender: AnyObject) {
print(ZZSomeAPI.call("A"))
}
}

现在我已经添加了一个 UITest 目标,记录了点击按钮的过程,我有类似的东西:

import XCTest
class ZZSomeClientUITests: XCTestCase {
override func setUp() {
super.setUp()
continueAfterFailure = false
XCUIApplication().launch()
}

func testCall() {
let app = XCUIApplication()
app.childrenMatchingType(.Window).elementBoundByIndex(0).childrenMatchingType(.Other).element.childrenMatchingType(.Other).elementBoundByIndex(1).childrenMatchingType(.Button).elementBoundByIndex(0).tap()
}
}

所以这有效,运行测试将打印出 true。但是我想在 API 返回 false 时包含一个测试而不弄乱 API。因此,我将 ZZSomeAPI.swift 添加到 UI 测试目标并尝试方法调配(更新了 UITest 代码):

import XCTest

class ZZSomeClientUITests: XCTestCase {

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

func testSwizzle() {
XCTAssert(ZZSomeAPI.call("a"))
XCTAssertFalse(ZZSomeAPI.callMock("a"))
XCTAssert(ZZSomeAPI.swizzleClass("call", withSelector: "callMock", forClass: ZZSomeAPI.self))
XCTAssertFalse(ZZSomeAPI.call("a"), "failed swizzle")
}

func testCall() {
XCTAssert(ZZSomeAPI.swizzleClass("call", withSelector: "callMock", forClass: ZZSomeAPI.self))
let app = XCUIApplication()
app.childrenMatchingType(.Window).elementBoundByIndex(0).childrenMatchingType(.Other).element.childrenMatchingType(.Other).elementBoundByIndex(1).childrenMatchingType(.Button).elementBoundByIndex(0).tap()
}

}

extension NSObject {
public class func swizzleClass(origSelector: String!, withSelector: String!, forClass:AnyClass!) -> Bool {
var originalMethod: Method?
var swizzledMethod: Method?

originalMethod = class_getClassMethod(forClass, Selector(origSelector))
swizzledMethod = class_getClassMethod(forClass, Selector(withSelector))

if (originalMethod == COpaquePointer(bitPattern: 0)) { return false }
if (swizzledMethod == COpaquePointer(bitPattern: 0)) { return false }

method_exchangeImplementations(originalMethod!, swizzledMethod!)
return true
}
}

extension ZZSomeAPI {
public class func callMock(parameter:String) -> Bool {
return false
}
}

因此,testSwizzle() 通过,这意味着调配有效。但是 testCall() 仍然打印 true 而不是 false
是因为当 UITest 和主要目标是两个不同的应用程序时,swizzling 只在测试目标上完成吗?
有什么办法解决这个问题吗?

我找到了 Mock API Requests Xcode 7 Swift Automated UI Testing但我不确定如何在此处使用 launchArguments
在示例中只有一种情况,但我需要模拟 call() 方法以获得不同测试方法的不同结果...如果我使用 launchArgument 例如 MOCK_API_RESPONSE 包含要返回的完整响应,主要目标应用程序委托(delegate)将有一些“丑陋的仅测试”代码......有没有办法检查(在主要目标中)它正在被编译对于一个 UITest 目标,所以它只包含那个模拟 launchArguments 的代码?

最干净的选择确实是让 swizzling 工作......

最佳答案

Xcode UI 测试在与您的应用程序不同的应用程序中执行。因此,对测试运行器应用程序中类的更改不会影响被测应用程序中的类。

这与单元测试不同,在单元测试中,您的测试在您的应用程序进程中运行。

关于ios - XCode UI 测试 swizzle API 类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33629875/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com