Laden...

Wie kann ich sicherstellern, dass ein UnitTest keine StackOverflowException hat?

Erstellt von Palladin007 vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.266 Views
Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 3 Jahren
Wie kann ich sicherstellern, dass ein UnitTest keine StackOverflowException hat?

Hi,

ich schreibe gerade ein paar UnitTests und dabei ist mir eine Möglichkeit aufgefallen, die (vor dem Fix) zu einer StackOverflowException führen konnte.
Ich arbeite mit MSTest.

Mir ist bewusst, dass ich keine StackOverflowException fangen kann und auch Negativ-Tests nicht möglich sind.
Aber ist es möglich, ein Test zu schreiben, der nur erfolgreich ist, wenn er bis zum Ende durchgelaufen ist?

Mein Versuch:

[TestMethod, ExpectedException(typeof(Exception), "NoStackOverflow")]
public void MyTest()
{
    DoWithStackOverflowException();
    throw new Exception("NoStackOverflow");
}
private void DoWithStackOverflowException()
{
    DoWithStackOverflowException();
}

Leider wird der Test-Status nie aktualisiert, im schlimmsten Fall sieht es also aus, als wäre er erfolgreich gewesen.
Hat jemand eine Idee, wie ich das Problem lösen kann?
Geht das vielleicht mit einem anderen Test-Framework?

T
2.219 Beiträge seit 2008
vor 3 Jahren

Das Problem scheint wohl bekannt zu sein.
Hab hier ein GitHub Issue dazu gefunden.

GitHub

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 3 Jahren

Ich hab's befürchtet ...

Meine Hoffnung war, dass z.B. ein anderes Test-Framework dafür einen eigenen Prozess startet und den überwacht.
Das wäre ja machbar - der Prozess bricht bei einer StackOverflowException zwar ab, aber der Prozess, der ihn gestartet hat, läuft weiter und kann reagieren.

Für mein kleines Projekt ist das nämlich ein kritischer Pfad, eine der wichtigsten Methoden schreit nach einer StackOverflowException, da will ich diesen Fall möglichst gut ausschließen können. 😕

T
2.219 Beiträge seit 2008
vor 3 Jahren

Kannst du ja mit deinem Beispiel Code und entsprechenden Frameworks testen.
Ist mit einem Test Projekt vermutlich ein kleiner Aufwand.

Leider konnte ich keine Information finden, ob das Problem in VS in einem Update behoben wurde.
Bisher sehe ich in der aktuellen VS 2019 Version immer noch den alten Status.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 3 Jahren

Hm - meine kleinen Tests haben ergeben: Nein

Gibt's einen Weg, dass ich den ehemaligen Test-Status vor jedem Durchlauf im Test selber ändern kann?

In dem Fall könnte jeder Test vor dem Durchlauf einmal den Status auf Failed setzen und im Falle einer StackOverflowException bleibt das dann so.

T
2.219 Beiträge seit 2008
vor 3 Jahren

Auf die schnelle nichts brauchbares gefunden.
Es gibt zwar die Möglichkeit über TestContext Informationen während des Laufs der Test Methode zu erhalten.
Leider kann man diese nur lesen und die Klasse selbst ist abstrakt, weshalb man diese auch nicht instanzieren kann.
Ich vermute mal, dass dieser Ansatz nicht direkt funktioniert.
Man könnte aber schauen ob man die alten Ergebnisse löschen kann z.B. im TestInitialize und dann prüft könnte das Ergebnis zurück gesetzt sein.
Oder du müsstest per Skript den Test triggern, vorher aber die Results löschen.
Ob das funktioniert ist aber nicht sicher.

TestContext

Nachtrag:
Scheinbar speichert VS den Status der Tests gesondert im Projekt.
Den Status im Test Explorer kann ich aktuell nur per Projekt bereinigen für alle Tests zurücksetzen.
Wäre zwar umständlich aber eine manuelle Lösung.

Ich schau mal was ich dazu finden kann bzw. wo die Ergebnisse gespeichert werden.
Die Result Ordner sind es nicht.

Nachtrag 2:
Ebenfalls müsstest du mal schauen ob du Zugriff auf die Ausgabe von VS bekommen kannst.
Dort gibt es in dem Fall dann folgende Nachricht.

---------- Testlauf wird gestartet ----------
Der aktive Testlauf wurde abgebrochen. Grund: Der Testhostprozess ist abgestürzt. : Stack overflow.

Wenn du den Fall abschnorcheln könntest, könntest du ggf. was machen.
Ob das klappt bezweifle ich leider jetzt schon 😦

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.807 Beiträge seit 2008
vor 3 Jahren

Das Problem nennt sich Halting problem
Wer es löst wird vermutlich stink reich.

Aber nein; derzeit gibt es keine Möglichkeit diese Exception in einem Test abzufangen.

Meine Hoffnung war, dass z.B. ein anderes Test-Framework dafür einen eigenen Prozess startet und den überwacht.

  • NUnit erstellt eine Instanz pro Test-Klasse
  • XUnit erstellt eine Instanz pro Test-Methode
  • MSTest hat eine (manuelle) Parallelisierung auf Test-Ebene (Worker und Scopes)

Im CI/CD mit Test Discovery müsste ein Fehler auftauchen, wenn ein Test gefunden aber kein positives Signal erhalten wird.
Also der Test müsste als "Not run" erkenntbar sein.