何かで書いて、次のようにアノテーションをつける。テストからは次のように使えるようになる。指定すると、指定したパッケージ以下(カンマ区切りで複数指定できる)から変換メソッドを見つけてくれる。アノテーションをつける。テスト内容にかからわず常にこの不変条件をチェックし、満たされないとテストが失敗するようになる。オプションを指定する。スタブ作成のための文法を提供する。一般的には次の形式をとり、式が現れる場所に置かれる。getメソッドに対して42を返却するスタブは次のように書く。42テスト全体としてはたとえばこのように書ける。`java.util.Collections.unmodifiableMap(map)`.こうした記述はMockitoのメソッドを呼ぶようなバイトコードにコンパイルされる。どのように発展させるか(させないか)は模索している段階にある。ある程度高機能なスタブを作るための表記は結局のところある種のプログラミング言語になる。スタブ/モック用の言語を使う利点があるスイートスポットは(もしあるとしたら)どの位の用途なのか。自然言語として読み下せることはスタブ/モックにとってどの程度重要なのだろうか。Mociktoを使用する必然性も実はあまりないかもしれない。4フェーズテストを書く方法を取り上げる。事前準備(setup)、実行(exercise)、検証(verify)、事後処理(teardown)からなる。YokohamaUnitでは見出しをつかってそれぞれのフェーズを表す。`1`.Setupでは主にLet文を使って変数の束縛を行う。Let文は複数並べてもよいし、andでつなげてもよい。2.beでなく=でもよい。2.ExerciseではDo文を使ってテスト対象のメソッドの実行を行う。Do文は式言語の(副作用を起こすことが期待される)式をとる。これも複数並べてもよいし、andでつなげてもよい。allを使った場合の実行単位が異なる。1つのメソッドの中で続けて実行されるようなコードにコンパイルされる。4フェーズテストをパラメタ化する方法については別の記事で紹介する。次の例はTeardownフェーズを含むテストの例である。Teardownフェーズの中でもExerciseフェーズと同様、Do文を使う。`temp.delete()`.Teardownフェーズはテストの成否にかかわらず必ず実行される。Groovy式の中では当然Groovyのリテラルが使える。リストのリテラルなどはJavaにはないリテラルだ。"c"]`.文字列などの基本的なリテラルもGroovyのものを利用できる。`"hello"`.しかしこのようにバッククォートとダブルクォートを重ねて書くのはうるさいと感じるかもしれない。そこでYokohamaUnitは基本型については独自にリテラルを用意している。"hello".YokohamaUnitの基本型リテラルはほとんど厳密にJavaの基本型リテラルを踏襲している。GroovyはおおむねJavaを踏襲しているが、違いに注意しなければならない点もある。シングルクォートはGroovyでは文字ではなく文字列として解釈される。普通に使う範囲で注意するのは文字リテラルくらいだろう。Javaになく、YokohamaUnitにあるリテラルとして複数行文字列リテラルがある。複数行文字列リテラルは見出しの後にバッククォート3つ(から5つ)で囲んで定義する。使用する際はその見出しを使って参照する。この識別子を使って改行コードや文字列末尾に改行が付くかどうかを制御することができる。lfという識別子を置くと改行コードがLFになる。lfa```この例でtextという識別子に特に意味はなく、無視される。crlfという識別子を置くと改行コードがCRLFになる。crlfa```chopという識別子を置くと末尾の改行コードが付かなくなる。任意のオブジェクトに変換できる。これは複雑なテストデータの準備に活用できる。YokohamaUnit自身のテストコードから例を示す。文字列Sourceが次のように定義されているとする。true.```テストデータとしてはこれを文字列ではなくASTデータ型であるGroupオブジェクトに変換したい。そこでSourceを参照する箇所では次のように書く。そのクラスの中から「文字列を引数として取り、Groupを戻すメソッド」を探す。}}そしてそのメソッドを使ってデータ変換を行うようなバイトコードを生成する。変換を行うメソッドが定義されたクラスはテストコンパイル時とテスト実行時の両方でクラスパス中になければならない。テストデータを表に抽出することができる。endsWith]表のキャプションは表の前でもよい。|JUnitのTheoryとの大きな違いだが、表の1行が1つのテストメソッドとなる。上記のような記述の場合、テストメソッドは3つできる。テストケース数も3件と数えられる。テストデータをCSVファイルやExcelに書くこともできる。テストコードのコンパイル時に行われ、やはり1行が1つのテストメソッドとなる。[YokohamaUnit]YokohamaUnitでは1つのソースファイルが1つのJUnitテストクラスにコンパイルされる。ソースファイルの標準的な拡張子はdocyである。そのテストの名前を示す見出しを書く。Javaのメソッド名の規約の制約を受けない。最初のハッシュ記号は上の例では1つだが、1つから6つまでの任意の数でよい。「4フェーズテスト」の2つに分けられる。今回は前者を取り上げる。関数的なメソッドとはその結果が引数の値のみによって決定されるメソッドである。そのようなメソッドはもっともテストがしやすい。関数的なメソッドをテストするためのAssert文は見出しに続けて直接書くことができる。123.thatは省略してもよい。テスト対象のメソッドである。Groovyの式として解釈される。Assert文は1つの見出しの下に複数続けて記述しても構わない。123.この場合それぞれのAssert文に対して別々のJUnitテストメソッドが生成される。したがって一方が失敗してももう一方のテストは実行されるし、2ケースとカウントされる。次のように書いた場合は1つのメソッドのみが生成される。123.例外の送出をテストしたい場合は次のように書く。`NumberFormatException`.例外を送出しないということをあえてテストとして書きたい場合は次のように書く。nothing.Assert文の副文の主語にあたる部分が長くなると読みにくくなることがある。そのような場合、where句を使って変数を導入することができる。"honorificabilitudinitatibus".isの代わりに=を使ってもよい。"honorificabilitudinitatibus".複数の変数を導入することもできる。いったほうがいいかもしれない。不変なフィールドを初期化するコンストラクタ引数にも依存してよい。[YokohamaUnit]プログラムの単体テスト(自動実行されるテストコード)は普通テスト対象となるプログラムと同じ言語で書かれる。当たり前のようだが必然的にそうでなければならないということではない。「その言語Aの関数やメソッドの呼び出し規約に従ってリンクできる」ということだけだ。理論上はC言語の単体テストをSML#で書いたって構わないはずだ。自明にリンクできる開発者自身が単体テストを書くことが多いといった理由によるだろう。した単体テストはある種の内部DSLとして書かれる。「テストの意図をそれにふさわしい見え方で表現したもの」として見えてほしいからだ。JavaのJUnitであれば、下記のような書き方をする。いう英語の文として読み下すことができるので可読性が高いと言われている。このような考え方はしばしば「ドキュメントとしてのテスト」といわれる。ところで上記のJUnitの文は詳しく見てみると「2つのレベル」がある。「テスト対象の呼び出し」に属する部分と「ドキュメント」に属する部分だ。部分だけは(いわば直接話法のように)そのまま残していた。この箇所は英文としてそのまま読み下すことができない。ドキュメントの文法(疑似英語)でなく対象プログラムの文法に属するとみなすことは自然である。以外の部分は「ドキュメント」に属するレベルである。(123がどちらに属するかについては微妙な点だ)このドキュメントの部分は「自然」だろうか。assertとThatの間に空白がなく、ThatのTだけが大文字なのだろうか。isの前にカンマが来て後に括弧が来るのはなぜだろうか。その答えはドキュメントのレベルをJavaの内部DSLで記述しているからだ。Javaの単体テストをJavaで書いているのかを振り返ってみよう。それはテスト対象とのリンク要件を容易に満たせるからだった。「ドキュメント」のレベルは別にそうではない。いう考えが浮かび上がってくる。テスト対象とリンクするバイナリにコンパイルされるだろう。そのようなJava向けの単体テストフレームワークである。「テスト対象の呼び出し」の部分にはGroovyを使う。テストコードは直接JUnitのクラスファイルにコンパイルされる。次のコードはYokohamaUnitのテストコードとして妥当なものの例である。|[1]外部DSLの選択は文法の不自然さ以外にもいくつかの内部DSLの制約を解消しうる。(JUnitにおける)例外のテストやパラメタ化テストの問題などである。次の記事からYokohamaUnitの機能を紹介していきたい。脱線になるが、結合のレベルが上がるほどこの要件は緩和される。コマンドのテストで求められるのは、コマンドライン呼び出しができることだけだ。テスト対象がTclで書かれていなければならないということはない。サービス側の実装言語にほとんど左右されないだろう。(..単体テストのための外部DSLカテゴリーOCaml(62)Tcl(27)D言語(5)COM(1)PowerShell(9)JavaScript(5)Linux(2)Lua(19)XSLT(1)Lisp(32)Excel(2)コードリーディング(4)Ruby(9)言語比較(7)Haskell(6)Groovy(1)PHP(10)Scala(48)Perl(2)Erlang(4)Python(2)Prolog(8)Java(8)自然言語(1)awk(1)SML(19)sh(2)SMV(1)YokohamaUnit(8)Rehearsal(1)Isabelle(1)最近のコメント不本意というよりは意外、というのが..ご案内ありがとうございます。..ご紹介&コメントありがとうございま..OCaml3.11のCamlp4か..エラー出た時はここが参考になりまし..コメントありがとうございます。SML#のバグ報..コメントありがとうございます。ソネットポイントこの広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。この広告は180日新規投稿のないブログに表示されます。