2016-02-08 7 views
11

Ich habe eine XCTestCase Unterklasse, die in etwa so aussieht. Ich habe setup() und tearDown Methoden der Kürze entfernt:Ist die Verwendung von Generics in XCTestCase-Unterklassen gültig?

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 
     } 
    } 
} 

Und seine Unterklasse, die etwa wie folgt aussieht:

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() 
     } 
    } 
} 

Theoretisch sollte dies wie erwartet - der Compiler nicht über beschwert etwas. Aber wenn ich die Testfälle durchführe, wird die Methode setup() nicht einmal aufgerufen. Aber es sagt, dass die Tests bestanden haben, als klar testName() Methode fehlschlagen sollte.

Ist die Verwendung von Generika ein Problem? Ich kann mir leicht viele nicht-generische Ansätze vorstellen, aber ich würde meine Testfälle gerne so schreiben. Ist die Interoperabilität des XCTest zwischen Objective-C und Swift hier das Problem?

+0

Ich denke, Sie haben Ihre eigene Frage beantwortet: Setup und Test werden nicht aufgerufen. Deine Idee sieht nützlich aus. Vielleicht könnten Sie versuchen, eine Pull-Anfrage zu implementieren: https://github.com/apple/swift-corelibs-xctest –

+0

Warum werden sie nicht aufgerufen, ist die Frage. In der Zwischenzeit habe ich eine sehr grobe Art und Weise, dies zu tun implementiert. Bringt mein Herz zum Wackeln. – avismara

+0

@avismara Was war Ihre Lösung? Ich verwende Swift 4 und kann immer noch keine Tests ausführen, wenn ich eine generische Unterklasse verwende. – Kdawgwilk

Antwort

5

XCTestCase verwendet die Objective-C-Laufzeit-Testklassen zu laden und Prüfverfahren usw.

Swift generische Klassen sind nicht kompatibel mit Objective-C zu finden. Siehe https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID53:

Wenn Sie eine Swift-Klasse erstellen, die von einer Objective-C-Klasse absteigt, die Klasse und ihre Mitglieder-Eigenschaften, Methoden, Indizes und initializers-die mit Objective-C kompatibel sind, sind automatisch verfügbar von Ziel c. Dies schließt Swift-only-Features, wie sie hier aufgelistet:

  • Generics

...

Ergo Ihre allgemeine XCTestCase Unterklasse kann nicht durch XCTest verwendet werden.

+1

Das ist bedauerlich. Es sollte einen Kompilierzeitfehler für diese Art von Framework-Einschränkungen geben. – avismara

+1

Sicher. Aber sagen Sie uns, wie um alles in der Welt könnten sie diesen zusätzlichen Anwendungsfall erraten haben? Öffnen Sie ein Radar und nehmen Sie keine Tests und Compiler-Schutzmechanismen für das, was sie nicht sind. Deine eigenen Fähigkeiten sind immer noch nützlich. –

+1

Nun, da XCTest Open-Source ist (https://github.com/apple/swift-corelibs-xctest), können Sie unter https: //bugs.swift einen Beitrag leisten oder einen offenen Fehlerbericht erstellen.org –

2

Nun, eigentlich ist es total machbar. Sie müssen nur eine Klasse erstellen, die eine Art Test Runner sein wird. Zum Beispiel:

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

Auf diese Weise können Sie alle Ihre generischen Tests ausführen.

Verwandte Themen