gpt4 book ai didi

ios - UIButton 点击​​的 XCTestCase

转载 作者:行者123 更新时间:2023-11-29 05:22:36 28 4
gpt4 key购买 nike

我正在尝试对 UIViewController 中的按钮点击接线进行单元测试,但我发现即使正在运行的应用程序中的代码工作正常,这些测试也会失败。

我通过删除 View Controller 简化了失败的测试,这样就简单地留下了:

import XCTest

class ButtonTest: XCTestCase {

var gotTap: XCTestExpectation!

func test_givenButtonWithTargetForTapAction_whenButtonIsSentTapAction_thenTargetIsCalled() {

gotTap = expectation(description: "Button tap recieved")

let button = UIButton()
button.addTarget(self, action: #selector(tap), for: .touchUpInside)

button.sendActions(for: .touchUpInside)

// Fails.
wait(for: [gotTap], timeout: 0.1)
}

@objc func tap() {
gotTap.fulfill()
}
}

测试的结果:

  • 将操作连接到满足测试期望的按钮
  • 使用 button.sendActions(for: .touchUpInside) 轻按按钮
  • 等待期望。

失败的是:

Asynchronous wait failed: Exceeded timeout of 0.1 seconds, with unfulfilled expectations: "Button tap recieved".

我不想为此使用 UI 测试。它们的执行速度要慢很多数量级,单元测试在这里应该是理想的选择。

问题

  • 此失败是否是因为 UIButton 操作发送需要响应程序链的一些额外设置?或者这里不存在的运行循环?或者是其他东西?如何在单元测试中进行最低限度的设置,而不实例化完整的运行应用程序?
  • 我最初尝试在没有预期的情况下同步测试按钮点击(这也不起作用,所以我想我会异步尝试) - 如果您可以帮助实现此功能,还请指出操作发送是同步还是异步.

最佳答案

A question关于控制事件有an answer控制事件需要 UIApplication 实例来发送操作。不幸的是,这个问题并没有表明如何做到这一点。

还有一些代码here它使用 swizzling 来修补在 UIControl 上发送的操作的实现,以便它不会委托(delegate)给 UIApplication。它不是用最近的 swift 构建的,因为它依赖于重写 initialize - 不过这可能是可以修复的。

我采取的方法是在 UIControl 上实现一个扩展,以便在测试中使用,该扩展提供了一个方法 simulateEvent(_ event: UIControl.Event) ,该方法如下像这样:

extension UIControl {

func simulateEvent(_ event: UIControl.Event) {
for target in allTargets {
let target = target as NSObjectProtocol
for actionName in actions(forTarget: target, forControlEvent: event) ?? [] {
let selector = Selector(actionName)
target.perform(selector)
}
}
}
}

这可以改进以正确检查选择器并确定是否也应该发送发送者和事件,但它是一个合理的概念证明,并且允许在 XCUnitTest 中发送按钮。我还认为它是非侵入性的,并接受单元测试未在完整的应用程序环境中运行的事实,因此测试无法利用完整的响应程序处理。

关于ios - UIButton 点击​​的 XCTestCase,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58519479/

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