API通信周りの継続的なテストの仕組み~SideCIでの実践~
-
Upload
koichiro-sumi -
Category
Engineering
-
view
99 -
download
2
Transcript of API通信周りの継続的なテストの仕組み~SideCIでの実践~
[Confidential] © 2013 Actcat, Inc.
軽く自己紹介 すみ です
n 「SideCI」というサービスを 開発しているエンジニアです。 言語歴: Ruby > Obj-‐C > Java > PHP, etc…
n Twitter: @sumyapp Facebook: sumyapp
2
[Confidential] © 2013 Actcat, Inc.
What is SideCI?
Integration: Open Source Software + Docker + GitHub
>
Automated Code Review and
Test and Delivery
3
[Confidential] © 2013 Actcat, Inc.
サービス構築にはAPIを作るのが一般的
9
API
API
{ "properties": { "age": { "description": "Age in years", "minimum": 0, "type": "integer" }, "firstName": { "type": "string”
役割毎にサーバ 分離パターン
Server-‐Client パターン
{ "properties": { "age": { "description": "Age in years", "minimum": 0, "type": "integer" }, "firstName": { "type": "string”
[Confidential] © 2013 Actcat, Inc.
APIのレスポンス値を変更すると…
10
API
API
{ "properties": { "age": { "description": "Age in years", "minimum": 0, “min”:9, "type": "integer" }, "firstName": { "type": "string”
役割毎にサーバ 分離パターン
Server-‐Client パターン
{ "properties": { "age": { "description": "Age in years", "minimum": 0, “min”:9, "type": "integer" }, "firstName": { "type": "string”
APIのデータのkeyを変更。 短い方が良いよね!
[Confidential] © 2013 Actcat, Inc.
APIのレスポンス値を変更すると…
11
API
API
{ "properties": { "age": { "description": "Age in years", "minimum": 0, “min”:9, "type": "integer" }, "firstName": { "type": "string”
役割毎にサーバ 分離パターン
Server-‐Client パターン
{ "properties": { "age": { "description": "Age in years", "minimum": 0, “min”:9, "type": "integer" }, "firstName": { "type": "string”
え、いきなり 動かなくなったんだけど…
[Confidential] © 2013 Actcat, Inc.
簡単な3 Step と CI で問題発生を防止
1. API仕様を固める(JSONも) 2. サーバとアプリでテスト通信、 通信時のリクエスト・レスポンスを ファイルに記録する
3. 記録したファイルを使った テストコードをサーバ側に書く
+ 上記のテストをCIでまわす
13
[Confidential] © 2013 Actcat, Inc.
1. API仕様を固める(JSONも) SideCI内での一例:
n URL: l POST "/task/register"
n Header: l 指定なし
n Body: l JSONで下記を送付する
l id: タスクID(タスク識別用) l type: タスクタイプ(rubocop, rails_best_practice, brakeman, bundle_outdated)
14
[Confidential] © 2013 Actcat, Inc.
2. サーバとアプリでテスト通信、 通信時のリクエスト・レスポンスを
ファイルに記録する 1. サーバをローカルで起動(本番でも可)
2. アプリからのリクエストをログ等で確認 3. Header, Request Bodyなどを記録 4. Responseなどを記録
15
[Confidential] © 2013 Actcat, Inc.
記録した一例 (SideCI<-GitHub)
{ "sha": "4e73f2ef6d3534b45bbdf220f060d2628c5952e5", "commit": { "author": { "name": ”Koichiro Sumi", "email": ”[email protected]", "date": "2014-‐02-‐14T09:46:50Z" }, "committer": { "name": "Koichiro Sumi", "email": "[email protected]", "date": "2014-‐02-‐14T09:46:50Z”,
16
JSONファイルとして保存
[Confidential] © 2013 Actcat, Inc.
記録した一例 (SideCI<-GitHub)
request.url "/api/v1/github_repositories/hook/” request.headers['X-‐GitHub-‐Event'] = 'pull_request’ request.headers['X-‐GitHub-‐Delivery'] = 'cd36a080-‐b5a8-‐11e4-‐9e0d-‐q1024663ce0’ request.headers['User-‐Agent'] = 'GitHub-‐Hookshot/e9dfd89’ request.headers['content-‐type'] = 'application/x-‐www-‐form-‐urlencoded’
17
Requestをメモしておく。Responseも
[Confidential] © 2013 Actcat, Inc.
記録したファイルを使った テストコードをサーバ側に書く
n APIはおそらくController?なので、そのControllerのテストコードを書こう
n リクエストに先ほどメモしたリクエストヘッダーやボディを設定、クライアントを装ってControllerにリクエストを送るコード
n そのレスポンスが、サーバ・アプリ間で動作確認を行った、正しく動作するレスポンスと同一であることを確認する
18
[Confidential] © 2013 Actcat, Inc.
Rspecでどう書くか? SideCIの一例
let(:params) { { "payload" => payload_basic } } let(:headers) { { "User-‐Agent" => "GitHub-‐Hookshot/2e7s9", "Content-‐Type" => "application/x-‐www-‐form-‐urlencoded", "Content-‐Length" => "10163", "X-‐GitHub-‐Event" => "push" } } let(:payload_basic ) { File.open('spec/basic.json').read } describe "POST 'hook'" do …(一部省略)…
19
[Confidential] © 2013 Actcat, Inc.
テストをCIでまわす
n 作ったテストはデプロイ前にかならずテスト実行。面倒だったらCIで回しましょう
n CIサービスの一例 l Jenkins…はセットアップが面倒なので, l SideCI, CircleCI, Wercker, Shippable, CodeShip, TravisCI, etc…
20
© 2015 Actcat, Inc.
+ 可能ならコードレビューも 最後に頼りになるのは人力
n API変更時にはコードをプルリクエストでAPI通信を行う先の担当のエンジニアにもレビューして貰いましょう
n うかつなAPI変更による障害防止には l 仕様をしっかり決めて、APIを変えられなくする
l 変えるとテストがFailedして気づくようにする
l テスト・実装共変えた場合は人力レビュー この3つの手段がおすすめだと思います
22
© 2015 Actcat, Inc.
SideCI Customers
GitHub + Railsな開発体制のプロジェクトで ご利用頂いております n 50以上のプロジェクトが毎週ご利用 n 1週間に500~1000回、SideCIがユーザの プロジェクトのコードにコメント
23