Ich habe ein Testprojekt in Visual Studio. Ich verwende Microsoft.VisualStudio.TestTools.UnitTesting.
Ich füge diese Zeile in einem Unit-Test hinzu:
Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();
Wenn ich den Test starte, wird der Test bestanden, 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?
HINWEIS: Die ursprüngliche Antwort unten sollte für alle Versionen von VS bis VS2012 funktionieren. VS2013 scheint kein Fenster mit Testergebnissen mehr zu haben. Wenn Sie eine testspezifische Ausgabe benötigen, können Sie stattdessen den @ Stretch-Vorschlag von Trace.Write()
verwenden, um die Ausgabe in das Ausgabefenster zu schreiben.
Die Console.Write
-Methode schreibt nicht in die "Konsole" - sie schreibt in alles, was mit dem Standardausgabe-Handle für den laufenden Prozess verbunden ist. In ähnlicher Weise liest Console.Read
die Eingabe 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 anzeigen, indem Sie mit der rechten Maustaste auf das Fenster "Testergebnisse" klicken und der Anzeige die Spalte "Ausgabe (StdOut)" hinzufügen. Dies zeigt alles an, was an stdout geschrieben wurde.
Sie könnten manuell ein Konsolenfenster mit P/Invoke öffnen, wie @ sinni800 sagt. Aus der AllocConsole
Dokumentation geht hervor, dass die Funktion die Handles stdin
und stdout
zurücksetzt, um auf das neue Konsolenfenster zu verweisen. (Da bin ich mir nicht hundertprozentig sicher. Es scheint mir falsch, wenn ich bereits stdout
umgeleitet habe, damit Windows es mir stiehlt, 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 erhalten, ist die Ausgabe für Sie da. Verwenden Sie Console.WriteLine
so wie Sie sind, und überprüfen Sie die Ausgabeergebnisse im Fenster Testergebnisse, wenn Sie fertig sind.
Jemand kommentierte diese offenbar neue Funktionalität in VS2013. Ich war mir nicht sicher, was er zuerst meinte, aber jetzt, wo ich das tue, denke ich, dass es seine eigene Antwort verdient.
Wir können Console.WriteLine normal verwenden und die Ausgabe wird angezeigt, nicht im Ausgabefenster, sondern in einem neuen Fenster, nachdem wir in den Testdetails auf "Ausgabe" geklickt haben.
Sie können diese Zeile verwenden, um in Output Window des Visual Studio zu schreiben:
System.Diagnostics.Debug.WriteLine("Matrix has you...");
Hoffentlich hilft das
Wie bereits erwähnt, sind Unit-Tests so konzipiert, dass sie ohne Interaktion laufen.
Sie können Unit-Tests jedoch genauso wie jeden anderen Code debuggen. Am einfachsten ist es, die Schaltfläche Debuggen auf der Registerkarte Testergebnisse zu verwenden.
Debugging heißt, Breakpoints verwenden zu können. Breakpoints verwenden zu können bedeutet, Tracepoints verwenden zu können, was ich im täglichen Debugging sehr nützlich finde.
Im Wesentlichen können Sie mit Tracepoints in das Ausgabefenster schreiben (oder genauer in die Standardausgabe). Optional können Sie weiterlaufen oder wie ein normaler Haltepunkt anhalten. Dadurch erhalten Sie die "Funktionalität", nach der Sie fragen, ohne dass Sie den Code neu erstellen oder mit Debug-Informationen füllen müssen.
Fügen Sie einfach einen Haltepunkt hinzu und klicken Sie dann mit der rechten Maustaste auf diesen Haltepunkt. Wählen Sie die Option "When Hit ...":
Welcher Dialog erscheint:
Ein paar Dinge zu beachten:
Weitere Informationen finden Sie in der Dokumentation.
Es gibt mehrere Möglichkeiten, die Ausgabe eines Visual Studio-Komponententests in C # zu schreiben:
Bestätigt in Visual Studio 2013 Professional.
Sie können verwenden
Trace.WriteLine()
zum Schreiben in das Ausgabefenster beim Debuggen eines Tests.
In Visual Studio 2017 zeigt "TestContext" den Ausgabe-Link nicht im Test Explorer an. Trace.Writeline () zeigt jedoch die Ouput-Verknüpfung.
Zunächst sollen Unit-Tests von design vollständig ohne Interaktion ablaufen.
Abgesehen davon glaube ich nicht, dass an eine Möglichkeit gedacht wurde.
Sie könnten versuchen, mit AllocConsole P/Invoke zu hacken, um eine Konsole zu öffnen, selbst wenn Ihre aktuelle Anwendung eine GUI-Anwendung ist. Die Console
-Klasse wird dann an die jetzt geöffnete Konsole gesendet.
Genau das ist keine Lösung, sondern ein Ansatz aus dem Buch der
art of Unit Testing von Roy Osherove
wir brauchen Stubs, um diese Abhängigkeiten zu durchbrechen, wie das Schreiben in das Dateisystem oder das Schreiben in das Ereignisprotokoll oder das Schreiben in die Konsole.
Stub könnte an die Hauptklasse übergeben werden, und wenn Stub nicht null ist, schreiben Sie in Stub. Es kann jedoch die API ändern (wie jetzt hat Konstruktor einen Stub als Parameter). Der andere Ansatz ist das Erben und Erstellen eines Scheinobjekts. was unten beschrieben wird.
namespace ClassLibrary1
{
// TO BE TESTED
public class MyBusinessClass
{
ConsoleStub myConsoleForTest;
public MyBusinessClass()
{
// Constructor
}
// This is test stub approach - 2
public MyBusinessClass(ConsoleStub console)
{
this.myConsoleForTest = console;
}
public virtual void MyBusinessMethod(string s)
{
// this needs to be unit tested
Console.WriteLine(s);
// Just an example - you need to be creative here
// there are many ways
if (myConsoleForTest !=null){
myConsoleForTest.WriteLine(s);
}
}
}
public class ConsoleStub
{
private string textToBeWrittenInConsole;
public string GetLastTextWrittenInConsole
{
get
{
return this.textToBeWrittenInConsole;
}
}
public void WriteLine(string text)
{
this.textToBeWrittenInConsole = text;
}
}
public class MyBusinessClassMock :MyBusinessClass
{
private ConsoleStub consoleStub;
public MyBusinessClassMock()
{
// Constructor
}
public MyBusinessClassMock(ConsoleStub stub)
{
this.consoleStub = stub;
}
public override void MyBusinessMethod(string s)
{
// if MOCK is not an option then pass this stub
// as property or parameter in constructor
// if you do not want to change the api still want
// to pass in main class then , make it protected and
// then inherit it and make just a property for consoleStub
base.MyBusinessMethod(s);
this.consoleStub.WriteLine(s);
}
}
[TestClass]
public class ConsoleTest
{
private ConsoleStub consoleStub;
private MyBusinessClassMock mybusinessObj
[TestInitialize]
public void Initialize()
{
consoleStub = new ConsoleStub();
mybusinessObj = new MyBusinessClassMock(consoleStub);
}
[TestMethod]
public void TestMyBusinessMethod()
{
mybusinessObj.MyBusinessMethod("hello world");
Assert.AreEqual(this.consoleStub.GetLastTextWrittenInConsole,"hello world" );
}
}
}
// Approach - 2
[TestClass]
public class ConsoleTest
{
private ConsoleStub consoleStub;
private MyBusinessClass mybusinessObj
[TestInitialize]
public void Initialize()
{
consoleStub = new ConsoleStub();
mybusinessObj = new MyBusinessClass(consoleStub);
}
[TestMethod]
public void TestMyBusinessMethod()
{
mybusinessObj.MyBusinessMethod("hello world");
Assert.AreEqual(this.consoleStub.GetLastTextWrittenInConsole,"hello world" );
}
}
Debug.WriteLine () kann ebenfalls verwendet werden.
Die IMHO-Ausgabenachricht ist in den meisten Fällen nur für den Fall eines fehlgeschlagenen Tests relevant. Ich habe das folgende Format erstellt, Sie können auch Ihr eigenes Format erstellen. Dies wird im VS Test Explorer-Fenster selbst angezeigt.
Wie wird diese Nachricht im VS Test Explorer-Fenster ausgegeben? 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 eigene Klasse für Sie einrichten. Ich hoffe es hilft!
Keine der anderen Lösungen funktionierte mit VS für Mac
Wenn Sie NUnit verwenden, können Sie Ihrer Lösung einen kleinen .NET
Konsolenprojekt hinzufügen. Verweisen Sie dann auf das Projekt, das Sie testen möchten, in Referenzen dieses neuen Objekts Konsolenprojekt.
Was auch immer Sie in Ihren [Test()]
-Methoden getan haben, können Sie in der Main
der Konsolen-App auf folgende Weise ausführen:
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.Write
und Console.WriteLine
in Ihrem Code verwenden.