Wie wird das Ziel der Arbeitslogikeinheit im Xcode 4.5-Projekt "Command Line Tool" eingerichtet?

8

Probleme beim Abrufen von Komponententests für ein bestimmtes Szenario. Hier ist was ich versuche:

  • In Xcode 4.5 habe ich ein einfaches OSX "Command Line Tool" Anwendungsprojekt (Foundation) erstellt.
    Beachten Sie, dass Xcode nicht die Option bietet, automatisch Unit-Tests zu einem "Command Line Tool" -Projekt hinzuzufügen - also schlagen Sie nicht vor, das Häkchen zu setzen; es ist nicht da: - /

  • In meinem Projekt habe ich eine triviale Beispielklasse erstellt, die ich testen möchte; z.B. "Form".

  • Ich habe die Anweisungen in Apples Xcode Unit Testing Guide für Einrichten von Unit-Testing in einem Projekt :

    • Ich habe meinem Projekt ein Einheitentestziel hinzugefügt und

    • Ich habe das Schema "Test" bearbeitet, um die Tests im neuen Ziel auszuführen.

  • In der Implementierung (.m) des Testprojekts habe ich einen Import für Shape.h und einen Code in der setUp() -Methode hinzugefügt, um eine Form zu instanziieren und sie einer Instanzvariablen zuzuweisen.

An diesem Punkt beschloss ich zu sehen, ob sich etwas aufbauen würde und ob der Standardtest noch laufen würde. Wenn ich jedoch Produkt ... Test aus dem Menü ausgewählt habe, ist der Build mit dem folgenden Fehler fehlgeschlagen:

%Vor%

Die Interpretation dieses Fehlers ist nicht das Problem. Ich denke, dass das Einheitentest-Ziel nicht mit der Binärdatei verknüpft ist, die die Implementierung von Shape enthält. Wie auch immer, ich grabe Xcode Unit Testing & amp; Zielkonfiguration Also:

Was muss ich tun, um die Testzielverknüpfung mit der resultierenden Ausgabe des Befehlszeilentools zu erhalten? Kann ich eine Verknüpfung zu einer ausführbaren Befehlszeile aus dem Einheitentestziel herstellen? Die Dokumentation von Apple sieht speziell für reguläre OSX-Anwendungen ( *.app ) und iOS-Anwendungen aus, und dies ist auch nicht der Fall.

Ich habe Business-Logik-Klassen, die ich gerne in einer Befehlszeilen-Tool-Einstellung entwickeln möchte (zu Beginn), also würde ich gerne verstehen, was ich tun muss, um ein Unit-Test-Target in einer " Befehlszeilen-Tool "Art des Projekts. Danke!

(ps Beachten Sie, dass ich nicht daran interessiert bin, meine Unit-Tests von über die Befehlszeile auszuführen - Stack Overflow hat bereits "ähnliche" Fragen dazu gestellt - Stattdessen führt Unit-Tests auf ein "Command Line Tool" aus Projekt und noch immer aus Xcode heraus.

    
Chris W. Rea 02.11.2012, 15:18
quelle

3 Antworten

13

Ich habe einen Workaround gefunden, den ich als geeignet empfinde und der außer einem hinzugefügten Ziel anscheinend keine wesentlichen Nachteile hat.

Kurz gesagt: Die Lösung beinhaltet das Hinzufügen eines statischen Bibliotheksziels , um die Vorteile von Xcode beim Erstellen von & amp; Führen Sie Unit-Test-Code um ein solches Ziel herum. Das Befehlszeilentool-Ziel wird dann an die statische Bibliothek delegiert, wo eine alternative Funktion main() -like definiert und vom tatsächlichen Einstiegspunkt main() aufgerufen wird. Das Befehlszeilentool wird frei von nicht-trivialem Code gehalten, so dass das Einheitentestziel auf alles zugreifen kann, was getestet werden muss.

Hier sind die Schritte:

  • Wählen Sie aus einem leeren Xcode im Menü Datei ... Neues Projekt .

  • Wählen Sie im resultierenden Dialogfeld OS X ... Anwendung ... Befehlszeilentool . Für dieses Beispiel nehme ich an, dass es SampleCmd heißt.

Nachdem das grundlegende Befehlszeilenwerkzeugprojekt erstellt wurde:

  • Wählen Sie im Menü Datei ... Neu ... Ziel .

  • Wählen Sie im resultierenden Dialogfeld OS X ... Framework & amp; Bibliothek ... Kakao-Bibliothek . Für dieses Beispiel nehme ich an, dass es SampleCmdLogic heißt.

  • Wählen Sie den Typ Static , damit das Befehlszeilentool eine eigenständige ausführbare Datei bleibt.

  • Stellen Sie sicher, dass das Kontrollkästchen Unit-Tests einschließen aktiviert ist.

Nachdem das statische Bibliotheksprojekt erstellt wurde:

  • Kopieren Sie die Funktion main() von main.m nach SampleCmdLogic.m und ersetzen Sie den Block @implementation . (Diese Datei enthält nur den Haupteingangspunkt. Andere Dateien können für Objective-C-Klassen usw. hinzugefügt werden.) Umbenennen Sie die Funktion in libMain() .

  • Fügen Sie in SampleCmdLogic.h eine Deklaration für den neuen libMain() hinzu und ersetzen Sie dabei den Block @interface :
    int libMain(int argc, const char * argv[]);

  • Fügen Sie im% code% des Befehlszeilentools oben ein main.m hinzu.

  • Ändern Sie in% ce_de% des Befehlszeilentools den gesamten Inhalt der realen Funktion #import "SampleCmdLogic.h" in:
    main.m

Der Code ist jetzt bereit, aber es sind Verknüpfungsschritte erforderlich:

  • Erweitern Sie in den Projekteinstellungen für main() unter Build-Phasen Zielabhängigkeiten und fügen Sie (+) SampleCmdLogic als Abhängigkeit hinzu.

  • Erweitern Sie in den Projekteinstellungen für return libMain(argc, argv); unter Build-Phasen Binär mit Bibliotheken verknüpfen und fügen Sie (+) SampleCmd

    hinzu

Alles ist jetzt fertig. Wenn Sie zum SampleCmd-Ziel wechseln und Product..Run aus dem Menü wählen, sollte der Build erfolgreich sein und wie erwartet ausgegeben werden. Wenn Sie zum SampleCmdLogic-Ziel wechseln und Product ... Test aus dem Menü auswählen, sollte der Build erfolgreich sein und die Komponententests werden ausgeführt. Das einzelne Problem, das gemeldet wird, ist die ursprüngliche standardmäßige fehlgeschlagene Unit-Test-Assertion, die von Xcode in SampleCmd eingefügt wurde. Dies wird erwartet.

Von diesem Punkt an fügen Sie alle Logik- und entsprechenden Tests zum SampleCmdLogic-Ziel hinzu. Das SampleCmd-Ziel soll trivial bleiben und nur den Einstiegspunkt des Befehlszeilentools bereitstellen.

    
Chris W. Rea 12.11.2012, 15:36
quelle
3

Normalerweise gibt es eine Reihe zusätzlicher Schritte, um ein Testziel zu einem App-Projekt hinzuzufügen - insbesondere die Einstellung von Bundle Loader und Test-Host, wie ich es in Ссылка .

Aber als ich sie mit einem Befehlszeilentool ausführte und versuchte, Tests auszuführen, wurde das Tool nur ausgeführt. Bei einer App wird die App gestartet, das Testpaket wird in die laufende App eingefügt und anschließend werden die Tests ausgeführt. Diese Phasen gelten jedoch nicht für die Befehlszeilentools.

Sie benötigen also anstelle eines injizierten Testpakets ein zweites Befehlszeilentool, das Ihre Tests ausführt. Stellen Sie dann Ihre Klassen so ein, dass sie sowohl auf das Testtool als auch auf Ihr tatsächliches Tool abzielen. gh-unit und google-toolbox-for-mac folgen beide diesem Modell, also würde ich sie ausprobieren.

    
Jon Reid 02.11.2012 17:23
quelle
1

Das unmittelbarste Problem scheint einfach darin zu bestehen, dass Shape nicht im neuen Testziel enthalten ist. Fügen Sie Shape.m zum Testziel hinzu:

  1. Klicken Sie im Projektnavigator
  2. auf Shape.m
  3. Öffnen Sie die Ansicht Dienstprogramme (Ansicht -> Dienstprogramme -> Dienstprogramme anzeigen)
  4. Stellen Sie im Abschnitt Zielmitgliedschaft der Ansicht Dienstprogramme sicher, dass sowohl Ihre app als auch Ihre Testziele überprüft werden.

Ich weiß nicht, ob das das Ende Ihrer Probleme mit Ihrem Setup ist, aber es scheint ein wahrscheinlicher Kandidat für Ihr unmittelbarstes Problem zu sein.

    
KevinH 12.11.2012 07:14
quelle