Slide 1

Slide 1 text

#MerpayTechFest Session Title Scenario-Based Integration Testing Platform for Microservices Kenta Mori Architect Team, Merpay, Inc.

Slide 2

Slide 2 text

#MerpayTechFest Architect Team, Merpay, Inc. Kenta Mori (@zoncoen) 2018年に株式会社メルペイに入社、 QRコード決済に関わるマイクロサービス 開発に携わる。現在 Architectチームに所属、マイクロサービス ため シナ リオテストプラットフォーム 開発などを担当している。

Slide 3

Slide 3 text

#MerpayTechFest Agenda Introduction Test Runner Continuous Integration Testing in the Real World 02 03 04 01 05 Conclusion

Slide 4

Slide 4 text

#MerpayTechFest Introduction

Slide 5

Slide 5 text

#MerpayTechFest Architecture of Merpay Client Service A Service B Service C API Gateway Authority HTTP gRPC gRPC gRPC HTTP Cloud Spanner Cloud Spanner Cloud Storage Cloud Spanner Cloud Pub/Sub

Slide 6

Slide 6 text

#MerpayTechFest Pros of Microservices Architecture ● Better maintainability, testability, deployability ○ 小さいサービスに分割することで見通しが良くなり、各チームが独立 したリリースサイクルで開発することができる ● Scalability ○ 必要なサービス みスケーリングすることで効率よくリソースを利用 することができる ● Improved fault isolation ○ メモリリーク ような問題がシステム全体に影響を与えない ● Eliminate technology lock-in ○ 各サービスが適切な技術スタックを選択することができる

Slide 7

Slide 7 text

#MerpayTechFest Cons of Microservices Architecture ● Complex communication ○ サービス間通信が増加、複雑化する ● Debugging problems can be harder ○ 複数 サービスにまたがる問題 デバッグ 難しい ● Deployment challengers ○ 別 サービスに依存する機能 リリース 完全に独立で ない ● Global testing is difficult ○ 依存しているサービスも含めたテスト 容易で ない

Slide 8

Slide 8 text

#MerpayTechFest Cons of Microservices Architecture ● Complex communication ○ サービス間通信が増加、複雑化する ● Debugging problems can be harder ○ 複数 サービスにまたがる問題 デバッグ 難しい ● Deployment challengers ○ 別 サービスに依存する機能 リリース 完全に独立で ない ● Global testing is difficult ○ 依存しているサービスも含めたテスト 容易で ない

Slide 9

Slide 9 text

#MerpayTechFest Microservices Testing Strategies ● Unit tests ○ テスト可能な最小単位 コードに対するテスト ● Component tests ○ テスト範囲を1つ サービスに限定したテスト ● Contract tests ○ Consumer が期待する仕様を満たしているか確認するテスト ● Integration tests ○ サービス間 通信経路や相互作用 検証も含めたテスト ● End-to-end tests ○ システム全体に対するテスト From martinfowler.com

Slide 10

Slide 10 text

#MerpayTechFest Microservices Testing Strategies External Service In-Memory Datastore External Datastore Service HTTP/gRPC Client Stub Client Client External Service

Slide 11

Slide 11 text

#MerpayTechFest Microservices Testing Strategies ● Unit tests ○ テスト可能な最小単位 コードに対するテスト External Service In-Memory Datastore External Datastore Service HTTP/gRPC Client Stub Client External Service Client

Slide 12

Slide 12 text

#MerpayTechFest Microservices Testing Strategies ● Component tests ○ テスト範囲を1つ サービスに限定したテスト External Service In-Memory Datastore External Datastore Service HTTP/gRPC Client Stub Client External Service Client

Slide 13

Slide 13 text

#MerpayTechFest Microservices Testing Strategies ● Contract tests ○ Consumer が期待する仕様を満たしているか確認するテスト External Service In-Memory Datastore External Datastore Service HTTP/gRPC Client Stub Client External Service Client Consumer Provider

Slide 14

Slide 14 text

#MerpayTechFest Microservices Testing Strategies ● Integration tests ○ サービス間 通信経路や相互作用 検証も含めたテスト External Service In-Memory Datastore External Datastore Service HTTP/gRPC Client Stub Client External Service Client

Slide 15

Slide 15 text

#MerpayTechFest Microservices Testing Strategies External Service In-Memory Datastore External Datastore Service HTTP/gRPC Client Stub Client ● End-to-end tests ○ システム全体に対するテスト Client External Service

Slide 16

Slide 16 text

#MerpayTechFest Microservices Testing Strategies ● Unit tests ○ Go test(関数単位 ユニットテスト) ● Component tests ○ Go test(Mock や Stub を使った1サービスに閉じたテスト) ● Contract tests ○ Pact (, schema-first development) ● Integration tests ○ Postman ● End-to-end tests ○ Appium, XCUITest, Cypress, etc.

Slide 17

Slide 17 text

#MerpayTechFest ● Unit tests ○ Go test(関数単位 ユニットテスト) ● Component tests ○ Go test(Mock や Stub を使った1サービスに閉じたテスト) ● Contract tests ○ Pact ● Integration tests ○ Postman ● End-to-end tests ○ Appium, XCUITest, Cypress, etc. Microservices Testing Strategies Difficult

Slide 18

Slide 18 text

#MerpayTechFest Test Runner

Slide 19

Slide 19 text

#MerpayTechFest Integration Testing Service A Service B Service C API Gateway Authority gRPC gRPC HTTP Cloud Spanner Cloud Spanner Cloud Storage Cloud Spanner Cloud Pub/Sub ? gRPC HTTP Client

Slide 20

Slide 20 text

#MerpayTechFest Postman ● JSON over HTTP な API サーバー テストを行うツール ○ https://www.postman.com/ ● GUI アプリケーションが用意されている ● 既存 CI に組み込みやすい ○ Newman を使うと CUI で実行できる ● JavaScript コードが実行できる ○ リクエストボディ 生成 ○ レスポンスボディ 確認

Slide 21

Slide 21 text

#MerpayTechFest Postman’s GUI

Slide 22

Slide 22 text

#MerpayTechFest Cons of Postman ● 任意 JavaScript ライブラリを追加できない ○ 汎用的な処理 使い回しもできない ○ グローバル変数を使ってできなく ないが… ● Pull Request ベース メンテナンスが難しい ○ エクスポートしたテスト 定義 JSON 複雑なファイルな で、差 分が確認しにくい ○ Not developer friendly

Slide 23

Slide 23 text

#MerpayTechFest { "info": { "_postman_id": "3c794208-be0b-48cf-9558-04910aa40430", "name": "example", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [ { "name": "Echo Service", "event": [ { "listen": "test", "script": { "id": "de3c44f3-4ae5-4352-8b5f-35bdbe4024a2", "exec": [ "pm.test(\"response status code is OK\", () => {", " pm.response.to.have.status(200);", "})", "", "pm.test('message must be \"hello\"', function () {", " const jsonData = pm.response.json();", " pm.expect(jsonData.message).to.eql(\"hello\");", "});" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Content-Type", "name": "Content-Type", "value": "application/json", "type": "text" } ], "body": { "mode": "raw", "raw": "{\n\t\"message\": \"hello\",\n}" }, "url": { "raw": "http://localhost:8080", "protocol": "http", "host": ["localhost"], "port": "8080" } }, "response": [] } ] } Exported JSON

Slide 24

Slide 24 text

#MerpayTechFest Scenarigo ● API サーバー シナリオテストを行うため ツール ○ https://github.com/zoncoen/scenarigo ○ テストシナリオを YAML で書ける ○ テストシナリオを使い回すことができる ○ Go で拡張することができる ○ HTTP だけでなく gRPC が使える

Slide 25

Slide 25 text

#MerpayTechFest Test Scenario Example title: echo-service steps: - title: POST /echo protocol: http request: method: POST url: '{{env.ECHO_ADDR}}/echo' body: message: hello expect: body: message: '{{request.message}}' ● Why YAML? ○ JSON より 手で読み書きしやすい(と思う)

Slide 26

Slide 26 text

#MerpayTechFest Test Scenario Example title: echo-service steps: - title: POST /echo protocol: http request: method: POST url: '{{env.ECHO_ADDR}}/echo' body: message: hello expect: body: message: '{{request.message}}' $ scenarigo run example.yaml 1. POST {{env.ECHO_ADDR}}/e cho 2. Receive response 3. Check response Scenarigo echo-service

Slide 27

Slide 27 text

#MerpayTechFest Reuse Test Scenario title: echo-service steps: - title: login include: './login.yaml' < run login.yaml bind: vars: userToken: '{{vars.userToken}}' < store token - title: POST /echo protocol: http request: method: POST url: '{{env.ECHO_SERVICE_ADDR}}/echo' header: Authorization: 'Bearer {{vars.userToken}}' < use token body: message: hello expect: body: message: '{{request.message}}'

Slide 28

Slide 28 text

#MerpayTechFest Plugin ● Go で拡張可能 package main import ( "github.com/google/uuid" ) func UUID() string { return uuid.New().String() } $ go build -buildmode=plugin -o gen.so gen.go

Slide 29

Slide 29 text

#MerpayTechFest Plugin ● Go で拡張可能 title: echo-service plugins: gen: gen.so steps: - title: POST /echo protocol: http request: method: POST url: '{{env.ECHO_ADDR}}/echo' body: id: '{{plugins.gen.UUID()}}' < call Go function message: hello expect: body: id: '{{request.id}}' message: '{{request.message}}'

Slide 30

Slide 30 text

#MerpayTechFest Integration Testing Service A Service B Service C API Gateway Authority gRPC gRPC Cloud Spanner Cloud Spanner Cloud Storage Cloud Spanner Cloud Pub/Sub Scenarigo gRPC HTTP Client HTTP

Slide 31

Slide 31 text

#MerpayTechFest Continuous Integration

Slide 32

Slide 32 text

#MerpayTechFest Integration Testing Service A Service B Service C API Gateway Authority gRPC gRPC Cloud Spanner Cloud Spanner Cloud Storage Cloud Spanner Cloud Pub/Sub Scenarigo gRPC HTTP Client HTTP

Slide 33

Slide 33 text

#MerpayTechFest Integration Testing Service A Service B Service C API Gateway Authority gRPC gRPC HTTP Cloud Spanner Cloud Spanner Cloud Storage Cloud Spanner Cloud Pub/Sub Scenarigo Webhook gRPC HTTP Client

Slide 34

Slide 34 text

#MerpayTechFest Prow ● Kubernetes 上で動く CI/CD システム ○ Kubernetes クラスタ上でジョブを実行 ○ Kubernetes 自体 テストに使われている ○ GitHub コミットをトリガーにしたり指定したスケジュールでテストを 実行することができる ○ https://github.com/kubernetes/test-infra/tree/master/pro w ● Kubernetes クラスタ上で実行される で、クラスタ外から アクセス を許可することなく各マイクロサービス テストができる

Slide 35

Slide 35 text

#MerpayTechFest Dashboard

Slide 36

Slide 36 text

#MerpayTechFest Result

Slide 37

Slide 37 text

#MerpayTechFest Developer Prow Testing Frow Webhook Logs Cloud Storage hook horologium deck Service X plank Controller Job Controller Controller

Slide 38

Slide 38 text

#MerpayTechFest Developer Prow Testing Frow Logs Cloud Storage hook horologium deck Service X ProwJob Custom Resource Create plank Controller Job Controller Controller

Slide 39

Slide 39 text

#MerpayTechFest Developer Prow Testing Frow Logs Cloud Storage hook horologium deck Service X ProwJob Custom Resource plank Controller Reconcile Job Controller Controller

Slide 40

Slide 40 text

#MerpayTechFest Developer Prow Testing Frow Logs Cloud Storage hook horologium deck Service X ProwJob Custom Resource plank Controller Reconcile Job Controller Controller

Slide 41

Slide 41 text

#MerpayTechFest Developer Prow Testing Frow Logs Cloud Storage hook horologium deck Service X ProwJob Custom Resource plank Controller Testing by Scenarigo Job Controller Controller

Slide 42

Slide 42 text

#MerpayTechFest Developer Prow Testing Frow Logs Cloud Storage hook horologium deck Service X ProwJob Custom Resource plank Controller Store Logs Job Controller Controller

Slide 43

Slide 43 text

#MerpayTechFest Developer Prow Testing Frow Logs Cloud Storage hook horologium deck Service X ProwJob Custom Resource plank Controller Get Logs Access Prow Dashboard Job Controller Controller

Slide 44

Slide 44 text

#MerpayTechFest Integration Testing Service A Service B Service C API Gateway Authority gRPC gRPC HTTP Cloud Spanner Cloud Spanner Cloud Storage Cloud Spanner Cloud Pub/Sub Scenarigo Webhook gRPC HTTP Client

Slide 45

Slide 45 text

#MerpayTechFest Testing in the Real World

Slide 46

Slide 46 text

#MerpayTechFest Run tests on local machines ● テストシナリオを作成するときに 手元からテストを実行したい ○ 開発環境 各マイクロサービス expose されてないためインター ネット越しに直接叩くこと できない ● telepresence を使ってリクエストをプロキシする ○ https://www.telepresence.io/ ○ k8s クラスタへ リクエストを自動でプロキシするようにできる ○ プロキシする に使う Deployment を ProwJob PodSpec に 沿って適切に作成することで、k8s 上でテストするときと同じ環境変 数や Secret を利用することができる

Slide 47

Slide 47 text

#MerpayTechFest scenario-test Namespace Local Scenarigo Pod foo-service Namespace foo-service Secret Env Telepresence create

Slide 48

Slide 48 text

#MerpayTechFest scenario-test Namespace Local Scenarigo Pod foo-service Namespace foo-service Secret Env Telepresence foo-service.foo-namespace .svc.cluster.local ● 同一クラスタな でアクセス可能

Slide 49

Slide 49 text

#MerpayTechFest scenario-test Namespace Local foo-service Namespace foo-service Secret Env Telepresence foo-service.foo-namespace .svc.cluster.local ● Expose していなけれ インターネット越しにアクセス不可

Slide 50

Slide 50 text

#MerpayTechFest scenario-test Namespace Local traffic-manager Pod foo-service Namespace foo-service via TUN Secret Env Telepresence ● telepresence connect でトンネリング

Slide 51

Slide 51 text

#MerpayTechFest scenario-test Namespace Local traffic-manager Pod foo-service Namespace foo-service foo-service.foo-namespace .svc.cluster.local via TUN Secret Env Telepresence ● クラスタへ リクエストが proxy される

Slide 52

Slide 52 text

#MerpayTechFest scenario-test Namespace Local traffic-manager Pod foo-service Namespace foo-service foo-service.foo-namespace .svc.cluster.local via TUN Secret Env Telepresence ● クラスタへ リクエストが proxy される

Slide 53

Slide 53 text

#MerpayTechFest scenario-test Namespace Local traffic-manager Pod foo-service Namespace foo-service foo-service.foo-namespace .svc.cluster.local via TUN Secret Env sshfs Telepresence ● Env や Secret も参照可能

Slide 54

Slide 54 text

#MerpayTechFest scenario-test Namespace Local traffic-manager Pod Secret Env foo-service Namespace foo-service foo-service.foo-namespace .svc.cluster.local via TUN Secret Env sshfs Telepresence ● Env や Secret も参照可能

Slide 55

Slide 55 text

#MerpayTechFest Other Issues ● テスト用データ 作成・管理 ○ 社内向けユーザー作成用便利ツール user-tkool ○ あらかじめユーザーを作成しておくことで高速化 ○ そ 他 データ ケースバイケース ● 時間に依存する機能 テスト ○ 環境をわける ○ リクエスト毎に時間を指定できるようにする ● 非同期に処理される機能 テスト ○ リトライする… etc.

Slide 56

Slide 56 text

#MerpayTechFest Other Issues ● 開発している機能を PR 状態でもテストしたい ○ Dynamic Service Routing

Slide 57

Slide 57 text

#MerpayTechFest Other Issues ● 開発している機能を PR 状態でもテストしたい ○ Dynamic Service Routing Next

Slide 58

Slide 58 text

#MerpayTechFest Conclusion

Slide 59

Slide 59 text

#MerpayTechFest Our Integration Testing Platform ● Scenarigo ○ HTTP/gRPC サーバー テストを行うツール ○ テストシナリオを YAML で記述できる ● Prow ○ Kubernetes 上で動く CI/CD システム ● Telepresence ○ Kubernetes クラスタ上にデプロイするアプリケーション向け開発支 援ツール

Slide 60

Slide 60 text

#MerpayTechFest Our Integration Testing Platform ● シナリオテストによるプロダクト 品質向上 ○ 各マイクロサービスを対象にしたインテグレーションテスト ○ 今で 40を超えるマイクロサービスに利用されている ● Future plans ○ Visualization ○ Coverage ○ テスト時間削減