2016-02-08 23 views
11

Ho una sottoclasse XCTestCase simile a questa. Ho rimosso setup() e tearDown metodi per brevità:L'uso di generici è valido nelle sottoclassi XCTestCase?

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

E la sua sottoclasse che sembra qualcosa di simile:

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 teoria, questo dovrebbe funzionare come previsto - il compilatore non lamentarsi nulla. Ma è solo che quando eseguo i test case, il metodo setup() non viene nemmeno chiamato. Ma, dice che i test sono passati quando il metodo testName() avrebbe dovuto fallire.

L'uso di generici è un problema? Posso facilmente pensare a molti approcci non generici, ma vorrei scrivere i miei casi di test in questo modo. L'interoperabilità dell'XCTest tra Objective-C e Swift è il problema qui?

+0

Penso che tu abbia risposto alla tua stessa domanda: setUp e test non vengono invocati. La tua idea sembra utile. Forse potresti provare a implementare una richiesta pull: https://github.com/apple/swift-corelibs-xctest –

+0

Perché non vengono richiamati, è la domanda. Nel frattempo, ho implementato un modo molto crudo per farlo. Mi fa ribollire il cuore – avismara

+0

@avismara Qual è stata la tua soluzione? Sto usando Swift 4 e non riesco ancora a eseguire test quando utilizzo una sottoclasse generica – Kdawgwilk

risposta

5

XCTestCase utilizza il runtime Objective-C per caricare classi di test e di trovare metodi di prova, ecc

classi generiche Swift non sono compatibili con Objective-C. Vedi https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID53:

Quando si crea una classe Swift che scende da una classe Objective-C, la classe ed i suoi soci-proprietà, metodi, indici, e inizializzatori-compatibili con Objective-C sono automaticamente disponibili da Objective-C. Ciò esclude Swift-solo le caratteristiche, come ad esempio quelli elencati qui:

  • Generics

...

Ergo sottoclasse XCTestCase generico non può essere utilizzato da XCTest.

+1

Questo è sfortunato. Ci dovrebbe essere un errore in fase di compilazione per questo tipo di limitazioni del framework. – avismara

+1

Sicuro. Ma dicci solo come mai avrebbero potuto indovinare questo caso d'uso extra-limite? Apri un radar e non fare test e compilatori di sicurezza per ciò che non sono. Le tue abilità sono ancora utili. –

+1

Inoltre, ora che XCTest è open-source (https://github.com/apple/swift-corelibs-xctest), puoi dare un contributo o creare una segnalazione di bug aperta su https: //bugs.swift.org –

2

Beh, in realtà è completamente fattibile. Devi solo creare una classe che sarà una sorta di corridore di prova. Ad esempio:

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

In questo modo è possibile eseguire tutti i test generici.