Domanda

Sto eseguendo la migrazione del mio progetto da Xcode 4.6.3 a Xcode 5.0.2.Gli unit test del progetto sono stati sviluppati con SenTestingKit/OCUnit.Ora, quando eseguo i test in Xcode 5, ricevo un errore da RunUnitTests lo script mi ​​dice questo

RunUnitTests è obsoleto.

Forse correlata è questa nota nelle note di rilascio di Xcode 5:

SenTestingKit e OCUnit sono deprecati.Utilizzare il programma di migrazione per passare a XCTest.

Purtroppo non sono riuscito a saperne di più su questo misterioso "migratore".Forse il mio google-fu manca [di nuovo], quindi la mia domanda principale è:Come posso migrare gli unit test da SenTestingKit/OCUnit al nuovo XCTest (con o senza il "migratore")?

Una domanda secondaria, nel caso in cui la migrazione sia un'attività complicata:È possibile fare in modo che Xcode 5 esegua unit test ancora basati su SenTestingKit/OCUnit?Dopotutto questi sono semplicemente deprecati, quindi dovrebbero essere ancora disponibili e funzionanti.

È stato utile?

Soluzione

Grazie alla risposta di Shaggy Frog sappiamo che il misterioso "migratore" menzionato nelle note di rilascio di Xcode è una procedura guidata avviata selezionando "Modifica > Refactor > Converti in XCTest".Scriverò della mia esperienza con questa procedura guidata in due parti.La prima parte è una risposta incompleta alla domanda primaria, la seconda parte risponde alla domanda secondaria.


Parte 1:Come migrare da OCUnit a XCTest

La prima cosa che devi capire è che affinché la procedura guidata funzioni, devi farlo selezionare una destinazione del test unitario.Se è selezionata la destinazione principale, la procedura guidata semplicemente non elenca alcuna destinazione da convertire.

Una volta scoperto questo, ho potuto eseguire la procedura guidata, ma nel mio caso il risultato finale è stato comunque un fallimento spettacolare!La procedura guidata affermava che non erano necessarie modifiche all'origine e che era necessario aggiornare solo le impostazioni di creazione per migrare a XCTest.Alla fine, la procedura guidata non è riuscita nemmeno a farlo correttamente:Esso fatto rimosso il riferimento al framework SenTestingKit, ma così è stato non inserire un riferimento al framework XCTest.

Ad ogni modo, quello che segue è un elenco delle modifiche che ho dovuto apportare manualmente perché la procedura guidata non è riuscita ad apportarle.Se la procedura guidata funziona meglio per te, potresti non aver bisogno di fare tutte queste cose.

  1. Rimuovere la fase di compilazione "Esegui script" dalla destinazione dello unit test
  2. Modificare la classe base di tutte le classi dei test case da SenTestCase A XCTestCase
  3. Modificare l'intestazione importata da <SenTestingKit/SenTestingKit.h> A <XCTest/XCTest.h>
  4. Nelle Impostazioni di creazione della destinazione del test, modifica Estensione wrapper da octest A xctest.
  5. Rinominare tutte le macro assert da ST* A XCT* (per esempio. STAssertTrue diventa XCTAssertTrue)
  6. Eccezione a quanto sopra: STAssertEquals deve essere rinominato in XCTAssertEqual (notare la "s" mancante alla fine).Saprai di essertene dimenticato se ricevi questo avviso del compilatore: warning: implicit declaration of function 'XCTAssertEquals' is invalid in C99
  7. Le nuove macro di asserzione XCTest non lo consentono nil da passare come descrizione dell'errore.Ad esempio, XCTAssertNotNil(anObject, nil) non è possibile e deve essere modificato in XCTAssertNotNil(anObject).Saprai di avere questo problema quando ricevi questo errore del compilatore: error: called object type 'NSString *' is not a function or function pointer.
  8. Se tu Fare necessario passare una descrizione dell'errore, le nuove macro assert XCTest richiedono un'espressione costante per l'identificatore di formato, proprio come NSString metodo di classe stringWithFormat: fa.Saprai di avere questo problema quando ricevi questo errore del compilatore: error: expected ')'.Qualche esempio:
NSString* formatSpecifier = @"%@";
NSString* failureDescription = @"foo";
// These are OK
XCTAssertNotNil(anObject, @"foo")
XCTAssertNotNil(anObject, @"%@", failureDescription)
// These are not OK
XCTAssertNotNil(anObject, failureDescription);
XCTAssertNotNil(anObject, formatSpecifier, failureDescription);

Ultimo ma non meno importante, come già accennato più sopra, è necessario aggiungere al target dello unit test il riferimento al framework XCTest.Saprai di averlo dimenticato se ricevi errori del linker come Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo.

Aggiornamento Xcode 6:Il collegamento a XCTest non è più richiesto in Xcode 6 (in effetti XCTest non è nemmeno più elencato come framework disponibile).Imposta invece l'impostazione di build CLANG_ENABLE_MODULES su YES (esposto nell'interfaccia utente come "Abilita moduli (C e Objective-C)").Ciò causerà clang per collegarsi automaticamente a XCTest quando vede un file #import <XCTest/XCTest.h> dichiarazione.I dettagli sono disponibili in Sezione "Moduli" della documentazione di clang.


Parte 2:Come eseguire i test OCUnit in Xcode 5

A questo punto ho ricevuto un errore del linker che mi ha fatto capire che la mia missione di migrare a XCTest era fallita.La ragione:XCTest non fa parte dell'SDK 6.1, ma sto ancora costruendo il mio progetto con l'SDK iOS 6.1 di base (questa risposta SO spiega come integrare SDK 6.1 in Xcode 5).

Dato che non riesco a continuare con la migrazione, la mia soluzione per il momento è quindi mantenere i miei unit test basati su SenTestingKit/OCUnit, finché non trovo il tempo di aggiornare la mia app a iOS 7.Questo è quello che dovevo fare per eseguire i test unitari:

  1. Rimuovere la fase di compilazione "Esegui script" dalla destinazione dello unit test.Questo è tutto ciò che serve per consentire a Xcode di eseguire unit test tramite l'azione "Test" ( + U) mentre è selezionata la destinazione del test unitario.
  2. Questo non è l'ideale, però, perché non voglio cambiare target solo per eseguire test unitari.Voglio invece eseguire test unitari mentre è selezionato il target principale.Il secondo passaggio quindi è modificare lo schema Xcode del target principale in modo che quando eseguo l'azione "Test", vengano invece eseguiti i test del target del test unitario.

La soluzione finale non è buona come in Xcode 4.x dove gli unit test venivano eseguiti automaticamente ogni volta che eseguivo l'azione "Esegui" o "Costruisci" del target principale.Sfortunatamente, sembra che non riesca a farlo funzionare senza una fase di compilazione "Esegui script".

Altri suggerimenti

Edit -> Refactor -> Converti in XCTEST

I test OCUnit funzionerà ancora, ma potrebbe anche migrare.Le modifiche finiscono per essere piuttosto minime.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top