在XCTestCase子类中使用泛型是否有效?

avi*_*ara 13 generics ios xctest swift

我有一个XCTestCase看起来像这样的子类.我已删除setup(),并tearDown为简洁的方法:

class ViewControllerTests <T : UIViewController>: XCTestCase {
    var viewController : T!

    final func loadControllerWithNibName(string:String) {
        viewController  = T(nibName: string, bundle: NSBundle(forClass: ViewControllerTests.self)) 
        if #available(iOS 9.0, *) {
            viewController.loadViewIfNeeded()
        } else {
            viewController.view.alpha = 1
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它的子类看起来像这样:

class WelcomeViewControllerTests : ViewControllerTests<WelcomeViewController> {
    override func setUp() {
        super.setUp()
        self.loadControllerWithNibName("welcomeViewController")
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    func testName() {
       let value =  self.viewController.firstNameTextField.text
        if value == "" {
            XCTFail()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

从理论上讲,这应该按预期工作 - 编译器不会抱怨任何事情.但只是当我运行测试用例时,该setup()方法甚至不会被调用.但是,它表示当明确的testName()方法失败时,测试已经过去了.

仿制药的使用是一个问题吗?我可以很容易地想到许多非泛型方法,但我非常想写这样的测试用例.这是XCTest在Objective-C和Swift之间的互操作性问题吗?

Gwe*_*oué 7

XCTestCase使用Objective-C运行时加载测试类并查找测试方法等.

Swift泛型类与Objective-C不兼容.请参阅https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID53:

当您创建一个源自Objective-C类的Swift类时,可以从Objective-C自动获得与Objective-C兼容的类及其成员属性,方法,下标和初始化程序.这不包括仅限Swift的功能,例如此处列出的功能:

  • 泛型

...

因此, XCTest不能使用您的通用XCTestCase子类.

  • 这是不幸的。对于此类框架限制,应该存在编译时错误。 (2认同)
  • 而且,既然XCTest是开源的(https://github.com/apple/swift-corelibs-xctest),您可以在https://bugs.swift.org上做出贡献或创建一个开放的bug报告。 (2认同)

小智 5

嗯,实际上它完全可行。您只需要创建一个类似于测试运行器的类。例如:

class TestRunner: XCTestCase {
    override class func initialize() {
        super.initialize()
        let case = XCTestSuite(forTestCaseClass: ViewControllerTests<WelcomeViewController>.self)
        case.runTest()
    }
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以运行所有通用测试。