シンタックスから NaturalSpec を理解する
テスティングフレームワークのうち、BDD 向けに作成されたものは、スペックをリーダブルにするためのシンタックスを提供しています。NaturalSpec からもいくつかのシンタックスが提供されています。これらの使い方を知ることで、NaturalSpec に親しみ、読みやすいスペックを素早く作成する力を養うことができると個人的には考えています(英語力もあるとなお良い)。
AAA (Arrange-Act-Assert) パターン
Given
- シグネチャ
- 'a -> 'a
- 解説
- テストコンテキスト(テスト対象オブジェクト)を使用してテストを開始することを表します。英語では Given を接続詞的に使用すると、「...を仮定すれば」という意味になります。Given が関数として実行された時間から、テストにかかった時間が計測されます。
As
- シグネチャ
- 'a -> 'a
- 解説
- Given と名称が異なるのみで、機能は同じシンタックスです。表現したい仕様に合わせて選択するのがいいと思います。何かパラメーターを与えるときは Given で、テストコンテキストを○○として扱う、といったときは As を選ぶとか。
When
- シグネチャ
- 'a -> 'a
- 解説
- AAA パターンの Act フェーズで使用します。
It
- シグネチャ
- 'a -> 'a
- 解説
- AAA パターンの Assert フェーズで使用します。大文字で始まるシンタックスは、出力結果を改行します。
Whereas
- シグネチャ
- 'a -> 'b -> 'a
- 解説
- AAA パターンの Assert フェーズで使用します。whereas は 2つのものを比較するときに用いられる接続詞。 Whereas シンタックスは 'a 型の引数と 'b 型の引数を受け取って 'a 型の値を返す関数として実装されていますが、'b 型の引数は使用されず、1番目の 'a 型の引数が戻り値として返されます。
equal
- シグネチャ
- 'a -> 'a -> AssertType * 'a * 'a * 'a
- 解説
- 2つの値が等しいかどうかをテストするようにスペックを構築します。should や should'nt と合わせて使用します。
be
- シグネチャ
- ('a -> bool) -> 'a -> AssertType * bool * bool * 'a
- 解説
- 'a 型の値を受け取って bool を返す関数を使用して、結果が true になるかどうかをテストするようにスペックを構築します。 should や should'nt と合わせて使用します。
have
- シグネチャ
- ('a -> bool) -> 'a -> AssertType * bool * bool * 'a
- 解説
- be と名称が異なるのみで、機能は同じシンタックスです。表現したい仕様に合わせて選択するのがいいと思います。
should
- シグネチャ
- ('a -> 'b -> AssertType * 'c * 'd * 'e) -> 'a -> 'b -> 'e
- 解説
- equal、be、have のいずれかと期待値、テストする値を受け取って、期待値通りであることをテストします。
shouldn't
- シグネチャ
- ('a -> 'b -> AssertType * 'c * 'd * 'e) -> 'a -> 'b -> 'e
- 解説
- should の否定であり、結果が期待値とは異なることをテストします。
Verify
- シグネチャ
- 'a -> unit
- 解説
- スペックを検証します。テストがすべて OK なら、出力結果に "OK" を追加します。NG の場合は例外を発生させます。Verify はスペックの最後に記述します。
流動的なヘルパー
castingAs
- シグネチャ
- obj -> 'a
- 解説
- obj 型の引数を 'a 型に変換します。また、出力結果に "casting as 型名" を追加します。
doing
- シグネチャ
- 'a -> 'a
- 解説
- 出力結果に "doing" を追加します。
getting
- シグネチャ
- 'a -> 'a
- 解説
- 出力結果に "getting" を追加します。
nothing
- シグネチャ
- 'a -> 'a
- 解説
- 出力結果に "nothing" を追加します。
solving
- シグネチャ
- 'a -> 'a
- 解説
- 出力結果に "nothing" を追加します。
その他
toSpec
- シグネチャ
- string -> unit
- 解説
- 出力結果に任意の文字列を追加します。関数を BDD スタイルで記述する場合に、副作用として toSpec 関数を呼び出し、出力結果に追加したい文字列を指定してください。
改訂履歴
2013/01/04 Given の説明に英語での意味を追加。
NaturalSpec チュートリアル翻訳版
F# のテスティングフレームワークの一つである NaturalSpec のチュートリアルを翻訳しました。原文のチュートリアルは NaturalSpec の作者である Steffen Forkmann 氏によって書かれています。
- テストのためのドメイン特化言語(DSL) - NaturalSpec の手引き
- NaturalSpec 入門
- NaturalSpec を使用して C# プロジェクトのスペックを生成する
- NaturalSpec とモックオブジェクト
- NaturalSpec を使用したパラメータ化されたシナリオ
- クイックソートを NaturalSpec でテストする
翻訳にあたり、チュートリアルのライセンスを確認し承諾を得ました。
@smallgeek Blog has no license. Just translate it.
— Steffen Forkmannさん (@sforkmann) 8月 8, 2012
原文のライセンスに従い、翻訳版のチュートリアルにもライセンスはありません。原文の著作権は Steffen Forkmann 氏に帰属しています。
また、原文から一部変更した部分があります。
- ソースコードが古かったため、最新版の NaturalSpec に対応
- 一部のリンク先を日本語のページに変更
- 実行環境を VS2008 から VS2010 に変更
私個人で NaturalSpec を使用するために翻訳をしていましたが、需要が少しでもあればと公開するに至りました。技術的な文献の翻訳はこれが初となりますので、読みにくい部分や間違った訳出をしている部分があるかもしれません。誤訳など、お気づきの点があれば、 @smallgeek までご連絡ください。
翻訳にあたり、公開のきっかけをくださった @bleis さん、FParsec チュートリアルの訳者であり、翻訳の相談に乗ってくださった @gab_km さんにお礼を申し上げます。
改訂履歴
2012/09/11 一部原文が残っていたため削除
クイックソートを NaturalSpec でテストする
前回の記事では NaturalSpec でパラメータ化されたシナリオを使用する2つの方法を示した。今回は小さなクイックソート関数を例に、2つを組み合わせてテストする方法を示す。
初めに、ソート用のシナリオを定義する。
次に、具体的なテストケースを定義する。
スペックを定義した後にすべきことは、ソート関数を実装することだ。私は F# で、非常に短い(それでいて、非常に単純な)クイックソートを実装した。
シナリオを実行すると、次のように出力される(ビットは省略)
ご覧のように、この関数はランダムなリストをソートしたとき、はるかに高速だ。ピボット要素の選択が非常に単純だからだ。
これは良い実装ではない(LINQ や PLINQ を使ってほしい)。ここでは、NaturalSpecを使用すれば、テスト関数を簡単に検証できることを示したかっただけだ。