【问题标题】:How to write unit test for button tap?如何为按钮点击编写单元测试?
【发布时间】:2019-05-14 08:25:28
【问题描述】:

在这里,我正在尝试检查视图控制器的单元测试用例。 - 我有一个带有按钮和标签的视图控制器。 - 当你点击按钮时,它会调用另一个方法。它将数据提供给按钮操作标签文本更改。
- 我想检查那个按钮是否触发了那个方法?不添加函数的任何布尔值或返回类型。

这是我的代码。

class ViewController: UIViewController {

    @IBOutlet weak var buttonFetch: UIButton?

    @IBOutlet weak var nameLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func fetchUser() {
        self.nameLabel.text = self.getUser()
    }

    func getUser() ->String {
        return User.data()
    }
}

struct User  {
    static func data()->String{
        return "Apple"
    }
}

这是我的测试用例

func testFetchUserAction() {
        controller.buttonFetch?.sendActions(for: .touchDown)
        // I want to test the method getUser from viewcontroller gets called or not
        // some thing like this XCTAssert(self.controller.getUser(),"not called")
        XCTAssertEqual(self.controller.nameLabel.text!, "Apple")

    }

【问题讨论】:

  • 为什么不使用 XCUITest 进行 ui 测试,比如按钮是否被点击?
  • @JatinKathrotiya 单元测试比 UI 测试快得多。
  • 那么你的目标是自相矛盾的。单元测试测试业务逻辑。如果你想测试点击按钮有什么效果,那就是 UI 测试。
  • @matt 单元测试测试你想要的任何东西。不要限制自己。我住在单元测试视图控制器上。 qualitycoding.org/testing-view-controllers
  • 值得肯定的论据。

标签: ios swift xctest xctestcase


【解决方案1】:

UIViewController 测试按钮上的假点击动作。

通过使用此帮助程序tap(_:),您可以验证您的按钮是否执行 @IBAction 你在测试你的 ViewController 时所期望的。

public func tap(_ button: UIButton) {
  button.sendActions(for: .touchUpInside)
}
// Button in your UIViewController
@IBOutlet weak var primaryButton: UIButton!

// In your XCTest subclass
var sut: UIViewController!

tap(sut.primaryButton) // example of use in your test() function

【讨论】:

    【解决方案2】:

    你错过了什么:

    确保在某处致电loadViewIfNeeded()

    这可以在测试中,也可以在setUp() 中。这将加载您的插座,并致电viewDidLoad()

    然后,尽可能测试调用动作的结果,而不是是否调用了方法。你已经在你的示例断言中做到了这一点。

    我还要补充一点,按钮的正确操作几乎总是.touchUpInside,而不是.touchDown。这允许用户按下按钮,然后拖走以改变主意。 “毕竟我不想推动这个。”

    【讨论】:

      【解决方案3】:

      你有没有像下面这样尝试过..

      func testFetchUserAction() {
      
          self.controller.nameLabel.text = nil
      
          //Use this line, If you assigned touchUpInside to your button action
          controller.buttonFetch?.sendActions(for: .touchUpInside)
      
          //Use this line, If you assigned touchDown to your button action
          controller.buttonFetch?.sendActions(for: .touchDown)
      
          XCTAssert(self.controller.nameLabel.text != nil, "not called")
      
      }
      

      注意:要故意让测试用例失败,可以在 sendActions 中更改 UIControl.Event

      【讨论】:

        【解决方案4】:

        我已经尝试如下,它通过了测试。 但我不确定它是否正确?

        XCTAssertNotNil(self.controller!.getUser, "get user method not called")
        

        【讨论】:

        【解决方案5】:

        在另一个回复中发现了类似的东西,尝试过这样的事情吗? 来源:How to add tap action for button in "Unit Testing" and show Alert

        func testTappingLoginButton_ShouldPresentAlert() {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let sut = storyboard.instantiateInitialViewController() as! ViewController
            sut.loadViewIfNeeded()
            let alertVerifier = QCOMockAlertVerifier()
        
            sut.loginButton.sendActions(for: .touchUpInside)
        
            XCTAssertEqual(alertVerifier.presentedCount, 1)
        }
        

        让我知道它是否有效!

        【讨论】:

          猜你喜欢
          • 2018-06-12
          • 2022-01-12
          • 2015-05-17
          • 2018-01-17
          • 2012-01-06
          • 2019-03-17
          • 2016-04-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多