Visual Studioにテストプロジェクトがあります。 Microsoft.VisualStudio.TestTools.UnitTestingを使用します。
ユニットテストの1つにこの行を追加します。
Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();
テストを実行すると、テストは成功しますが、コンソールウィンドウはまったく開かれません。
単体テストでコンソールウィンドウを操作できるようにする方法はありますか?
注:以下の元の回答は、VS2012までのVSのすべてのバージョンで機能するはずです。 VS2013には、[テスト結果]ウィンドウが表示されなくなりました。代わりに、テスト固有の出力が必要な場合は、@ StretchのTrace.Write()
の提案を使用して、出力ウィンドウに出力を書き込むことができます。
Console.Write
メソッドは「コンソール」に書き込みません。実行中のプロセスの標準出力ハンドルに接続されているものに書き込みます。同様に、Console.Read
は、標準入力に接続されているものから入力を読み取ります。
VS2010を通じて単体テストを実行すると、標準出力はテストハーネスによってリダイレクトされ、テスト出力の一部として保存されます。これを確認するには、テスト結果ウィンドウを右クリックし、「出力(StdOut)」という名前の列を表示に追加します。これにより、stdoutに書き込まれたものがすべて表示されます。
could @ sinni800が言うようにP/Invokeを使用して、手動でコンソールウィンドウを開きます。 AllocConsole
name__のドキュメントを読むと、この関数はstdin
name__およびstdout
name__ハンドルをリセットして新しいコンソールウィンドウを指すように見えます。 (私はそれについて100%確信していません;それを盗むためにWindows用にstdout
name__をすでにリダイレクトしている場合、それはちょっと間違っているようですが、私は試していません。)
しかし、一般的には、それは悪い考えだと思います。コンソールを使用したいのがユニットテストに関する詳細情報をダンプすることだけである場合、出力はそこにあります。 Console.WriteLine
をそのまま使用し、完了したら、[テスト結果]ウィンドウで出力結果を確認します。
この行を使用して、Visual Studioの 出力ウィンドウ に書き込むことができます。
System.Diagnostics.Debug.WriteLine("Matrix has you...");
役立つことを願っています
前述のように、単体テストは相互作用なしで実行されるように設計されています。
ただし、他のコードと同様に、単体テストをデバッグできます。最も簡単な方法は、[テスト結果]タブの[デバッグ]ボタンを使用することです。
デバッグできるとは、ブレークポイントを使用できることを意味します。したがって、ブレークポイントを使用できるということは、Tracepointsを使用できることを意味します。これは、毎日のデバッグに非常に役立ちます。
基本的に、トレースポイントを使用すると、出力ウィンドウ(または、より正確には標準出力)に書き込むことができます。オプションで、実行を継続することも、通常のブレークポイントのように停止することもできます。これにより、コードを再構築したり、デバッグ情報で埋めたりすることなく、求めている「機能」が得られます。
単にブレークポイントを追加し、そのブレークポイントを右クリックします。 [ヒット時...]オプションを選択します。
ダイアログが表示されます:
注意すべきいくつかの点:
詳細については、ドキュメントを参照してください。
C#でVisual Studio単体テストからの出力を書き込む方法はいくつかあります。
Visual Studio 2013 Professionalで確認済み。
使用できます
Trace.WriteLine()
unittestのデバッグ時に出力ウィンドウに書き込む。
Visual Studio 2017では、「TestContext」はテストエクスプローラーに出力リンクを表示しません。ただし、Trace.Writeline()はOuputリンクを示しています。
すべてのユニットテストの最初は、designによって、相互作用なしで完全に実行されることになっています。
それはさておき、私は考えられていた可能性があるとは思わない。
AllocConsole P/Invoke を使用してハッキングを試みると、現在のアプリケーションがGUIアプリケーションであってもコンソールが開きます。 Console
クラスは、現在開かれているコンソールにポストします。
Debug.WriteLine()も使用できます。
これはまさに解決策ではなく、本からのアプローチです
roy Osheroveによるユニットテストの芸術
fileSystemへの書き込み、イベントログへの書き込み、コンソールへの書き込みなど、これらの依存関係を解消するためのスタブが必要です-
スタブはメインクラスに渡され、スタブがnullでない場合はスタブに書き込みます。ただし、APIを変更できます(コンストラクターがパラメーターとしてスタブを持つようになりました)。もう1つのアプローチは、モックオブジェクトの継承と作成です。以下で説明します。
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" );
}
}
IMHO出力メッセージは、ほとんどの場合、失敗したテストケースにのみ関連します。以下の形式を作成しましたが、独自の形式も作成できます。これは、VS Test Explorerウィンドウ自体に表示されます。
VS Test Explorerウィンドウでこのメッセージをスローする方法は?このようなサンプルコードが機能するはずです。
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.");
これ専用の個別のクラスを用意できます。それが役に立てば幸い!
他のソリューションのどれもVS for Macで動作しませんでした
NUnitを使用している場合、小さな.NET
Console Projectをソリューションに追加し、テストするプロジェクトをReferencesで参照できます。その新しいConsole Projectの。
[Test()]
メソッドで実行していたことはすべて、この方法でコンソールアプリのMain
で実行できます。
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}");
}
}
これらの状況では、コードでConsole.Write
およびConsole.WriteLine
を自由に使用できます。