Cryptic NSInternalInconsistencyException beim Ausführen von Komponententests in Xcode 9 GM

8

Ich führe die Unit-Tests meiner iOS-App auf Xcode 9 GM aus, und einige von ihnen scheitern mit einer seltsamen NSInternalInconsistencyException. Sie beschweren sich, dass einige Testaussagen nicht gemeldet werden können, weil die betroffenen Tests kein XCTestRun-Objekt haben. Ich benutze OCMockito + OCHamcrest für Mocking und Anrufverifizierung.

Zu Demonstrationszwecken sagen wir, meine App heißt MyTestApp und ich habe eine Testklasse FooTest (die von XCTestCase erbt). In -setUp erstelle ich die verschiedenen Mock-Objekte für die Tests und verbinde sie miteinander, und in -tearDown setze ich sie für alle Fälle auf Null.

Hier ist ein Beispiel für die Ausnahme, die ich bekomme:

%Vor%

Einige bemerkenswerte Dinge:

  • Die Komponententests initialisieren XCTestCase- oder XCTest- "Infrastruktur" -Klassen nicht außerhalb des XCTest-Frameworks.
  • Die restlichen Anweisungen der betroffenen Komponententests werden tatsächlich ausgeführt, bis zu dem Punkt der Ausnahme.
  • Die betroffene Codezeile sieht folgendermaßen aus: [verify(_mockTestObject) description];
  • Der Stack-Trace liegt dort, wo das Problem auftritt - er sagt, dass es in setup ist, aber von dem, was ich sagen kann, meldet OCMockito einfach zu Beginn des nächsten Unit-Test-Tests Erwartungsfehler . Der Problemort (FooTest.mm:135) sieht wie der obige Aufruf verify () aus.

Tatsächlich schlagen alle Komponententests fehl, die mit dieser Ausnahme fehlschlagen, weil wir versuchen zu überprüfen, ob -[NSObject description] für ein oder mehrere Mock-Objekte aufgerufen wurde. Durch das Entfernen aller Instanzen, die diesen Aufruf verifizieren, werden die Tests bestanden.

Ich habe bei Google nach anderen Instanzen dieser bestimmten NSInternalInconsistencyException gesucht, und das hat zu keinen Ergebnissen geführt. Ich bin mir nicht sicher, auf welche Weise - [NSObject description] unterscheidet sich von jeder anderen Methode, die für ein Mock-Objekt aufgerufen werden kann - es ist möglich, dass das Problem auch nicht wirklich da ist, sondern dass es sich nur so manifestiert. Ich habe auch versucht zu finden, ob es irgendwelche Debug / Diagnose-Optionen gibt, die ich für XCTest aktivieren kann, damit ich vielleicht ausführlichere Protokollierungsinformationen über die Testausführung erhalten kann, aber ich habe auch nichts dergleichen gefunden.

Irgendwelche Ideen, wo ich als nächstes hinschauen sollte? Vielen Dank!

    
RuslanD 19.09.2017, 20:50
quelle

1 Antwort

1

Ich hatte ein ähnliches Problem, als ich an einer großen Suite von Legacy-Code-Tests arbeitete. Die Frage ist: Funktionieren Ihre Tests mit XCTExpectation gut, wenn Sie sie separat ausführen? Wenn dies der Fall ist, bedeutet dies, dass einige der Tests, die vor Tests mit NSInternalInconsistencyException ausgeführt werden, XCTest verwandte Methoden so versenden, dass sie nach dem Ende des relevanten Tests ausgeführt werden.

sieht so aus (Beispiel):

Test1 - & gt; Versendet asynchron "Block", der XCTFail

ausführt

Test1 - & gt; endet

XCTFail wird ausgeführt (aber Test1 wird übergeben, da es ohne "fail" beendet wurde) auf dem Haupt- oder dem anderen Thread.

Test2 - & gt; testet etwas mit XCTExpectation - & gt; NSInternalInconsistencyException

Apple-Dokumente liefern nicht viele Informationen über die internen Eingeweide von XCTest, aber ich bin mir ziemlich sicher, dass dies das Problem ist. Versuchen Sie, die Fehlerbehebungsschritte zu befolgen, um Tests, die "widersprüchlich" sind (die schlechten, die asynchrone Sachen ohne XCTestExpectation ausführen, wie Methoden mit Abschlussbehandlern, die XCTest -Assitionen machen, fehlschlägt usw.) zu fixieren:

  1. Binäre Suche in Ihrer Suite: Deaktivieren Sie die Hälfte der Tests und führen Sie die Suite mit Ihrem FooTest .
  2. aus
  3. Wenn Ihre Testsuite ordnungsgemäß ausgeführt wird, aktivieren Sie die Hälfte der deaktivierten Tests erneut. Wenn Testsuite mit Ausnahme ausgeführt wird, wurden alle deaktivierten Tests erneut aktiviert und die andere Hälfte deaktiviert.
  4. Wiederholen Sie Schritt 1, dann in Bezug auf eine kleinere Anzahl von Tests.
  5. Schließlich werden Sie mit Tests enden, die diese Ausnahme verursachen.

In meinem Fall gab es mehrere Tests, die diesen Konflikt mit XCTestExpectation verursachten, daher war die Suche ziemlich nervtötend (mehrere Stunden für eine Suite von 1000+ XCTestCases , also etwa 5k Tests).

Untersuchen Sie dann gründlich, was im Test passiert, der mit Ihrem Test in Konflikt steht.

    
Wladek Surala 27.11.2017 11:05
quelle

Tags und Links