【问题标题】:Cannot override init() function in Swift XCTestCase无法覆盖 Swift XCTestCase 中的 init() 函数
【发布时间】:2018-11-18 16:47:51
【问题描述】:

出于以下几个原因,我想在 UI 测试中覆盖 XCTestCase 的 init 函数:

  • 在 setUp() 之外启动应用程序,这样应用程序就不需要为每次测试重新启动(这很乏味并且会减慢测试速度)
  • 要初始化其他提供一般导航应用程序的类,我必须使用测试用例 (self) 对其进行初始化。

我现在的样子是这样的:

import XCTest

class UITest: XCTestCase {

    let app = XCUIApplication()

    // Helper packages
    var helper: UITestHelper!

    override func setUp() {
        super.setUp()

        // Helper package instantiation
        helper = UITestHelper(withTestCase: self, forApp: app)

        continueAfterFailure = false
        app.launch()
    }

... tearDown(), tests ....

当我打电话时:

override init() {
    super.init()
    foo()
}

我收到Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

【问题讨论】:

  • 一种可能的解决方法是使用lazy 变量,但请不要这样做。它将在您的测试之间创建依赖关系。

标签: ios swift xcode xcode-ui-testing


【解决方案1】:

init 不是XCTestCase 的指定初始化器。指定的初始化程序是initWithInvocation:。这需要一个NSInvocation,它在 Swift 中不可用。执行您所描述的操作的唯一方法是在 ObjC 中。

这没有记录,因为它不受支持。可能实现您所描述的,但它可能会以微妙的方式中断,您应该探索其他解决方案来解决您的问题。

崩溃是 ObjC 初始化语义的副产品。每个 ObjC 类都必须响应 init(因为它继承自 NSObject)。但是,当调用init 时,有很多 ObjC 对象没有正确初始化。 (NSError 因这个问题而出名。)知道的唯一方法是通过文档。更复杂的 Swift 初始化系统是为了解决 ObjC 初始化系统中的问题。

我会将您的更深层次的目标分解为单独的问题并询问如何解决它们(您还应该非常清楚地表明您正在谈论 UI 测试;虽然您的代码表明了这一点,但从文本中并不清楚)。确保您所描述的内容不会破坏 Xcode 10 的新并行测试功能以及对排序的更改。

【讨论】:

  • 它会破坏一件事的测试并行化,它会使一个测试依赖于套件中的其他测试,这通常是一件坏事。
猜你喜欢
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 2021-07-11
相关资源
最近更新 更多