Frage Wie migriere ich von SenTestingKit / OCUnit nach XCTest?


Ich bin dabei, mein Projekt von Xcode 4.6.3 nach Xcode 5.0.2 zu migrieren. Die Unit-Tests des Projekts wurden mit SenTestingKit / OCUnit entwickelt. Wenn ich jetzt die Tests in Xcode 5 starte, bekomme ich einen Fehler von der RunUnitTests Skript, das mir das sagt

RunUnitTests ist veraltet.

Möglicherweise verwandt ist dieser Hinweis in den Xcode 5 Release Notes:

SenTestingKit und OCUnit sind veraltet. Verwenden Sie den Migrator, um zu XCTest zu wechseln.

Leider habe ich nicht mehr über diesen mysteriösen "Migrator" erfahren können. Möglicherweise fehlt mir mein google-fu [wieder], also lautet meine Hauptfrage: Wie migriere ich Komponententests von SenTestingKit / OCUnit auf den neuen XCTest (mit oder ohne den "Migrator")?

Eine sekundäre Frage, falls die Migration ein kompliziertes Geschäft ist: Ist es möglich, Xcode 5 dazu zu bringen, Komponententests auszuführen, die immer noch auf SenTestingKit / OCUnit basieren? Nachdem all dies nur veraltet ist, sollten sie immer noch funktionsfähig sein.


34
2017-11-16 19:06


Ursprung


Antworten:


Dank der Antwort von Shaggy Frog wissen wir, dass der mysteriöse "Migrator", der in den Xcode-Versionshinweisen erwähnt wird, ein Assistent ist, der durch Auswahl von "Bearbeiten> Refaktor> In XCTest konvertieren" gestartet wird. Ich werde über meine Erfahrung mit diesem Assistenten in zwei Teilen schreiben. Der erste Teil ist eine unvollständige Antwort auf die primäre Frage, der zweite Teil beantwortet die sekundäre Frage.


Teil 1: Wie man von OCUnit zu XCTest migriert

Das erste, was Sie wissen müssen, ist, dass der Assistent arbeiten muss Wählen Sie ein Einheitentestziel aus. Wenn Sie das Hauptziel ausgewählt haben, listet der Assistent einfach keine zu konvertierenden Ziele auf.

Als ich das herausfand, war ich in der Lage, durch den Zauberer zu treten, aber in meinem Fall war das Endergebnis immer noch ein spektakulärer Fehlschlag! Der Assistent gab an, dass keine Quellenänderungen erforderlich sind und dass nur Buildeinstellungen aktualisiert werden müssen, um nach XCTest zu migrieren. Am Ende hat der Zauberer das nicht mal richtig gemacht: Es hat getan entfernen Sie den Verweis auf das SenTestingKit-Framework, aber es tat nicht Verweisen Sie auf den XCTest-Rahmen.

Wie auch immer, was folgt, ist eine Liste der Änderungen, die ich manuell vornehmen musste, weil der Assistent sie nicht für mich erstellt hat. Wenn der Assistent für Sie besser funktioniert, müssen Sie möglicherweise nicht alle diese Schritte ausführen.

  1. Entfernen Sie die Build-Phase "Run Script" vom Einheitentestziel
  2. Ändern Sie die Basisklasse aller Testfall-Klassen von SenTestCase zu XCTestCase
  3. Ändern Sie den importierten Header von <SenTestingKit/SenTestingKit.h> zu <XCTest/XCTest.h>
  4. Ändern Sie in den Build Settings des Testziels Wrapper Extension von octest zu xctest.
  5. Benenne alle Asser-Makros um ST* zu XCT* (z.B. STAssertTrue wird XCTAssertTrue)
  6. Ausnahme zu den oben genannten: STAssertEquals muss in umbenannt werden XCTAssertEqual (Beachten Sie das fehlende "s" am Ende). Sie werden wissen, dass Sie dies vergessen haben, wenn Sie diese Compiler-Warnung erhalten: warning: implicit declaration of function 'XCTAssertEquals' is invalid in C99
  7. Die neuen XCTest-Assert-Makros erlauben dies nicht nil als Fehlerbeschreibung übergeben werden. Zum Beispiel, XCTAssertNotNil(anObject, nil)ist nicht möglich und muss geändert werden XCTAssertNotNil(anObject). Sie werden wissen, dass Sie dieses Problem haben, wenn Sie diesen Compilerfehler erhalten: error: called object type 'NSString *' is not a function or function pointer.
  8. Wenn du machen Wenn Sie eine Fehlerbeschreibung übergeben müssen, benötigen die neuen XCTest - Assert - Makros einen konstanten Ausdruck für den Formatspezifizierer, genau wie der NSString Klassenmethode stringWithFormat: tut. Sie werden wissen, dass Sie dieses Problem haben, wenn Sie diesen Compilerfehler erhalten: error: expected ')'. Einige Beispiele:
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);

Zu guter Letzt muss, wie bereits weiter oben erwähnt, der Verweis auf das XCTest-Framework zum Einheitentestziel hinzugefügt werden. Sie werden wissen, dass Sie dies vergessen haben, wenn Sie Linker - Fehler wie Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo.

Xcode 6 Aktualisierung: Die Verknüpfung mit XCTest ist in Xcode 6 nicht mehr erforderlich (XCTest ist sogar nicht mehr als verfügbares Framework gelistet). Setzen Sie stattdessen die Build-Einstellung CLANG_ENABLE_MODULES auf YES (in der Benutzeroberfläche als "Module aktivieren (C und Objective-C)" verfügbar). Dies wird verursachen clang automatisch mit XCTest verbinden, wenn es ein sieht #import <XCTest/XCTest.h> Erklärung. Details sind verfügbar in der Abschnitt "Module" der Clang-Dokumentation.


Teil 2: Wie man OCUnit Tests in Xcode 5 ausführt

An diesem Punkt bekam ich einen Linker-Fehler, der mir klar machte, dass meine Mission, zum XCTest zu migrieren, fehlgeschlagen war. Der Grund: XCTest ist nicht Teil von SDK 6.1, aber ich baue immer noch mein Projekt mit dem Basis SDK iOS 6.1 (diese SO Antwort erklärt, wie man SDK 6.1 in Xcode integriert 5).

Da ich mit der Migration nicht fortfahren kann, besteht meine Lösung im Moment darin, meine Komponententests auf SenTestingKit / OCUnit zu basieren, bis ich die Zeit finde, meine App auf iOS 7 zu aktualisieren. Das war es, was ich tun musste um die Komponententests auszuführen:

  1. Entfernen Sie die Build-Phase "Run Script" vom Einheitentestziel. Dies ist alles, was erforderlich ist, damit Xcode Unit-Tests über die Aktion "Test" ausführen kann ( + U) während das Einheitentestziel ausgewählt ist.
  2. Dies ist jedoch nicht ideal, da ich die Ziele nicht einfach nur zum Ausführen von Komponententests wechseln möchte. Stattdessen möchte ich Komponententests durchführen während das Hauptziel ausgewählt ist. Der zweite Schritt besteht daher darin, das Xcode-Schema des Hauptziels so zu ändern, dass bei Ausführung der Aktion "Test" stattdessen die Tests des Einheitentestziels ausgeführt werden.

Die endgültige Lösung ist nicht so gut wie in Xcode 4.x, wo die Komponententests jedes Mal automatisch ausgeführt wurden, wenn ich die Aktion "Ausführen" oder "Erstellen" des Hauptziels ausführte. Leider scheint es, dass ich das ohne eine "Run Script" -Buildphase nicht zum Laufen bringen kann.


57
2017-11-17 04:33



Bearbeiten -> Refaktor -> In XCTest konvertieren

OCUnit-Tests funktionieren weiterhin, aber Sie können auch migrieren. Die Änderungen sind minimal.


14
2017-11-16 19:09