2010-01-18 7 views
8

Wir verwenden NUnit & VisualStudio, um C# .NET-Code für eine Weile zu schreiben. Testing Ausnahmen wurden im Stil vonExceptionAsserts & Debuggen Ihres C# -Projekts in VS

alter Syntax getan:

[Test] 
[ExpectException(typeof(ExceptionType))] 
public void TestExceptionType() 
{ 

} 

Jetzt NUnit hat 2.5.2 freigegeben Version, die Assert.Throws(Type expectedExceptionType, TestDelegate code); eingeführt Dies macht Ausnahme testet eine ganze Menge mehr flexibel. Unsere Ausnahme-Tests sehen nun wie folgt aus:

neue Syntax:

[Test] 
public void TestWithNullBufferArgument() 
{ 
    ArgumentNullException ex = Assert.Throws<ArgumentNullException>(() => _testInstance.TestFunction(null)); 

    // now you can examine the exception and it's properties 
    Assert.AreEqual(ex.Message, "Argument was null"); 
} 

Unser Problem ist, dass, wenn Assert.Throws Visual Studio ein Fenster husten verwendet wird, wird eine nicht behandelte Ausnahme zeigt, wenn NUnit (entweder Konsole oder GUI-Runner) wird verwendet, um das Programm zu debuggen.

, um dies zu klären: Wir haben das VS-Projekt festgelegt, das die Komponententests zum Ausführen von nunit-x86.exe beim Debuggen enthält. (Siehe Projekteigenschaften, Registerkarte Debugging, Startaktion ist so eingestellt, dass sie nunit-x86.exe ausführt)

Dies hält NUnit davon ab, die Tests fortzusetzen. Es ist möglich, das Debugging/Unit-Testing durch Drücken von F5 fortzusetzen, aber dies ist keine praktikable Lösung.

Gibt es eine Möglichkeit, dies zu vermeiden? Probieren Sie es aus ... catch Block um die Assert.Throws tut nichts, da die Ausnahme im Delegate-Code passiert.

Ich hoffe, dass jemand etwas Licht darauf werfen kann.

+0

Das Testbeispiel, das Sie anzeigen, entspricht nicht der von Ihnen angezeigten Syntax. Was meinst du auch, wenn NUnit ... verwendet wird, um das Programm zu debuggen? Meinen Sie, dass Sie nur Tests ausführen, oder führen Sie Tests im Debugger aus (ich weiß, dass TestDriven.NET das kann; wissen Sie nichts über die NUnit-Runner)? – Jay

+0

Hallo Jay! Entschuldigung für die Verwirrung. Es gibt zwei verschiedene Syntaxtypen: neu und alt. Wir haben von alter Syntax auf neue Syntax umgestellt und verwenden jetzt die Bedingung Assert.Throws <>. Wir führen Tests in den Debuggern durch, es hat bisher gut funktioniert und es ist sehr einfach zu sehen, was schief läuft, da VS direkt zu dem Punkt springt, an dem eine Ausnahme verursacht wird. Mit der neuen Syntax erhalten wir alle Ausnahmetests als "falsch positive", wobei bei der alten Syntax nur echte Ausnahmen die Ausführung unterbrechen würden. –

Antwort

7

Das Problem selbst erscheint, weil Sie wahrscheinlich die Option Nur aktivierten Code einschalten aktiviert haben (Extras-> Optionen-> Debugging-> Allgemein-> Nur Code aktivieren).

„Wenn diese Funktion aktiviert ist, zeigt der Debugger und Schritte in Benutzercode“ nur, ignorieren Systemcode und anderen Code, der optimiert ist oder nicht über Debug-Symbole („My-Code)“ (siehe „General, Debugging, Options Dialog Box“)

Normalerweise haben Sie eine Release-Version von nunit.framework.dll, die keine entsprechende Datei nunit.framework.pdb hat.

So gibt es 2 Möglichkeiten:

  1. Disable "Just My-Code" -Funktion

  2. Download-Quellen von nunit (von http://www.nunit.org/index.php?p=download), bauen sie im Debug-Modus, alle NUnit.Framework setzen. * (dll, pdb, xml) in lib oder ein anderes Verzeichnis in Ihrer Lösung und verweisen Sie auf die Datei nunit.framework.dll in Ihrem Testprojekt.

Hoffe, das hilft.

+0

Dh, das ist ein interessanter Gedankengang. Ich habe Option 1 ausprobiert (nur weil es schnell ist und ich noch keine Zeit hatte, Nummer 2 auszuprobieren) und leider hat es für mich keinen Unterschied gemacht. Wenn überhaupt, bekomme ich jetzt mehr unbehandelte Ausnahmen. Das Problem mit Assert.Throws <>, das eine nicht behandelte Ausnahme verursacht, ist immer noch vorhanden. –

+0

Ich weiß es nicht. Das klingt wie mein Setup, außer dass ich nunit-gui.exe anrufe –

+0

Ich habe das für Nunit-GUI mit den gleichen Ergebnissen wie für Nunit-Konsole versucht. Immer noch gibt es eine Option mit Debugging-Symbolen, hoffe, dass das für Sie arbeiten wird. –

-1

Konnte es erreichbar sein, indem Sie die Ausnahme deaktivieren. Öffnen Sie das Debug/Exceptions-Menü und suchen Sie nach Ihrer Exception.

+0

Das funktioniert, aber es bedeutet auch, dass keine Ausnahmen abgefangen werden, wenn das echte Programm und nicht die Komponententests debuggen. Idealerweise würden wir nach einem Weg suchen, wie wir es beim Debuggen der Komponententests einfach vermeiden können. Danke für den Hinweis, das könnte eine akzeptable Lösung sein, wenn nichts anderes auftaucht. –

+0

Was ist, wenn Sie zwei Komponententests schreiben? man sicherstellen, dass die Ausnahme ausgelöst wird, die zweite wird die Ausführung tun? –

+0

Ich dachte auch darüber nach.Leider funktioniert es nicht, da die Ausnahme vom Code im Delegaten ausgelöst wird und Assert.Throws <> erwartet, dass die Ausnahme ausgelöst wird. –

1

Ich denke, dass Sie durch die NUnit Behauptung geblendet werden. Sie könnten dasselbe mit einem einfachen Versuch/Fang erreichen.

try 
{ 
    _testInstance.TestFunction(null); 
    Assert.Fail("The method should have thrown..."); 
}catch{} 

Jetzt haben Sie alles, was Sie brauchen. Sie schlagen fehl, wenn die Ausnahme nicht ausgelöst wird und Ihr regulärer Code Ausnahmen wie erwartet verarbeiten kann.

+0

Sie haben Recht, dies wäre ein grundlegender Weg, um Ausnahmen im Komponententest zu behandeln. Das Schöne an der NUnit-Ausnahme-Assertion ist, dass Sie bestimmte Eigenschaften der ausgelösten Ausnahme testen können. Zum Beispiel können Sie testen, ob der Parameter, der an die Ausnahme übergeben wurde, korrekt war. Ich mag und benutze das und ich möchte es behalten. –

+0

Wäre es nicht möglich, die Parameter der Ausnahme auf diese Weise zu testen? Anstatt {} zu fangen, können Sie catch sagen (Ausnahme ex) {Assert.IsTrue (ex.Whatever); } – Phil

+0

Ja, das stimmt tatsächlich. Schön und einfach, ich mag es! Meine ursprüngliche Frage war jedoch die Frage, die die Assert.Throws <> Methode verursachte, deshalb gab ich das Kopfgeld jemandem, der das unmittelbare Problem löste. –

2

ärgerte Das gleiche Problem mir auch schon seit geraumer Zeit, ich ein paar Tests gemacht und fanden die folgende: mit Debug-Informationen auf ‚none‘

Wenn eine Bibliothek (nunit in diesem Fall), dann kompiliert Wenn das Konstrukt, das dem folgenden ähnelt, mit der Bibliothek ausgeführt wird und der Code des Delegierten eine Ausnahme auslöst, hört VS auf, sich über die Ausnahme zu beschweren, die nicht vom Benutzercode behandelt wird.

Bibliothek Code:

public static Exception Throws(TestDelegate code, string message) 
{ 
    Exception caughtException = null; 

    try 
    { 
     code(); 
    } 
    catch (Exception ex) 
    { 
     caughtException = ex; 
    }   

    return caughtException; 
} 

Client-Code:

private void btnTest_Click(object sender, EventArgs e) 
{ 
    var ex = MyAssert.Throws(() => { throw new Exception(); }, "");  
} 

Einstellung Debug-Informationen eines Bibliotheksprojekt jede andere Option außer 'none' löst das Problem also Debugger nicht mehr auf nicht stoppen diese ein bisschen "unbehandelten" Ausnahmen. Ich testete es mit Nunit und meiner eigenen handgerollten Bibliothek mit dem obigen Code (nahm einen Ausschnitt aus der Methode von Nunits Wirrwarr). Ich nehme an, es ist ein Feature oder ein "Feature" von VS.

Es lässt uns nicht so viele Möglichkeiten:

  1. Filter Ausnahme wie zuvor vorgeschlagen,

  2. Recompile nunit.framework.dll für den lokalen Gebrauch, die lästigen Anschläge

zu vermeiden

Andere Optionen könnten sein, entweder MS- oder NUnit-Teams oder beide zu kontaktieren und sie zu bitten, das Problem zu untersuchen/zu klären und NUnit mit minimalen Debug-Informationen zu kompilieren respectively.

Bearbeiten:

Eine weitere Option gefunden.

  1. In meinem Fall macht das Deaktivieren der Option "JIT-Optimierung beim Laden von Modulen unterdrücken" auch dann Sinn, wenn Bibliotheken ohne Debug-Informationen kompiliert wurden. Dies funktioniert jedoch nur, wenn das Projekt in der Release-Konfiguration ausgeführt wird.
+0

dyadenka, vielen Dank für das detaillierte Feedback! Unglücklicherweise hat Dh den gleichen Vorschlag (redefiniere nunit framework in der debug-Konfiguration) vor einiger Zeit, also bekommt er das Bounty. Ich habe in der Nunit Mailingliste über dieses Problem geschrieben, also werden wir es tun, wenn sie eine bessere Lösung finden. –

+0

Keine Sorge, Kopfgeld war kein Ziel, primäres Ziel war es, das Problem dieser nervigen Stops in VS zu lösen. – Dyadenka