XCTestCase的UIButton点击 [英] XCTestCase of a UIButton tap

查看:256
本文介绍了XCTestCase的UIButton点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图对UIViewController中的按钮抽头的布线进行单元测试,但是我发现即使正在运行的应用程序中的代码运行正常,这些测试也失败了.

I am trying to unit test the wiring of button taps in a UIViewController but I'm finding these tests fail even though the code in the running app works fine.

我通过删除视图控制器简化了失败的测试,并简化了操作:

I've simplified the failing test by removing the view controller and such leaving simply:

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)
  • 轻击按钮
  • 等待期望.
  • Wires up an action to a button that fulfils a test expectation
  • Taps the button using button.sendActions(for: .touchUpInside)
  • Waits for the expectations.

失败是:

异步等待失败:超出了0.1秒的超时,并且未实现预期:已收到按钮点击".

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

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

I don't want to use a UI test fo this. They are many orders of magnitude slower to execute, and a unit test should be ideal here.

  • 是否由于发送UIButton操作需要响应者链的其他一些设置而失败?还是这里不存在的运行循环?或者是其他东西?如何在不实例化完整的运行应用程序的情况下在单元测试中进行最少的设置?
  • 我最初尝试在没有期望的情况下同步测试按钮的点击(这也没有用,所以我认为我会异步尝试)–如果您可以帮助使其正常工作,请同时说明动作发送是同步还是异步.
  • Is this failing because the UIButton action sending requires some additional setup of the responder chain? Or a run loop that is not present here? Or something else? How can I set this up minimally in a unit test without instantiating a complete running app?
  • I initially tried to synchronously test button taps without an expectation (this also didn't work so I thought I'd try asynchronously) – if you can help to get this working, please also indicate if action sending is synchronous or asynchronous.

推荐答案

关于控制事件的问题一个答案,该事件要求控制事件需要UIApplication实例才能发送动作.不幸的是,这个问题并未说明如何实现.

A question about control events has an answer that control events require a UIApplication instance to send actions. Unfortunately the question doesn't indicate how this might be done.

此处使用swizzling修补在UIControl上发送的操作的实现的补丁,这样它就不会委派给UIApplication.它之所以无法迅速建立,是因为它依赖于覆盖initialize,但是这可能是可修复的.

There's also some code here that uses swizzling to patch the implementation of action sending on UIControl so that it doesn't delegate to UIApplication. It doesn't build with recent swift because it relies on overriding initialize – this might be fixable however.

我采用的方法是在UIControl上实现扩展,以用于测试中,该扩展提供了如下所示的方法simulateEvent(_ event: UIControl.Event):

The approach that I've taken is to implement an extension on UIControl for use in tests that provides a method simulateEvent(_ event: UIControl.Event) which goes like this:

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中发送按钮.我还认为它是非侵入性的,并且接受单元测试未在完整的应用程序环境中运行的事实,因此测试无法利用完整的响应程序处理.

This could be refined to properly examine the selector and determine if the sender and event should also be sent, but it's a reasonable proof of concept and allows for button sending in XCUnitTest. I also feel it's non invasive and accepts the fact that a unit test is not running in a full application environment, so tests can't make use of full responder handling.

这篇关于XCTestCase的UIButton点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆