スポンサーサイト

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

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

 さて前回はF# Interactiveを使って、手軽なテストをしてみましたが、今回はDLLファイル等を作成して、それに対してテストするという方法を紹介したいと思います。

テスト部分は、テスト対象の関数が定義されているファイルと(1)同一ファイル内(2)同一プロジェクトで違うファイル内(3)異なるプロジェクト(4)異なるソリューションというように色々選べるのですが、今回は「同一ファイル内の場合」を紹介します。


まずテスト部分は他の部分と分離した方がよいので、別モジュールでくるみます。
そしてunit->unit型のテスト用関数を書くのですが、其々のテスト用関数の先頭に[<Fact>]アトリビュートを付け加えます。たとえば次のようになります。

module module01

//今回は次の3行は特に必要なし
#if INTERACTIVE
#r @"c:\Program Files\xUnit-1.5\xunit.dll"
#endif

open Xunit

//テスト対象の関数
let extractBetween low high lst =
    lst |> List.filter(fun x -> low < x && x < high)


//テスト用関数

module MyTest00 =
   [<Fact>]
   let test1()=
     Xunit.Assert.Equal([3],extractBetween 2 4 [-1;2;3;5])

   [<Fact>]
   let test2() =
     Xunit.Assert.Empty(extractBetween 1 3 [0;4])

これでビルドしてdllファイルを作っておきます。(実行ファイルの場合はExeファイルになります。)

さて、テストを行うには、コマンドプロンプトでxuint-1.5フォルダ内にあるxunit.console.exeを使って、
xunit.console ファイル名と打ち込み実行する方法と、xuint.gui.exeを利用して、アプリケーション上で行う方法があります。(visual studio 2008ではxunit.installer.exeを実行することによってTestDriven.NETも利用できるようですが、未確認です。)
今回はxuint.gui.exeを利用してみます。
xunit.gui.exeをダブルクリックするとウィンドウが開きます。


xunit00.jpg 

Assenblyメニューからopenでコンパイルされたファイル(dllまたはEXE)を指定します。

これで左下のRun Allボタンを実行すると、テスト結果が表示されます。

xunit01.jpg

(異なるファイル、プロジェクトにテスト部分を置く場合も、テストする関数を含むモジュール、プロジェクトへの参照を、テスト側から設定して置いてから、テストの方をコンパイルし、その結果のDLLファイル等を読み込んでRun Allするだけです。)


次にアトリビュートの使い方の例を二つほど挙げておきます。
まず、テストをスキップする方法です。

関数test1()の上のアトリビュート部分を次のように変えておきます。

   [<Fact(Skip="今回はテストしない")>]
   let test1()=
     Xunit.Assert.Equal([3],extractBetween 2 4 [-1;2;3;5])

このようにしてRun Allボタンを押すと、OutPut部分には次のように表示されます。

module01+MyTest00.test1 : 今回はテストしない

次に関数の実行時間にタイムアウトを設定する方法です。

関数test1()を次のように変えておきます。

   [<Fact(Timeout=100)>]
   let test1()=
     System.Threading.Thread.Sleep(200);
     Xunit.Assert.Equal([3],extractBetween 2 4 [-1;2;3;5])

このようにしてRun Allボタンを押すと、OutPut部分には次のように表示されます。

module01+MyTest00.test1 : Test execution time exceeded: 100ms

スポンサーサイト

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ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。