I have a XCTestCase
subclass that looks something like this. I have removed setup()
and tearDown
methods for brevity:
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
}
}
}
And its subclass that looks something like this :
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()
}
}
}
In theory, this should work as expected -- the compiler doesn't complain about anything. But it's just that when I run the test cases, the setup()
method doesn't even get called. But, it says the tests have passed when clearly testName()
method should fail.
Is the use of generics a problem? I can easily think of many non-generic approaches, but I would very much want to write my test cases like this. Is the XCTest's interoperability between Objective-C and Swift the issue here?
XCTestCase uses the Objective-C runtime to load test classes and find test methods, etc.
Swift generic classes are not compatible with Objective-C. See 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 your generic XCTestCase subclass can not be used by XCTest.
Well, actually its totally doable. You just have to create a class that will be sort of test runner. For example:
class TestRunner: XCTestCase {
override class func initialize() {
super.initialize()
let case = XCTestSuite(forTestCaseClass: ViewControllerTests<WelcomeViewController>.self)
case.runTest()
}
}
This way you can run all your generic tests.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With