J'ai un projet de test dans Visual Studio. J'utilise Microsoft.VisualStudio.TestTools.UnitTesting.
J'ajoute cette ligne dans l'un de mes tests unitaires:
Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();
Lorsque j'exécute le test, le test réussit, mais la fenêtre de la console n'est pas ouverte du tout.
Existe-t-il un moyen de rendre la fenêtre de console disponible pour l’interaction via un test unitaire?
REMARQUE: La réponse originale ci-dessous devrait fonctionner pour toutes les versions de VS jusqu'à VS2012. VS2013 ne semble plus avoir de fenêtre Résultats du test. Si vous avez besoin d'une sortie spécifique au test, vous pouvez utiliser la suggestion de Trace.Write()
de @ Stretch pour écrire la sortie dans la fenêtre Sortie.
La méthode Console.Write
n'écrit pas sur la "console" - elle écrit sur tout ce qui est connecté au handle de sortie standard du processus en cours d'exécution. De même, Console.Read
lit les entrées à partir de tout ce qui est connecté à l'entrée standard.
Lorsque vous exécutez un test unitaire via VS2010, la sortie standard est redirigée par le faisceau de test et stockée avec la sortie de test. Vous pouvez le voir en cliquant avec le bouton droit de la souris sur la fenêtre Résultats du test et en ajoutant la colonne intitulée "Sortie (StdOut)" à l'écran. Cela montrera tout ce qui a été écrit sur stdout.
Vous pourriez ouvrir manuellement une fenêtre de console en utilisant P/Invoke comme @ sinni800 le dit. D'après la documentation AllocConsole
, il apparaît que la fonction réinitialisera les poignées stdin
et stdout
pour qu'elles pointent vers la nouvelle fenêtre de la console. (Je ne suis pas tout à fait sûr à ce sujet; cela me semble un peu faux si j'ai déjà redirigé stdout
pour que Windows me le vole, mais je n'ai pas essayé.)
En général, cependant, je pense que c'est une mauvaise idée. si vous souhaitez uniquement utiliser la console pour afficher davantage d'informations sur votre test unitaire, la sortie est là pour vous. Continuez à utiliser Console.WriteLine
comme vous êtes et vérifiez les résultats dans la fenêtre Résultats du test lorsque vous avez terminé.
Quelqu'un a commenté cette fonctionnalité apparemment nouvelle dans VS2013. Je ne savais pas trop ce qu'il voulait dire au début, mais maintenant que je le fais, je pense que cela mérite sa propre réponse.
Nous pouvons utiliser Console.WriteLine normalement et la sortie est affichée, mais pas dans la fenêtre de sortie, mais dans une nouvelle fenêtre après avoir cliqué sur "Sortie" dans les détails du test.
Vous pouvez utiliser cette ligne pour écrire dans Fenêtre de sortie de Visual Studio:
System.Diagnostics.Debug.WriteLine("Matrix has you...");
J'espère que cela pourra aider
Comme indiqué, les tests unitaires sont conçus pour fonctionner sans interaction.
Cependant, vous pouvez déboguer des tests unitaires, comme n'importe quel autre code. Le moyen le plus simple consiste à utiliser le bouton Déboguer de l'onglet Résultats du test.
Être capable de déboguer signifie pouvoir utiliser les points d'arrêt. Pouvoir utiliser des points d'arrêt signifie donc pouvoir utiliser Tracepoints, que je trouve extrêmement utile dans le débogage quotidien.
Les points de trace vous permettent essentiellement d’écrire dans la fenêtre Sortie (ou, plus précisément, dans la sortie standard). Vous pouvez éventuellement continuer à courir ou vous arrêter comme un point d'arrêt habituel. Cela vous donne la "fonctionnalité" que vous demandez, sans qu'il soit nécessaire de reconstruire votre code ni de le remplir avec des informations de débogage.
Ajoutez simplement un point d'arrêt, puis cliquez avec le bouton droit de la souris sur ce point d'arrêt. Sélectionnez l'option "When Hit ...":
Ce qui amène le dialogue:
Quelques points à noter:
Voir la documentation pour plus de détails.
Il existe plusieurs façons d'écrire la sortie d'un test d'unité Visual Studio en C #:
Confirmé dans Visual Studio 2013 Professional.
Vous pouvez utiliser
Trace.WriteLine()
pour écrire dans la fenêtre de sortie lors du débogage d’un unittest.
Dans Visual Studio 2017, "TestContext" n'indique pas le lien de sortie dans Test Explorer. Cependant, Trace.Writeline () affiche le lien Ouput.
Tout d’abord, les tests unitaires sont, par design, supposés fonctionner complètement sans interaction.
Cela dit, je ne pense pas qu'il y ait une possibilité à laquelle on a pensé.
Vous pouvez essayer le piratage avec AllocConsole P/Invoke qui ouvrira une console même si votre application actuelle est une application à interface graphique. La classe Console
publiera ensuite sur la console maintenant ouverte.
Ce n’est pas une solution, mais une approche du livre the
art des tests unitaires par Roy Osherove
nous avons besoin de stubs pour rompre ces dépendances, comme écrire dans FileSystem ou écrire dans Event Log ou écrire dans la console -
Le stub peut être passé dans la classe principale et si stub n'est pas nul, écrivez dans le stub. Cependant, il peut changer l’API (comme maintenant, le constructeur a un tronçon comme paramètre). L'autre approche consiste à hériter et à créer un objet fantaisie. qui est décrit ci-dessous.
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 () peut également être utilisé.
Les messages de sortie IMHO ne sont pertinents que pour le scénario de test ayant échoué dans la plupart des cas. J'ai composé le format ci-dessous, vous pouvez créer le vôtre aussi. Ceci est affiché dans la fenêtre de VS Test Explorer elle-même.
Comment afficher ce message dans la fenêtre de VS Test Explorer? Un exemple de code comme celui-ci devrait fonctionner.
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.");
Vous pouvez avoir une classe séparée dédiée à cela pour vous. J'espère que ça aide!
Aucune des autres solutions ne fonctionnait sur VS pour Mac
Si vous utilisez NUnit, vous pouvez ajouter un petit .NET
projet de console à votre solution, puis référencer le projet que vous souhaitez tester dans les références de cette nouvelle Projet de console.
Tout ce que vous faisiez dans vos méthodes [Test()]
peut être fait dans la Main
de l'application console de cette manière:
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}");
}
}
Vous êtes libre d'utiliser Console.Write
et Console.WriteLine
dans votre code dans ces circonstances.