Delphi で BDD やってみた(仮)
Rad Studio 勉強会にて発表してた内容の本編+補足です。
なんで BDD?
DUnit つかってテスト書いてるんですが、なーんか冗長的で。
コードの圧縮を図るんですが、テストコードの可読性やらがという本末転倒ぶり。
そもそも全部に対してこんなに細かくいんのかっちゅう話なわけで、
もうちょい大きい粒度で確認したいってことで
BDD (正確には Spec 系) フレームワークが無いかぁ・・・と探したわけです。
んで、ありました。
DelphiSpec
わりとそのまんま。
使っている技術は DUnitX と同じ Attribute ですが、
テストシナリオが完全に外だしになってるのがなかなかすごい!
構成
フレームワーク本体を除いたファイルの種類は、大きく3つに分かれます。
- 実行コード本体
- シナリオ
- シナリオ実行コード
実行コードはおいといて、シナリオから。
シナリオ
BDD にそった形式で書かれてます。
まず機能があって次にScenario があり、
Given があり、And、Then、When と続くかんじです。
今回だと、こんな感じ。
- 機能:アカウント
前提条件
以下のユーザーが存在している。id user password 1 Roman pass1 2 Other pass2 - シナリオ:正規ユーザー
- 私のユーザー名は Roman です。
- 私のパスワードは pass1 です。
- 私はログインを試みました。
- 私は私のプライベートメッセージを閲覧できます。
- シナリオ:不正ユーザー
- 略
- シナリオ:削除済みユーザー
- 略
シナリオ実行コード
シナリオと関数の対応、仮引数への値渡しのルール定義をやってます。
で、対応づけられたルールにそって、シナリオが実行されます。
ルールが無かった場合、わけ分からんシナリオいれんじゃあない! って怒られます。
Attribute なしでも OK。
シナリオの文字列と関数名を一致させれば良い感じ。
テスト実行時の動き
実行ファイルは指定されたフォルダ内のシナリオを読み込み、
Attribute や関数名と照らし合わせて、シナリオの実行手順を構築する。
テストの実行ボタンをおせば、実行開始時に読み込んだシナリオにそってテストが行われる、って順序です。
実際試してみて
よかったところ
テストシナリオの完全分離
間違いなく読みやすい。
何をやりたいか、何を見たいかが明確なので楽。
上記で紹介したアカウントの例で話すと、
パスワードの文字列パターンの対応とかも前提条件と
シナリオを書けば実行ファイルを作り直さなくてもいける。パターンがかきやすかった
すっげーしょぼいサンプルではありましたが。
一回シナリオ実行コードを書き上げた後の、
パターン書き出しのやりやすさったらなかった。
ちょいつらかったとこ
型変換
これはぼくの書き方が悪かったが、Attribute で暗黙的に変換出来る型と
出来ない型、出来てもサポートしない型*1があったりしました。UTF-8 の日本語を読んでくれない
うん、分かる。英語でかけってことでしょ。わかる。
ただ、このシナリオの使いどころを考えると、読む人がエンジニアじゃあない場合もあるかなぁと。 一応 S-JIS ならいけました。
かいてて
そもそも、DUnit と Jenkins と CodeCoverage の方を書かないと色々伝わらなそう・・・。
次はそっちかきます。
おまけ
日本語対応したので、そのうちPR。
*1:だってそう書かれてたし・・・