kazokmr's Blog

試したこと、読んだこと、見たこと、聴いたことを書きたくなったら書くブログ

BDD in Action 2nd Edition 第8章メモ

第8章を読みました。この本の目次を見ると付録を除いて全15章となっているので、折り返し地点です。 現時点で9章はまだ公開されていませんが。

www.manning.com

kazokmr.hatenablog.com

8章もCucumberでテストを書くときのテクニックの説明です。
読みやすく、メンテナンスしやすく、信頼性が高いテストコードを書くために、レイヤー構造の概念を用いています。

この章のボリュームは他と比べると多くはありませんが、Cucumberを用いた 振る舞い の一部がよくわかるような内容だと思います。

レイヤー構造でテストを書く

ここで説明しているレイヤーは大きく次の3つに分かれ、上からピラミッド型で表されていました。

  1. ビジネスルール・レイヤー : フィーチャーファイルやシナリオ

  2. ビジネスフロー・レイヤー : グルーコード

  3. テクニカル・レイヤー : 実際にテスト対象アプリのUIを操作したり、REST API を送信するコード

これは「テストピラミッド」の最上位に当たる UIテスト の三角形の中を分解しているように思えた。
(図を見せて説明できないので、イメージしづらいですが。)

ビジネスルール・レイヤー

これまでの章で見てきた、Gherkin形式で書かれたシナリオを指す。
何をテストするのか、あるいは、何を期待しているのかを ビジネス側のユーザーがわかる用語や表現で記述した物。

シナリオの内容は、ここまでに行ったアクションで、ビジネス側と合意が取れているはずなので、Cucumberのテスト結果から、アプリケーションがシナリオを満たしているかどうかが把握できる。

ビジネスフロー・レイヤー

前の7章で出てきた、シナリオとCucumberでのテストをつなぐ、ステップ定義ファイルを指す。
ここで Given, When, Then の各ステップごとに定義メソッドで、受け入れテストのための準備、実行、検証を行う。

このレイヤーのポイントは ユースケース図のように アクターやアクターが操作するモノをオブジェクト化して、振る舞いを表現すること。 だと感じた。

どういうことかというと、テストコード上に アクターそのもの、そのアクターが操作するクライアントツール(WebアプリのUIならブラウザ)などを テスト専用のクラスとして定義しオブジェクトにすることで、グルーコードの中で、実際に振る舞いを表現して、シナリオを実演することができる。

つまり、テスト対象アプリケーションを利用する現実世界をモデリングして、グルーコードでシナリオを表現できるようにする。

  1. 「アクターは、ブラウザで、○○ページを開く」

  2. 「アクターは、ブラウザで、テキストに ***と入力する」

  3. 「アクターは、ブラウザで、送信ボタンをクリックする」

  4. 「ブラウザに・・・・・と出力される。」
    -> この出力内容がシナリオで期待値と合っているか検証する

グルーコードで表現するオブジェクトは、抽象的に書くことが望ましい。
そうすることで、オブジェクトの汎用性、再利用性を高め、アプリケーションを変更した時の影響を小さくすることができる。

テクニカル・レイヤー

上位のビジネスフロー・レイヤー (グルーコード)で、定義した振る舞いから、テスト対象アプリケーションのUI、あるいはREST APIなどの操作を行う。

本の中ではこのレイヤーの中も2つのレイヤーに分かれていて、上位の方は ページ、テキスト、ボタンのような抽象的なオブジェクトを用意して表現し、下位のレイヤーでそれらのオブジェクトがUI上で、どこに配置され、id属性やname属性などのプロパティを具象化する。

レイヤー化のメリット

このようにCucumberのテストコードをレイヤー構造にすることで次のようなメリットがあると思った。

変更に強い

アプリケーションの変更がどのような内容かによって、修正が必要なテストコードの影響範囲を小さくできる。

例えば、ビジネスの要件は変わらず、UI のレイアウト や REST APIのパラメータ名称だけが 変わるだけなら、最下層のレイヤーだけを修正すればいいかもしれない。

または、アクターとして表現するべき登場人物が増えるのなら、アクターのオブジェクトの種類を増やし、その分だけきぞんのテストの実行を追加するだけで良いかもしれない。

再利用しやすい

新しいビジネス要件を実装する際に、作成済みのアクターなどのオブジェクトを流用して、シナリオを具現化しやすくなる。

アプリケーションのUIが作られる前に、テストコードが書き始められる

シナリオはもちろんグルーコードやテクニカルレイヤーの一部は、アプリケーションのUIの詳細情報と疎結になるので、UIを作る前からテストを書き始めることができる。
これは、受け入れテストやエンドツーエンドテストの早期実行に繋げることができると思う。

ペルソナを使う

前述のアクターについて、TypeSafe Config ライブラリ を用いて、HOCON形式で作成した属性情報を取り込み、ペルソナとして具象化する方法が紹介されていた。

TypeSafe Config や HOCONファイルは使ったことないけど、本文中のサンプルを見る限り、単純なプロパティを羅列化したオブジェクトを用意したい場合に便利そうだと思った。

GitHub - lightbend/config: configuration library for JVM languages using HOCON files

所感

BDDやCucumberがカバーしているのは、シナリオを用いた受け入れテストやエンドツーエンドテストになるからか、テストコードを手続き的に書いてしまうことが多い。
これだと、コードが長くなって読みづらくなったり、テスト対象アプリケーションへの依存度が高くなりがちなので、レイヤー構造を採用することで、そういった欠点が解消できそうだと思った。

テストコードで書くことが、テスト対象システムの外側、つまり実際にシステムを使うユーザー自身やユーザーの振る舞い、システムのインターフェースに対する操作である点に「振る舞い駆動開発」と呼ばれる理由の1つを見た気がした。

テストコードの中で、アプリケーションを利用する現実世界を表現して書くのは、正にユースケース図の振る舞いのイメージに重なると感じた。

またこの方法だとプロダクトコードと並行してテストコードが書けることが多いので、受け入れテストの早期実行が実現できる。という点にとても共感できた。

このようなユーザー(文章中だとアクター)中心のコーディングスタイルを「スクリーンプレイ」と呼ぶそうで、これは著者が開発している、Serenityにも取り入れられている。スクリーンプレイの詳細は今後公開される章で説明があるようなので楽しみ。だけど、いつ公開されるのかな??