.NETテストプログラミング入門4
前回紹介したテストコードにはある問題があります。それは、並行的にテストを行う時露呈します。
using System;
using System.IO;
using System.Threading;
class Tester
{
public bool ConsoleOutCheck( string right, Action proc, bool yield )
{
//出力先を変えてテストを行いやすくする
TextWriter tmp = Console.Out;
StringWriter writer = new StringWriter();
Console.SetOut( writer );
//テスト対象を実行
Thread.Sleep( 100 );
proc();
//出力設定を元に戻す
if ( yield == true ) Thread.Yield();
Console.SetOut( tmp );
//出力値をテスト
bool result = writer.ToString().Equals( right );
//テスト結果を返す
return result;
}
}
class Piyo
{
public void Greeting()
{
Console.WriteLine( "おはピヨ♪" );
}
}
class HelloWorld
{
public void FirstProgramming()
{
Console.WriteLine( "Hello World!" );
}
}
class Test
{
static void Main( string[] args )
{
//テストの準備
Tester tester = new Tester();
//Piyoクラスのテストを実行
string piyoMessage = null;
Thread pt = new Thread( () => {
Piyo piyo = new Piyo();
string right = "おはピヨ♪" + Environment.NewLine;
bool result = tester.ConsoleOutCheck(
right,
() => piyo.Greeting(),
false );
piyoMessage = result == true ?
"Piyoテスト成功" : "Piyoテスト失敗";
} );
//HelloWorldクラスのテストを実行
string helloMessage = null;
Thread ht = new Thread( () => {
HelloWorld hello = new HelloWorld();
string right = "Hello World!" + Environment.NewLine;
bool result = tester.ConsoleOutCheck(
right,
() => hello.FirstProgramming(),
true );
helloMessage = result == true ?
"HelloWorldテスト成功" : "HelloWorldテスト失敗";
} );
//並行的にテスト
pt.Start();
ht.Start();
pt.Join();
ht.Join();
//テスト結果を表示
Console.WriteLine( piyoMessage );
Console.WriteLine( helloMessage );
}
}
※このサンプルコードは、並行処理による問題が発生しやすいようにしています。このサンプルを実行すれば、前回紹介したテストコードは並行処理時に問題がある事が分かります。もし、問題が発生しない場合は、Sleepに引き渡す値を大きくしてみましょう。
この問題が発生する原因は、静的プロパティを使用している点です。静的プロパティであるOutプロパティを静的メソッドで設定しているため、個々のスレッドの出力ストリームの変更が、他のスレッドに影響を与えています。この状態ではまともにテストが出来ません。
今後並行的にテストを処理する機会が多くなるでしょう。ですから、テスト対象となるクラスが持つ性質をよく考えなくてはなりません。問題の解決方法は次回解説します。続く...