我有一个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 } } }
它的子类看起来像这样:
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() } } }
在理论上,这应该按预期工作 – 编译器不会抱怨任何事情.但是只是当我运行测试用例时,setup()方法甚至没有被调用.但是,它表明当testName()方法应该失败时,测试已经过去了.
使用泛型是一个问题吗?我可以很容易地想到很多非通用的方法,但是我很想写这样的测试用例.这是XCTest在Objective-C和Swift之间的互操作性?
解决方法
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:
When you create a Swift class that descends from an Objective-C class,the class and its members—properties,methods,subscripts,and initializers—that are compatible with Objective-C are automatically available from Objective-C. This excludes Swift-only features,such as those listed here:
- Generics
…
Ergo您的通用XCTestCase子类不能被XCTest使用.