2016-07-16

Pact試してみた

あるいは Kanazawa.rb meetup #47 に参加してきたよの巻。

Swaggerに対するモヤモヤ

最近 Swagger を動かしたり していたんですが、まぁ確かに Swagger UI は Google API Explorer みたいで感動はするんですが、「いや、『仕様』を書きたいんじゃないんだ」という気持ちがどうもモヤモヤしてましてですね。というのも、API というのはあくまで外部とのインターフェイスで、実際にはそのインターフェイスを実現するためには中で涙ぐましい努力をしたりするわけじゃないですか。そう、シンクロナイズドスイミングみたいなアレです。

そんな気持ちもあって、Swagger ではなく Grape から入るということを前回はやっていたわけです。Swagger UI は「公開されている API のクライアントを書く際にチェック用のツールとしては優れている」けど、ここからコード生成してもなー、っていう。どうせ中の泥臭い部分はサーバを書く言語で書かなきゃいけないのなら、インターフェイス部分を書く手間を減らしてくれる Grape などの DSL からドキュメント起こす方がいいよな、と思うわけです。少なくともサーバを書くという部分においては。

※ いい具合に Facade なコードを作っておけばできなくはないかもしれないし、Grape の中に生々しくロジックが入りすぎていていいわけでもないですが。

同時に自分の中では「仕様を外部に公開するよりはオレはテストをしたいのだ」という気持ちがくすぶってくるわけです。ビビりなので。spec の validation ではなく API のテストをしたいわけです。そんなものは今まで通りやればいいじゃん? うん、まぁそうなんだけど。

Consumer Driven Contract TestingとPact

Consumer Driven Contract Testing という考え方があるらしい。

API サーバの詳細な動作ではなく、「クライアントが壊れないように API が動作してほしい」という意味での Concumer Driven Contract. 自分の理解としては The RSpec Book の中にあった BDD の二重構造の外側の部分のテストみたいな印象です。

これを実現する

realestate-com-au/pact: Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.

というツールが『マイクロサービスアーキテクチャ』の中で紹介されていたので、これを試す、というのを今回の meetup のお題にしました。

Pactにできること

  • クライアント(Consumer)側が守ってほしい挙動を記述する(標準では RSpec を利用)
    • mock サーバを立ち上げ、サーバ側の挙動は mock として記述する
  • それをサーバ(Provider)側と共有するためのJSONフォーマットがある(Pactfile)
  • これを Provider 側で実行する
  • 集約サーバがある(Broker)
  • Broker から Provider は自分が守るべき Contract を取得し、守れているか自分に対してテストする
    • mock を使ったテストは標準では rack-test を使うので Grape で書いた API はまさにそのままテストできる

mock を stub ではなく正しく mock として使っているので test double が分かっていないと、混乱するかもしれないです。しかも中間形式を用いながら使いまわしているので、クライアント側の期待する動作をサーバ側で検証できるのは非常に面白いです。

Broker はなくても Provider 側でテストの実行方法が分かれば最低限なんとかなるので、以下を目標としました。

本日の目標

  1. Consumer のテストの記述と Mock の動作が分かる
  2. Pactfile を生成する
  3. Grape ですでに途中まで書いてある API があるので、それに対してPactfileからテストを実行する

までできれば練習完了。 3 は完了しなかったけど、これは想定の範囲内ということで。

bethesque/pact-consumer-minitest: Minitest support for the Pact Consumer gem

感想としてはクライアント側のコードを example に合わせて HTTParty を使ってみて、この部分に慣れていなかったのでなかなか手間取ってしまいましたが、サーバの mock は書きやすくてよかったと思います。まずは API のテストの第一歩を歩き始めた気分。

(このあと provider state など不慣れな用語がたくさん出てきて戸惑うことになるのですが、それはまた後日)

参考

About

例によって個人のなんちゃらです