UnitTest 違和感のない文章をテストケースに落とし込んでから実装するよ!

昨日はFeatureSpec/FeatureSpecTestの話を書いたので今日はその続き。
テスト呑み。SpecTest。思ってたんと違う!をふせぎたい。 - Mitsuyuki.Shiiba

ざっくり書いてしまおう。

ドキュメント周り

ドキュメントは、最初から完成してることは全然なくて、作りながら書いて、書いては作って、最終的に、その機能をリリースするときに最後の仕上げをする感じ。

仕様系

名前 内容
FeatureSpec プロダクトオーナーチームが作る。実現させたい機能の概要が書いてある。
UISpec WebUIのドキュメント。FeatureSpecに入れると大きくなっちゃうので、切り出してるだけ。プロダクトオーナーチームが理解できる。
DevSpec 開発チーム用の詳細ドキュメント。例外時の動作とかそういうのも含めて。
OpsSpec 開発チームがこの機能を運用するときのためのドキュメント。例外でたときにできるだけ自動でリカバリしようとか、相手のシステムが落ちてても大丈夫なように作ろうとか。そういうの。

受け入れテスト系

名前 内容
FeatureSpecTest FeatureSpecが満たされていることを確認するテストのドキュメント。プロダクトオーナーチームの目線でのテスト。
UISpecTest UIの中で、プロダクトオーナーチームが気にしたい部分のテストドキュメント。というのも、細かい動きとかは別途Gebとかで書くので。

開発チームのテスト

受け入れテストはドキュメントを見せながら、一緒にアプリを触りながら、思ってたんと違う?とか言いながらやります。で、次は、開発チーム内のテストについての話。

UnitTest

僕のチームはDDDスタイルで開発してるのでこんなレイヤー構造。

  • Usecase Layer (Application Service)
  • Domain Layer
    • Entity / Value Object / Repository / Domain Service
  • Infrastructure Layer

Domain Layerは他のレイヤーには依存していないので、すごくテストが書きやすい。Repositoryはインターフェイスだけです。

Usecase LayerはRepositoryがDIされてて、そこからEntityを取得したり保存したりするので、単体テスト時はRepositoryのモックを使います。

Infrastructure LayerはDBとかメッセージングキューとか、そういうインフラに依存するので、ちょっとテストが重いです。スローテストになっちゃうので、テスト用のプロジェクトを別に作ってテスト流した方がいいなぁって最近思ってます。

TestFirst

ということで、UnitTestは他のレイヤーからは切り離してます。で、どうやって作ってるかってのですが。

DDDのユビキタス言語を定義して、まずはどんな機能を実現させたいかを、その言語を使って文章にします。で、その文章をレイヤーとかクラスに落とし込んでいきます。

そうすると、だいたいInput/Output/状態変化が見えてくるので、それを元にまずはペアでテストを書きます。

からの、実装。

そしてタイムアップ!