Kann ich in einem Unit-Test in die Konsole schreiben? Wenn ja, warum öffnet sich das Konsolenfenster nicht?


148

Ich habe ein Testprojekt in Visual Studio. Ich verwende Microsoft.VisualStudio.TestTools.UnitTesting.

Ich füge diese Zeile in einem meiner Unit-Tests hinzu:

Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();

Wenn ich den Test ausführe, besteht der Test, aber das Konsolenfenster wird überhaupt nicht geöffnet.

Gibt es eine Möglichkeit, das Konsolenfenster für die Interaktion über einen Komponententest verfügbar zu machen?


1
Es kommt wirklich auf den Läufer an. Sie können TestDriven.Net verwenden (ein großartiger Testläufer für den persönlichen Gebrauch) - Console.WriteLine schreibt in den VS-Ausgabebereich.
Seldary

1
Vielen Dank für die Verbreitung der Nachricht auf TestDriven.Net
GrayFox374

NCrunch hat auch diese Funktion, die es allein den Preis IMO wert macht. Ich habe eine DumpErweiterungsmethode, die den Inhalt des Objekts in die Konsole ausgibt, was das Debuggen erheblich erleichtert. i.imgur.com/MEZwy7X.png
DharmaTurtle

Antworten:


125

HINWEIS: Die ursprüngliche Antwort unten sollte für jede Version von VS bis VS2012 funktionieren. VS2013 scheint kein Testergebnisfenster mehr zu haben. Wenn Sie eine testspezifische Ausgabe benötigen, können Sie stattdessen den Vorschlag von @ Stretch verwenden Trace.Write(), um die Ausgabe in das Ausgabefenster zu schreiben.


Die Console.WriteMethode schreibt nicht in die "Konsole", sondern in alles, was mit dem Standardausgabehandle für den laufenden Prozess verbunden ist. Console.ReadLiest in ähnlicher Weise Eingaben von allem, was mit der Standardeingabe verbunden ist.

Wenn Sie einen Komponententest über VS2010 ausführen, wird die Standardausgabe vom Testkabelbaum umgeleitet und als Teil der Testausgabe gespeichert. Sie können dies sehen, indem Sie mit der rechten Maustaste auf das Fenster Testergebnisse klicken und der Anzeige die Spalte "Ausgabe (StdOut)" hinzufügen. Dies zeigt alles, was in stdout geschrieben wurde.

Sie können ein Konsolenfenster manuell öffnen, indem Sie P / Invoke verwenden, wie @ sinni800 sagt. Nach dem Lesen der AllocConsoleDokumentation wird die Funktion zurückgesetzt stdinund stdoutbehandelt, um auf das neue Konsolenfenster zu verweisen. (Da bin ich mir nicht 100% sicher. Es scheint mir irgendwie falsch zu sein, wenn ich stdoutWindows bereits umgeleitet habe , um es mir zu stehlen, aber ich habe es nicht versucht.)

Im Allgemeinen halte ich es jedoch für eine schlechte Idee; Wenn Sie die Konsole nur verwenden möchten, um weitere Informationen zu Ihrem Komponententest zu speichern, ist die Ausgabe für Sie da. Verwenden Console.WriteLineSie weiterhin so, wie Sie sind, und überprüfen Sie die Ausgabeergebnisse im Fenster Testergebnisse, wenn dies erledigt ist.


Versuchen Sie, eine neue Windows-Anwendung zu öffnen, indem Sie mit AllocConsole eine Konsole zuweisen, die dort geschrieben wird. Ich weiß nicht, was es wirklich tut, aber es funktioniert möglicherweise nicht in einer Unit-Test-Umgebung. Es wäre wirklich schön zu wissen ...
sinni800

hrm. Beim erneuten Lesen der AllocConsoleDokumentation bin ich möglicherweise falsch, aber ich muss sie testen.
Michael Edenfield

2
Für mich sagte dieser Kommentar von Michael alles, worüber ich nachdenken musste: "Wenn Sie einen Komponententest über VS2010 ausführen, wird die Standardausgabe vom Testkabelbaum umgeleitet und als Teil der Testausgabe gespeichert."
Robert Patterson

5
Wenn Sie in VS2013 in die Konsole schreiben, wird im TestExplorer / Test / Summary eine Linkbezeichnung [Ausgabe] angezeigt. Klicken Sie darauf und Sie erhalten die gewünschte Ausgabe. Warten? Sie möchten auch Console.ReadLine () aufrufen?
Visar

3
Gehen Sie in V2017 (Community) zu "Test Explorer", wählen Sie das Testergebniselement in der Liste aus und klicken Sie im anderen Fenster (Testergebnisfenster?) Auf den Link "Ausgabe". Da es wahrscheinlich abgeschnitten wird, verwenden Sie "Alle kopieren" und an einer anderen Stelle vorbei.
Heringer

180

Jemand hat diese anscheinend neue Funktionalität in VS2013 kommentiert. Ich war mir zunächst nicht sicher, was er meinte, aber jetzt, wo ich es tue, denke ich, dass es eine eigene Antwort verdient.

Wir können Console.WriteLine normal verwenden und die Ausgabe wird angezeigt, nur nicht im Ausgabefenster, sondern in einem neuen Fenster, nachdem wir in den Testdetails auf "Ausgabe" geklickt haben.

Geben Sie hier die Bildbeschreibung ein


2
Hervorragende Lösung. Stellen Sie sicher, dass es in VS2015 Enterprise funktioniert.
Garfbradaz

6
Leider kann man in diesem Ausgabebereich keinen Text zum Kopieren und Einfügen auswählen :( Was dachten sie?!
ODER Mapper

3
@ORMapper, klicken Sie mit der rechten Maustaste auf den Bereich "Standardausgabe" und wählen Sie "Alle kopieren"
möglicherweise

2
@ Ovi-WanKenobi versuchen, etwas mit Console.Write
Tiago Duarte

5
In vs 2017 müssen Sie JEDEN Test auswählen, der ausgeführt wird, und dann auf Ausgabe klicken - nicht sehr nützlich, wenn Sie viele Tests haben. Ich möchte die gesamte Ausgabe zusammen sehen - nicht in separaten Fenstern.
Inliner49er

37

Mit dieser Zeile können Sie in das Ausgabefenster von Visual Studio schreiben :

System.Diagnostics.Debug.WriteLine("Matrix has you...");

Muss im Debug-Modus ausgeführt werden.


7
Es schreibt nicht auf meinem VS
Luis Filipe

1
Überprüfen Sie diesen Thread für die Details - stackoverflow.com/questions/1159755/…
Dmitry Pavlov

1
Dies funktionierte hervorragend für mich, indem ich MSTest und R # zum Anzeigen der Ausgabe verwendete. Vielen Dank!
Isaac Baker

2
@William wird angezeigt, wenn Sie einen Test debuggen, aber nicht, wenn Sie ihn einfach ohne Debugging ausführen.
Jojo

29

Wie bereits erwähnt, sind Unit-Tests so konzipiert, dass sie ohne Interaktion ausgeführt werden können.

Sie können Unit-Tests jedoch wie jeden anderen Code debuggen. Am einfachsten ist es, die Schaltfläche Debuggen auf der Registerkarte Testergebnisse zu verwenden.

Debuggen bedeutet, Haltepunkte verwenden zu können. Haltepunkte verwenden zu können bedeutet also, Tracepoints verwenden zu können , was ich beim täglichen Debuggen äußerst nützlich finde.

Mit Tracepoints können Sie im Wesentlichen in das Ausgabefenster (oder genauer in die Standardausgabe) schreiben. Optional können Sie die Ausführung fortsetzen oder wie ein normaler Haltepunkt anhalten. Auf diese Weise erhalten Sie die gewünschte "Funktionalität", ohne dass Sie Ihren Code neu erstellen oder mit Debug-Informationen füllen müssen.

Fügen Sie einfach einen Haltepunkt hinzu und klicken Sie mit der rechten Maustaste auf diesen Haltepunkt. Wählen Sie die Option "Wenn getroffen ...": Bei Trefferoption

Was den Dialog aufruft: Wenn der Haltepunkt erreicht ist

Ein paar Dinge zu beachten:

  1. Beachten Sie, dass der Haltepunkt jetzt als Diamant anstelle einer Kugel angezeigt wird, die einen Verfolgungspunkt angibt
  2. Sie können den Wert einer Variablen ausgeben, indem Sie ihn wie folgt einschließen.
  3. Deaktivieren Sie das Kontrollkästchen "Ausführung fortsetzen", damit der Code wie bei jedem normalen Haltepunkt in dieser Zeile unterbrochen wird
  4. Sie haben die Möglichkeit, ein Makro auszuführen. Bitte seien Sie vorsichtig - Sie können schädliche Nebenwirkungen verursachen.

Weitere Informationen finden Sie in der Dokumentation.


24

Es gibt verschiedene Möglichkeiten, die Ausgabe eines Visual Studio-Komponententests in C # zu schreiben:

  • Console.Write - Das Visual Studio-Testkabel erfasst dies und zeigt es an, wenn Sie den Test im Test-Explorer auswählen und auf den Link Ausgabe klicken. Wird nicht im Visual Studio-Ausgabefenster angezeigt, wenn ein Komponententest ausgeführt oder debuggt wird (dies ist möglicherweise ein Fehler).
  • Debug.Write - Das Visual Studio-Testkabel erfasst dies und zeigt es in der Testausgabe an. Wird beim Debuggen eines Komponententests im Visual Studio-Ausgabefenster angezeigt, es sei denn, die Visual Studio-Debugging-Optionen sind so konfiguriert, dass die Ausgabe in das Sofortfenster umgeleitet wird. Im Ausgabefenster (oder im Sofortfenster) wird nichts angezeigt, wenn Sie den Test einfach ohne Debugging ausführen. Standardmäßig nur in einem Debug-Build verfügbar (dh wenn die DEBUG-Konstante definiert ist).
  • Trace.Write - Das Visual Studio-Testkabel erfasst dies und zeigt es in der Testausgabe an. Wird beim Debuggen eines Komponententests im Visual Studio-Ausgabefenster (oder im Sofortfenster) angezeigt (jedoch nicht, wenn der Test einfach ohne Debugging ausgeführt wird). Standardmäßig sowohl in Debug- als auch in Release-Builds verfügbar (dh wenn die TRACE-Konstante definiert ist).

Bestätigt in Visual Studio 2013 Professional.


1
Beachten Sie, dass sich die Regeln geringfügig unterscheiden, wenn Sie NUnit und die Erweiterung NUnit Test Adapter für Visual Studio anstelle des integrierten Microsoft-Testframeworks verwenden.
Jojo

9

Sie können verwenden

Trace.WriteLine() 

beim Debuggen eines Unittest in das Ausgabefenster schreiben.


5

In Visual Studio 2017 zeigt "TestContext" keinen Ausgabe-Link im Test Explorer an. Trace.Writeline () zeigt jedoch den Ouput-Link.


Nur zu Ihrer
Information

4

Zunächst alle Unit - Tests sind, durch Design , soll ganz ohne Interaktion laufen.

Abgesehen davon glaube ich nicht, dass es eine Möglichkeit gibt, an die gedacht wurde.

Sie können versuchen, mit AllocConsole P / Invoke zu hacken, wodurch eine Konsole geöffnet wird, auch wenn Ihre aktuelle Anwendung eine GUI-Anwendung ist. Die ConsoleKlasse wird dann auf der jetzt geöffneten Konsole posten.


1
Hmm .. Mein Hauptmotiv ist es, einige zusätzliche Daten in die Konsole zu schreiben, um einige tiefere Details zu sehen. Es wird eine Ad-hoc-Sache sein, die ich später vielleicht nicht brauche.
Bleistiftkuchen


2

IMHO-Ausgabemeldungen sind in den meisten Fällen nur für den Fall eines fehlgeschlagenen Tests relevant. Ich habe das folgende Format zusammengestellt, Sie können auch Ihr eigenes erstellen. Dies wird im VS Test Explorer-Fenster selbst angezeigt.

Wie wird diese Nachricht in das VS Test Explorer-Fenster geworfen? Ein Beispielcode wie dieser sollte funktionieren.

if(test_condition_fails)
    Assert.Fail(@"Test Type: Positive/Negative.
                Mock Properties: someclass.propertyOne: True
                someclass.propertyTwo: True
                Test Properties: someclass.testPropertyOne: True
                someclass.testPropertyOne: False
                Reason for Failure: The Mail was not sent on Success Task completion.");

Sie können eine separate Klasse für Sie haben. Ich hoffe es hilft!


Ich dachte, ich würde das auch hinzufügen. In Visual Studio 2019 mit XUNIT können Sie Folgendes tun: Assert.True (Erfolg, "DELETE RECORD FAILED"); DELETE RECORD FAILED wird dann im VS 2019 Test Explorer angezeigt. Wie die obige Antwort funktioniert dies auch hier nur, wenn Ihr Komponententest die erwartete Bedingung nicht erfüllt hat.
TroySteven

1

Ich habe eine einfachere Lösung (die ich kürzlich aus einer Vielzahl von faulen Gründen selbst verwendet habe). Fügen Sie diese Methode der Klasse hinzu, in der Sie arbeiten:

public static void DumbDebug(string message)
    {
        File.WriteAllText(@"C:\AdHocConsole\" + message + ".txt", "this is really dumb, I wish microsoft had more obvious solutions to it's solutions' problems.");
    }

Dann ... öffnen Sie das Verzeichnis AdHocConsole, sortieren Sie nach Erstellungszeit. Stellen Sie sicher, dass Ihre "Druckanweisungen" unterschiedlich sind, da sie sonst unterschiedlich sind.


0

Visual Studio für Mac

Keine der anderen Lösungen funktionierte unter VS für Mac

Wenn Sie NUnit verwenden , können Sie Ihrer Lösung ein kleines .NET Konsolenprojekt hinzufügen und dann in den Referenzen dieses neuen Konsolenprojekts auf das Projekt verweisen, das Sie testen möchten .

Was auch immer Sie in Ihren [Test()]Methoden getan haben, können Sie in Mainder Konsolen-App auf folgende Weise tun :

class MainClass
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Console");

        // Reproduce the Unit Test
        var classToTest = new ClassToTest();
        var expected = 42;
        var actual = classToTest.MeaningOfLife();
        Console.WriteLine($"Pass: {expected.Equals(actual)}, expected={expected}, actual={actual}");
    }
}

Unter diesen Umständen können Sie Console.Writeund Console.WriteLinein Ihrem Code frei verwenden .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.