M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

NUnitことはじめ (1)

引きつづき、NUnitについて見ていきます。原文は、NUnit 2.5.9です。
とりあえず導入から、単純な比較アサーションまで。

******************************

NUnitことはじめ

もしまだでしたらダウンロードページでNUnitをダウンロードしましょう。インストールページには、NUnitをあなたのシステム上に導入する手順が示されています。

NUnitをはじめてお使いの方はクイックスタートページを参照してください。この記事はC#で銀行アプリケーションをつくるという設定で、NUnitを使用した開発工程の例を示しています。VB.NETやJ#、C++マネージ拡張(managed C++)での使用も含めたより多くの例を見るにはサンプルページをチェックしてください。

どちらのテストランナーを使用するか

NUnitには2つの異なる実行方法があります。コンソールランナー(console runner)──nunit-console.exeは、起動は速いですが、対話性に欠けます(is not interactive)。GUIランナー──nunit.exeは、テストケースの選択的実行の機能や視覚的なフィードバックの機能を提供するWindows Forms*1アプリケーションです。

アサーション

アサーション”はxUnit系フレームワークによる単体テストの中心的概念です。NUnitも例外ではありません。NUnitは、Assertクラスのstaticメソッドとして豊富なアサーションを提供しています。

もしアサーションが失敗したら、このアサーションメソッドの呼び出しはいかなる値も返さず、かわりにエラーを報告します。もしテストケースに複数のアサーションが含まれていた場合、失敗したアサーションに後続するアサーションは実行されません。このため、たいていの場合1つのテストケースにつき1つのアサーションを行うのがベストです。

それぞれのメソッドは、メッセージなしに、シンプルなテキストメッセージとともに、あるいはまたメッセージといくつかの引数をともなって、実行されます。最後のケースの場合、メッセージは指定されたテキストと引数とを使用して整形されます。

2つのモデル

NUnit2.4より前は、Assertクラスの個々のメソッドが種々のアサーションのために使用されていました。これを“クラシックモデル”(Classic Model)と呼びます。

NUnit2.4からは、“制約ベースモデル”が導入されました。このアプローチはAssertクラスの1つのメソッドを、すべてのアサーションで使用します。実行したテストに合わせてConstraintオブジェクトを渡すのです。

現在、制約ベースモデルは、NUnitのすべてのアサーションメソッドの内部で使用されています。つまり、クラシックモデルのアプローチのためのメソッドは、新しい制約ベースモデルの上に再実装されているのです。

等式アサーション

このアサーションのためのメソッドは2つの引数が等しいことをテストします。自動ボクシングをせずに直接に値を使用して比較を行うため、このメソッドは共通値型向けにオーバーロードされています。

Assert.AreEqual( int expected, int actual );
Assert.AreEqual( int expected, int actual, string message );
Assert.AreEqual( int expected, int actual, string message, 
                 params object[] parms );
				 
Assert.AreEqual( uint expected, uint actual );
Assert.AreEqual( uint expected, uint actual, string message );
Assert.AreEqual( uint expected, uint actual, string message, 
                 params object[] parms );

Assert.AreEqual( decimal expected, decimal actual );
Assert.AreEqual( decimal expected, decimal actual, string message );
Assert.AreEqual( decimal expected, decimal actual, string message, 
                 params object[] parms );

Assert.AreEqual( float expected, float actual, float tolerance );
Assert.AreEqual( float expected, float actual, float tolerance,
                 string message );
Assert.AreEqual( float expected, float actual, float tolerance,
                 string message, params object[] parms );

Assert.AreEqual( double expected, double actual, double tolerance );
Assert.AreEqual( double expected, double actual, double tolerance,
                 string message );
Assert.AreEqual( double expected, double actual, double tolerance,
                 string message, params object[] parms );

Assert.AreEqual( object expected, object actual );
Assert.AreEqual( object expected, object actual, string message );
Assert.AreEqual( object expected, object actual, string message, 
                 params object[] parms );

Assert.AreNotEqual( int expected, int actual );
Assert.AreNotEqual( int expected, int actual, string message );
Assert.AreNotEqual( int expected, int actual, string message,
                 params object[] parms );

// (訳者:中略します)
異なる型の数値同士を比較する

2つのobjectを比較するオーバーロードメソッドは、2つの異なる型の数値同士を比較するために提供されています。次のアサーションは成功します。

        Assert.AreEqual( 5, 5.0 );
浮動小数点値を比較する

float型とdouble型の比較は、通常、2つの値が等しいと見なす際の許容誤差範囲を示す引数をともない行われます。NUnit2.4.4以降、この第3の引数が指定されていない場合には、GlobalSettings.DefaultFloatingPointToleranceの値が使用されます。これより前のバージョンであるか、デフォルト値が設定されていない場合、2つの浮動小数点値の比較は、2値がまったく等しいことを確認するものになります。

特殊値の比較もできます。次のアサーションは成功します。

        Assert.AreEqual( double.PositiveInfinity, double.PositiveInfinity );
        Assert.AreEqual( double.NegativeInfinity, double.NegativeInfinity );
        Assert.AreEqual( double.NaN, double.NaN );

注意:上記の例のうち最後のものについてNUnit2.2.3で変更がありました。初期のバージョンではこのテスト結果は失敗となりました。新しい挙動(NaN同士の比較結果が成功となる)はテストをよりやりやすくするように思われたため、この変更が行われました。混乱をさけるため、(NaNをチェックする)それが必要な場面では、新しく追加されたAssert.IsNaNメソッドを使用されることをおすすめします。

配列やコレクションを比較する

バージョン2.2以来、NUnitは2つの1次元配列同士を比較することが可能です。バージョン2.4からは、多次元配列、入れ子配列(配列の配列)*2やコレクション同士を比較できます。Assert.AreEqualメソッドは、同じ次元数で、それぞれの対応する子要素同士が等しい場合に、2つの配列もしくはコレクションは等しいと見なされます。

同一性アサーション


Assert.AreSame
メソッドおよびAssert.AreNotSameメソッドは、引数として渡された2つのobjectが同一のものであるか否かをテストします。

Assert.AreSame( object expected, object actual );
Assert.AreSame( object expected, object actual, string message );
Assert.AreSame( object expected, object actual, string message, 
                params object[] parms );

Assert.AreNotSame( object expected, object actual );
Assert.AreNotSame( object expected, object actual, string message );
Assert.AreNotSame( object expected, object actual, string message, 
                params object[] parms );

Assert.Containsメソッドはあるobjectが配列もしくはリストに含まれているかどうかを確認します。

Assert.Contains( object anObject, IList collection );
Assert.Contains( object anObject, IList collection, 
                string message );
Assert.Contains( object anObject, IList collection,
                string message, params object[] parms );

条件アサーション

特定の条件をテストするためのメソッドは──その条件ごとに名前が付けられています──、第1引数にチェックする値をとり、メッセージ用に任意の引数として第2引数をとります。次のようなメソッドが提供されています。

Assert.IsTrue( bool condition );
Assert.IsTrue( bool condition, string message );
Assert.IsTrue( bool condition, string message, object[] parms );

Assert.True( bool condition );
Assert.True( bool condition, string message );
Assert.True( bool condition, string message, object[] parms );

Assert.IsFalse( bool condition);
Assert.IsFalse( bool condition, string message );
Assert.IsFalse( bool condition, string message, object[] parms );

Assert.False( bool condition);
Assert.False( bool condition, string message );
Assert.False( bool condition, string message, object[] parms );

Assert.IsNull( object anObject );
Assert.IsNull( object anObject, string message );
Assert.IsNull( object anObject, string message, object[] parms );

Assert.Null( object anObject );
Assert.Null( object anObject, string message );
Assert.Null( object anObject, string message, object[] parms );

Assert.IsNotNull( object anObject );
Assert.IsNotNull( object anObject, string message );
Assert.IsNotNull( object anObject, string message, object[] parms );

Assert.NotNull( object anObject );
Assert.NotNull( object anObject, string message );
Assert.NotNull( object anObject, string message, object[] parms );

Assert.IsNaN( double aDouble );
Assert.IsNaN( double aDouble, string message );
Assert.IsNaN( double aDouble, string message, object[] parms );

Assert.IsEmpty( string aString );
Assert.IsEmpty( string aString, string message );
Assert.IsEmpty( string aString, string message,
          params object[] args );

Assert.IsNotEmpty( string aString );
Assert.IsNotEmpty( string aString, string message );
Assert.IsNotEmpty( string aString, string message,
          params object[] args );

Assert.IsEmpty( ICollection collection );
Assert.IsEmpty( ICollection collection, string message );
Assert.IsEmpty( ICollection collection, string message,
          params object[] args );

Assert.IsNotEmpty( ICollection collection );
Assert.IsNotEmpty( ICollection collection, string message );
Assert.IsNotEmpty( ICollection collection, string message,
          params object[] args );

True、False、NullそしてNotNull条件のテストために2つの形式が用意されています。“Is”形式はNUnitの初期バージョンと互換です。一方“Is”をともなわないものはNUnitLiteとの互換性のために用意されています。
Assert.IsEmptyメソッドとAssert.IsNotEmptyメソッドは、stringとコレクションのために使用されます。

比較アサーション(NUnit 2.2.4)

次に示すメソッド群は一方のobjectが他方のobjectに比べて大きいかどうかをテストします。アサーションの通例に反して、これらのメソッドは、“自然な”英語ないし数学の規則にしたがって読めるようデザインされています。例えば、Assert.Greater( x, y )というアサーションは、“xはyより大きい”(x is greater than y. 〔 x > y 〕)とふうに読めます。

Assert.Greater( int arg1, int arg2 );
Assert.Greater( int arg1, int arg2, string message );
Assert.Greater( int arg1, int arg2, string message, 
                object[] parms );

// (訳者:中略します。各値型のために比較アサーションメソッドが用意されています。)

Assert.Greater( IComparable arg1, IComparable arg2 );
Assert.Greater( IComparable arg1, IComparable arg2, string message );
Assert.Greater( IComparable arg1, IComparable arg2, string message, 
                object[] parms );

次に示すメソッド群は、一方のobjectが他方のobjectより大きいか等しいことをテストします。

Assert.GreaterOrEqual( int arg1, int arg2 );
Assert.GreaterOrEqual( int arg1, int arg2, string message );
Assert.GreaterOrEqual( int arg1, int arg2, string message, 
                object[] parms );

// (訳者:中略します。各値型のために比較アサーションメソッドが用意されています。)

Assert.GreaterOrEqual( IComparable arg1, IComparable arg2 );
Assert.GreaterOrEqual( IComparable arg1, IComparable arg2, string message );
Assert.GreaterOrEqual( IComparable arg1, IComparable arg2, string message, 
                object[] parms );

次に示すメソッド群は、一方のobjectが他方のobjectより小さいことをテストします。

Assert.Less( int arg1, int arg2 );
Assert.Less( int arg1, int arg2, string message );
Assert.Less( int arg1, int arg2, string message, 
                object[] parms );
				
// (訳者:中略します。各値型のために比較アサーションメソッドが用意されています。)
				
Assert.Less( IComparable arg1, IComparable arg2 );
Assert.Less( IComparable arg1, IComparable arg2, string message );
Assert.Less( IComparable arg1, IComparable arg2, string message, 
                object[] parms );

次に示すメソッド群は、一方のobjectが他方のobjectより小さいか等しいことをテストします。

Assert.LessOrEqual( int arg1, int arg2 );
Assert.LessOrEqual( int arg1, int arg2, string message );
Assert.LessOrEqual( int arg1, int arg2, string message, 
                object[] parms );
				
// (訳者:中略します。各値型のために比較アサーションメソッドが用意されています。)
				
Assert.LessOrEqual( IComparable arg1, IComparable arg2 );
Assert.LessOrEqual( IComparable arg1, IComparable arg2, string message );
Assert.LessOrEqual( IComparable arg1, IComparable arg2, string message, 
                object[] parms );

******************************

NUnitことはじめ (2)」に続く──

*1:訳者:.NETフレームワークが提供するGUIアプリAPIのことです。

*2:訳者:C#では多次元配列は、入れ子配列とは異なります。Javaでは多次元配列は配列の配列として表現されますが、C#では多次元配列(矩形配列)と、配列への参照を要素とする配列であるジャグ配列の2種類があります。