初心者のためのC#プログラミング本格入門100 - 似たテストも必要。
ファイルを分割しやりやすくなったところで、foreachループ対応の件に戻ります。何か新しいことをする前に、テストをしましょう。それがテストファーストです。
class SimpleListTest : Test
{
public override void ExecuteAllTest()
{
this.OneElementAdd();
this.CurrentTest();
this.AddElementCheck();
this.ForeEachTest();
this.ForeEachTest2();
}
//foreachを模倣する
public void ForeEachTest()
{
//準備
base.Execute();
for ( int i = 0 ; i < 10 ; ++i )
{
this.target.Add( i );
}
//1 ~ 9 の数値が格納されているはず
int x = 0;
System.Text.StringBuilder error =
new System.Text.StringBuilder();
do {
if ( ie.Current != x )
{
string message =
"ForeEachTestで予期せぬ値が返されました。" +
"予想値:" + x +
" 返された値" + ie.Current +
System.Environment.NewLine;
error.Append( message );
base.Error( message );
}
++x;
} while ( ie.MoveNext() );
if ( error.Length != 0 ) {
base.Error( error.ToString() );
}
}
public void ForeEachTest2()
{
//準備
base.Execute();
for ( int i = 0 ; i < 10 ; ++i ) {
this.target.Add( i );
}
//1 ~ 9 の数値が格納されているはず
int x = 0;
System.Text.StringBuilder error =
new System.Text.StringBuilder();
foreach ( int value in this.target ) {
if ( value != x ) {
string message =
"ForeEachTest2で予期せぬ値が返されました。" +
"予想値:" + x +
" 返された値" + value +
System.Environment.NewLine;
error.Append( message );
base.Error( message );
}
++x;
}
}
}
この2つの似たテストを実行してみましょう。お察しの通りエラーが出ます。あわてず予想値と実際に返された値を比べてみましょう。1つずつずれています。この様子から、配列のインデックスがずれているとわかります。ということで、初期値を変更してみましょう。
private class Enumerator :
System.Collections.Generic.IEnumerable<int>,
System.Collections.Generic.IEnumerator<int>
{
private int[ ] data;
private int readIndex; //読み取り位置
public Enumerator( int[ ] data )
{
this.data = data;
this.readIndex = -1; //0からー1へ変更
}
//他は省略
}
変更したらまたテストを実行しましょう。今度は止まってしまいます。止まった時、開発ソフトのデバッグ機能で確認すると、readIndexが-1のまま配列にアクセスしてしまっています。配列は0から数えるので、ストップしてしまいます。では、どこが間違っているのでしょうか?答えを見る前に、一度自分で考えてみて下さい。分かりましたか?答えは、「テストプログラム自体が間違っている」です。テストをする際は、テストプログラムも視野に入れて点検します。-1のまま配列にアクセスするのが問題なのですから、1つの命令をテストプログラムに追加します。
public void ForeEachTest()
{
//準備
base.Execute();
for ( int i = 0 ; i < 10 ; ++i )
{
this.target.Add( i );
}
//1 ~ 9 の数値が格納されているはず
int x = 0;
System.Text.StringBuilder error =
new System.Text.StringBuilder();
ie.Reset(); //ここに注目!
do {
if ( ie.Current != x )
{
string message =
"ForeEachTestで予期せぬ値が返されました。" +
"予想値:" + x +
" 返された値" + ie.Current +
System.Environment.NewLine;
error.Append( message );
base.Error( message );
}
++x;
} while ( ie.MoveNext() );
if ( error.Length != 0 ) {
base.Error( error.ToString() );
}
}
1行追加しただけで大丈夫です。今度はテスト成功です。初心者の方は、なぜ同じ内容に見えるテストを作ったのか不思議に思ったでしょう。その答えは、実際にやってみてわかったと思います。テスト漏れが生じないように、微妙に違うテストも必要なのです。特に今回のように、手探りで進んでいる状態のときは有効です。学習目的のときは特にこれが言えます。1つだけで済ませようとせず、角度を変えて考える姿勢が大事です。プログラミングはいろいろ試して習得するものです。1つで分かったつもりにならず、色々試してみましょう。続く...