スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門 ツール編  その1 xUnit.net(1)

関数等やクラスなどの様々な要素(ユニット)をテストするテスティングフレームワークの一つであるxUnit.netを紹介します。
 
このようなフレームワークは色々提供されていて、他にもNUintやMSTest等があります。
http://xunit.codeplex.com/wikipage?title=Comparisons&referringTitle=HomeにはxUnit.netとこれらの比較対象表が示されています。)
 
それではインストールですがhttp://xunit.codeplex.com/のHow Do I...?部分の「How do I install xUnit.net」の部分をクリックして、そのページのDownload the binaries for the 「latest release」のlatest release部分をクリックして移動した先のページのwunit-*.*.zipをダウンロードします。これを解凍したフォルダ内のファイルを使用します。
今回使用してみるのはxunit.dllとxunit.gui.exeです。
その前に解凍したxunit-1.5フォルダーを任意の場所に移動しておきます。(私はc:\Program Filesフォルダに移動しました。)
まずVisual Studio内のSolution Explorerの参照で、xunit.dllへの参照を追加しておきます。
(なお現時点(2010.5.28)でxunit1.5は.NET 4.0 には一部非対応ですので、.NET 3.5をターゲットにして作成しています。)
 
次にALT+ControlでF#Interactiveにソースコードを送ったときに、F# Interactiveにもxunit.dllの参照が追加されるようにソースの先頭に対のように入力しておきます。
 
#if INTERACTIVE
#r @"c:\Program Files\xUnit-1.5\xunit.dll"
#endif
open Xunit
 
これだけ選択してalt+returnでF#Interactiveに送ると、次のように表示されます。

--> Referenced 'c:\Program Files\xUnit-1.5\xunit.dll'
 
それでは、ソースコード入力部分で、Xunit.とタイプするとその後の候補が一覧で現れるはずです。
ではAssertを選択しXunit.Assert.の状態にします。次の選択候補が現れますのでまずはEqualを選択します。
ではXunit.Assert.Equal(3,1+2)としてこれをF# Interactiveに送ってみます。
これは「3と1+2が等しいかどうか確認しなさい」という意味になります。
F# Interactiveでは
Binding session to 'c:\Program Files\xUnit-1.5\xunit.dll'...
val it : unit = ()
と表示されます。
ということで確認できればunitが返されます。
 
では次にXunit.Assert.Equal(3,1+5)を送ってみます。

Xunit.Sdk.EqualException: Assert.Equal() Failure
Expected: 3
Actual:   6
   at Xunit.Assert.Equal[T](T expected, T actual, IComparer`1 comparer)
   at <StartupCode$FSI_0004>.$FSI_0004.main@()
Stopped due to error
このように失敗すると例外が投げられます。 
 
次に予想された例外が投げられるかどうかを確認してみます。
 
> let div (x,y) =
    x/y;;
 
val div : int * int -> int
 
> Xunit.Assert.Throws<System.Exception>(Xunit.Assert.ThrowsDelegate(fun x -> div(5,0)|>ignore));;
> Xunit.Sdk.ThrowsException: Assert.Throws() Failure
Expected: System.Exception
Actual:   System.DivideByZeroException: Attempted to divide by zero.
   at Xunit.Assert.Throws(Type exceptionType, ThrowsDelegate testCode)
   at Xunit.Assert.Throws[T](ThrowsDelegate testCode)
   at <StartupCode$FSI_0008>.$FSI_0008.main@()
Stopped due to error
 
ということでSystem.Exceptionを期待したのに、実際にはSystem.DivideByZeroExceptionが投げられて失敗です。
成功するようにしてみます。
 
> Xunit.Assert.Throws<System.DivideByZeroException>(Xunit.Assert.ThrowsDelegate(fun x -> div(5,0)|>ignore));;
>
val it : System.DivideByZeroException =
  System.DivideByZeroException: Attempted to divide by zero.
   at FSI_0009.it@7-1.Invoke()
   at Xunit.Record.Exception(ThrowsDelegate code)
    {Data = dict [];
     HelpLink = null;
     InnerException = null;
     Message = "Attempted to divide by zero.";
     Source = "FSI-ASSEMBLY";
     StackTrace = "   at FSI_0009.it@7-1.Invoke()
   at Xunit.Record.Exception(ThrowsDelegate code)";
     TargetSite = Void Invoke();}
>
ある範囲内にあるかどうかはInRangeを使います。
>  Xunit.Assert.InRange(4+1,3,7);;//4+1が3と7の間にあるか?
val it : unit = ()
 
大小関係等についてはAssert.Trueが利用できます。
> Xunit.Assert.True(3<7);;
val it : unit = ()
 
> Xunit.Assert.Empty([]);;
> val it : unit = ()
 
では、関数を定義とそれのテストをF# Interactiveを利用して実際におこなってみます。
 
#if INTERACTIVE
#r @"c:\Program Files\xUnit-1.5\xunit.dll"
#endif
open Xunit
 
//テスト対象の関数 lst内でlowとhighの間にある値を抜き出す
let extractBetween low high lst =
    lst |> List.filter(fun x -> low < x && x < high)
 
 
//テスト用関数
let test1()=
     Xunit.Assert.Equal([3],extractBetween 2 4 [-1;2;3;5]) //成功のはず
let test2() =
    Xunit.Assert.Empty(extractBetween 1 3 [2;4]) // 失敗するはず
 
//テストの実行
test1()
test2()
 
全部選択してalt+returnでF#Interaciveに送ると次のようになります。
 
>
 
--> Referenced 'c:\Program Files\xUnit-1.5\xunit.dll'
 
Binding session to 'c:\Program Files\xUnit-1.5\xunit.dll'...
Xunit.Sdk.EmptyException: Assert.Empty() failure
   at Xunit.Assert.Empty(IEnumerable collection)
   at FSI_0002.test2() in C:\Users\T_GYOUTEN\documents\visual studio 10\Projects\ForBlog\ForBlog\program.fs:line 14
   at <StartupCode$FSI_0002>.$FSI_0002.main@() in C:\Users\T_GYOUTEN\documents\visual studio 10\Projects\ForBlog\ForBlog\program.fs:line 17
Stopped due to error
 
ちゃんとtest2で例外が発生しています。
 
なおXunit.Assert...と書いてますが、open XunitとしているのでXunitは不要です。
 
また
//テスト用関数
let test1()=
     Xunit.Assert.Equal([3],extractBetween 2 4 [-1;2;3;5]) 
     Xunit.Assert.Empty(extractBetween 1 3 [0;4]) 
//テストの実行
test1()
 
としてテストをまとめてしまってもよろしいかと思います。
 
最後にヘルプの見かたを紹介しておきます。
ヘルプのchmファイルもxunit-1.5.zipをダウンロードしたページにxunit-1.5.chmという形であるので、これをダウンロードします。適当なフォルダに保存したら、エクスポローラーで右クリックして、プロパティを表示し、全般タブの「ブロックの解除」ボタンを押して適用しておきます。
これでヘルプが見れるようになります。(残念ながら、英語な上にC#,Visual Basicの例しかのってません)
 
今回はF#Interactiveを利用してちょっとしたテストを書いてみましたが、次回はDLLもしくはEXEを対象にしたテストの作り方を紹介したいと思います。
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。