F#のコードをユニットテストで検証する その2(xUnit)
xUnit.net を利用してVisual Studio 2013のテストエクスプローラーでユニットテストを実行してみます。
その準備として以下の xUnit.net および xUnit.net テストランナーの NuGet パッケージをプロジェクトにインストールします。
NuGet パッケージ管理画面からインストール
xUnit.net を利用したコードの例
- module Sample1
- open Xunit
- let countWordsInStr (str: string) : int =
- let clist: char list = [ for c in str -> c ] // stringをcharの配列に変換
- let rec inWord (curList: char list) (count: int) : int =
- match curList with
- | [(**)] -> count
- | hd::tl when hd = ' ' -> inSpace tl count
- | _::tl -> inWord tl count
- and inSpace (curList: char list) (count: int) : int=
- match curList with
- | [(**)] -> count
- | hd::tl when hd = ' ' -> inSpace tl count
- | _::tl -> inWord tl (count + 1) // 空白→文字の遷移でインクリメント
- inSpace clist 0
- [<Fact>]
- let ``Word Count - Part0``() =
- Assert.Equal(0, countWordsInStr " ")
- [<Fact>]
- let ``Word Count - Part1``() =
- Assert.Equal(1, countWordsInStr " aaa")
- [<Fact>]
- let ``Word Count - Part2``() =
- Assert.Equal(2, countWordsInStr "aaa bbbb")
- [<Fact>]
- let ``Word Count - Part3``() =
- Assert.Equal(3, countWordsInStr "aaa bbbb ccccccc ")
- [<Fact>]
- let ``Word Count - Part4``() =
- Assert.Equal(4, countWordsInStr "a b c d")
4行目の countWordsInStr がテスト対象となる関数です。引数で与えられた文字列に含まれている単語数を数えます。ここではホワイトスペースのみを区切り文字として認識するように書いています。
6~15行目はこの関数内で使用するローカル関数です。let rec...and...の構文使って相互再帰(mutual recursion)する関数を2つ定義しています。16行目でこのローカル関数を使ってcountWordsInStr の戻り値を作り、そのまま返しています。
18行目以降の5つの関数がテスト用関数の定義になります。Factアトリビュートを付加した関数がテストランナーによって実行されます。xUnit の Assert.Equal メソッドで引数に渡された二つの値が等しいかを検査しています。
注)8行目・13行目にある(**)はF#用コメントです。はてなブログでは角括弧が消えてしまうことがあるのでその対策として入れてあります。
Visual Studio2013のテストエクスプローラーの実行結果