Ci sono molti sviluppatori che evitano o non credono di poter testare UIViewControllers. Apples poor testing doco non aiuta neanche questo.
UIViewControllers sono abbastanza testabili con un numero di approcci che è possibile adottare.
In primo luogo, come chiunque altro vi dirà, cercate di mantenere la logica aziendale fuori dal vostro controller di visualizzazione. Prova a farlo solo per caricare la vista e il meno possibile. Passare dall'architettura MVC a qualcos'altro può aiutare con questo. A seconda di ciò che si sta creando, si può anche prendere in considerazione l'utilizzo di classi di UIView personalizzate per aiutare pure.
test di unità/logica pura
mi avete a che fare con quello che Apple chiamata 'test Logica', vale a dire un bersaglio di prova senza eseguibile assegnato. Puoi ancora testare molto. I metodi che contengono un semplice codice di gestione delle viste possono essere testati impostando manualmente una vista, oppure usando il codice di prova per caricare manualmente un file xib, ecc. Strutture di simulazione come OCMock possono essere molto utili.
Spesso, tuttavia, in questi tipi di test, è necessario eseguire manualmente vari metodi del ciclo di vita per eseguire il codice che si desidera testare.Ad esempio, se si vogliono testare un metodo viewDidLoad
:
id mockView = OCMClassMock([UIView class]);
// Setup mock expectations.
myViewController.view = mockView;
[myViewController viewDidLoad];
test applicativi
Se si utilizza un obiettivo di prova in cui è stata impostata l'applicazione, quindi si può effettivamente fare alcuni test da un unit test senza provare a navigare l'app. Questo è un po 'un trucco, ma a volte l'ho trovato abbastanza utile.
UIView *myView = // ... load the view manually or simply [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)]
myViewController.view = myView;
[[UIApplication sharedApplication].keyWindow addSubview:myView];
Assicurarsi di rimuovere la vista nel teardown se si utilizza questo approccio. Il vantaggio di questo è che tutti i metodi del ciclo di vita intorno a ottenere una vista sullo schermo vengono automaticamente chiamati per te.
Principalmente l'ho trovato utile per i test in relazione ai controller di visualizzazione e alle viste personalizzate relative a viste che sono parti di layout di schermo più grandi. Non tanto i controller di visualizzazione di livello superiore.
test UI
Infine v'è il nuovo framework di test di interfaccia utente che Apple ha fornito. Ho usato framework Ruby di terze parti come Frank e Calabash in passato. A quanto pare, il test dell'interfaccia utente di Apple è abbastanza buono e abbastanza simile a questi strumenti.
Il trucco con esso è usarlo per costruire una libreria di metodi che hanno senso e aiutano a descrivere (usando una DSL) vari aspetti della tua app.
Lo svantaggio di questo approccio è che non è possibile caricare solo la vista che si desidera testare. Devi effettivamente eseguire l'app e navigare verso di essa. L'altro aspetto negativo di questo è che si basa molto sulla vista basata sull'accessibilità esterna della tua app. È quasi impossibile raggiungere le parti interne in modo che i test si basino sul comportamento delle schermate delle app piuttosto che sulle classi interne.
Finora non ho esplorato l'idea di mescolare questa forma di test e caricare manualmente le viste sulla finestra, ma non riesco a capire perché non funzionerebbe.
Che cosa stai cercando di testare? Quale valore fornirebbe un test unitario in questo scenario? –
Quindi con UIView * v = [vista vc] Controllo se la vista è caricata e non è nulla, XCTAssertNotNil (v, @ "Dovrebbe essere caricata") ... ma per gli altri metodi del ciclo di vita sto cercando di istruirmi è una pratica di test unitaria comune. Intendo anche aumentare la copertura del codice. – ramo
@ramo Non penso che ci sia molto valore nel testare la capacità del framework UIKit di caricare la vista, a meno che tu non sia preoccupato di non riuscire a creare le connessioni corrette in uno .xib o storyboard. –