Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AWSマネージドサービスとのテスタブルなアプリケーションコード
Search
shiro seike
PRO
October 08, 2022
Programming
2
1.6k
AWSマネージドサービスとのテスタブルなアプリケーションコード
shiro seike
PRO
October 08, 2022
Tweet
Share
More Decks by shiro seike
See All by shiro seike
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
1
98
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
120
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
520
とにかくAWS GameDay!AWSは世界の共通言語! / Anyway, AWS GameDay! AWS is the world's lingua franca!
seike460
PRO
1
1.1k
実践サーバーレスパフォーマンスチューニング ~その実力に迫る~ / Practical Serverless Performance Tuning ~A Close Look at its Power~
seike460
PRO
2
350
PHPを書く理由、PHPを書いていて良い理由 / Reasons to write PHP and why it is good to write PHP
seike460
PRO
5
600
AWS CDKを用いたセキュアなCI/CDパイプラインの構築 / Build a secure CI/CD pipeline using AWS CDK
seike460
PRO
3
760
いまあるチームにフィットさせる Serverless そして Platform Engineeringへの挑戦 / Serverless Fits the Team You Have and Platform Engineering
seike460
PRO
2
2.1k
いまあるチームにフィットさせる Serverless / Serverless fits in with the team you have now.
seike460
PRO
2
180
Other Decks in Programming
See All in Programming
短期間での新規プロダクト開発における「コスパの良い」Goのテスト戦略」 / kamakura.go
n3xem
2
170
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
540
これが俺の”自分戦略” プロセスを楽しんでいこう! - Developers CAREER Boost 2024
niftycorp
PRO
0
190
採用事例の少ないSvelteを選んだ理由と それを正解にするためにやっていること
oekazuma
2
1k
DevFest Tokyo 2025 - Flutter のアプリアーキテクチャ現在地点
wasabeef
5
900
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
710
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
1
120
nekko cloudにおけるProxmox VE利用事例
irumaru
3
420
Jakarta EE meets AI
ivargrimstad
0
230
Mermaid x AST x 生成AI = コードとドキュメントの完全同期への道
shibuyamizuho
0
160
20年もののレガシープロダクトに 0からPHPStanを入れるまで / phpcon2024
hirobe1999
0
270
競技プログラミングへのお誘い@阪大BOOSTセミナー
kotamanegi
0
360
Featured
See All Featured
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Being A Developer After 40
akosma
87
590k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Producing Creativity
orderedlist
PRO
341
39k
Documentation Writing (for coders)
carmenintech
66
4.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Side Projects
sachag
452
42k
How STYLIGHT went responsive
nonsquared
95
5.2k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Adopting Sorbet at Scale
ufuk
73
9.1k
Transcript
AWSマネージドサービスとの テスタブルなアプリケーションコード JAWS DAYS 2022 Satellites 2022/10/08 清家史郎 1
自己紹介 清家 史郎 @seike460 - ID - GitHub:seike460 - Twitter:@seike460
- Work at - 株式会社 Fusic (フュージック) 技術開発本部/技術開発第一部門 - チームリーダー/プリンシパルエンジニア/ エバンジェリスト - Skill - PHP/Go/AWS - Community - PHPカンファレンス2018 - 2022 - AWS Dev Day Japan 2021 - 2022 2
Agenda 3 1. テストコード 2. ユニットテストの導入 3. マネージドサービスに対するユニットテスト 4. マネージドサービスのエミュレート
5. まとめ
01 テストコード
人はなぜテストをするのか 5 不具合は誰も幸せになることがない - システム利用者は利用できない為の不利益を - システム運用者は障害復旧に時間を取られ、ユーザー離れで不利益を - システム開発者は障害対応に心を削られ、 障害原因に気付いて心を削られ、障害報告に心を削られ、
障害対応後に残った仕事に心を削られ… 不具合は人を不幸にする。テストをすることで、不幸な人を救いましょう
どうやってテストをすればよいのか 6 時間をつぎ込んで、ひたすら手動テストを行うべきなのか 技術発達により加速する現代の開発速度についていく為には、 時間を使って解決することは得策とは言えないし、人は必ず間違えます。 テストをしたから絶対に大丈夫、本当でしょうか?
自動テスト 7 ではどうするのか 私達がプログラムでユーザーの課題を解決するように、 自動テストを行う事で、プログラムで課題解決を行います。
自動テストは何をすると良いのか 8 UI Tests、Service Tests、Unit Testsと分類され、大雑把に言うと より疎結合で早い Unit Testsと、より密結合で遅い UI
Testsとなる The Practical Test Pyramid https://martinfowler.com/articles/practical-test-pyramid.html
02 ユニットテストの導入
Bref 10 AWS Lambdaを利用したServerless PHPを簡単に実現してくれるオープンソース Serverless Frameworkを利用して 簡単にPHPのCustom
RuntimeをAWS Lambdaにデプロイすることが出来ます。
Docker / Bref 11 DockerHubにてDocker Imageも配布されているため、 簡単に開発を始める事が出来るのも嬉しいポイント
Serverless Framework 12 Serverless Applicationを構成管理デプロイするためのツールで、 Yamlにて設定されたAWS Lambdaを簡単にデプロイすることが出来ます。 また同じYaml内にCloud
Formationを記述する事も出来るため、 汎用性が高く様々なプラグインも提供されているツール
例題システム 13 MVP(Minimum Viable Product)として とにかく注文をインターネットから受け取る事が目的で、S3に注文情報を保存し 人力でその注文情報を見ながら受注生産を行うシステムがあったとします。
注文情報の保存処理を記述 14 S3に注文情報(Order)を保存する HTTP Requestの情報をS3に 保存するプログラムを記述することで 要件を満たすことが出来ました。
事業成長し… 15 事業成長し、注文情報を人力で見に行く事が限界を迎えました。 そのため注文されてからの生産依頼を自動で行うシステムを構築しました。 システムへの生産依頼はSQSを介して実行されます。
注文情報保存後に、キューイング処理の追加 16 S3に注文情報を保存後、 SQSにメッセージ送信部分を 追加することで、 生産依頼システムへ 連携する事が出来た
更に事業成長し… 17 更に事業成長して、注文情報の納期管理や在庫管理を行うため、 注文情報を検索する必要が出てきました。 そこでDynamoDBを利用した注文情報検索システムを構築しました。
キューイング処理後にDynamoDBに保存する 18 SQSにメッセージ送信後に DynamoDBへの保存処理を 追加することで、 注文情報検索システムへの データ追加を行う事が出来た
更に更に事業成長し… 19 度重なる機能追加で全ての機能を手動テストすることで、 品質を担保する事が難しくなってきました。 そこで自動テストを取り入れる事になります。
再度テストピラミッドをおさらい 20 より疎結合で速度の早いUnit Testsを作成したい
Unit Testを…書けない! 21 今まで追加で全ての情報保存を完全に密結合に してしまっているのでUnit テストは出来ない このような構造にしてしまっていると、
Requestを再現して 他の機能と一緒にテストを行うしかない状態
Unit Testの単位を探す 22 Unit Testを呼べる単位を考える S3への注文情報の保存 生産依頼システムへのキューイング 注文情報検索システムへのDB保存
処理の単位で分割をする 23 S3でいうとこの部分 - クライアント生成 - 保存情報生成 - 保存処理の実施
が一つ一つの処理単位となる
注文データ保存を行うModelを作成 24 S3へデータの保存を行う、 Modelを作成することで、 処理の切り出しを行う
注文データ保存を行うModelを作成 25 それぞれの保存先に対する 処理毎に分割する事が出来ました
データ保存先により、Modelを変更する 26 主題とは少しズレますが、 データの保存先がそれぞれ違うので S3用、SQS用、DynamoDB用と データの保存先毎にModelを作成すると 更に保存先毎に振る舞いを変更する事が出来ます。
このModelに対するUnitテストを記述することで 自動テストを行っていきます。
03 マネージドサービスに対する Unit Test
PHPUnit 28 PHPでUnit Testを行う場合、PHPUnitを使うのが良い 様々なWeb Frameworkでも取り入れられているメジャーなTest Framework https://phpunit.de/
PHPUnitの実行の様子 29 Testを記述して実行すると次の様に 結果を確認することが出来ます。 ...FE... . … 成功したテスト
想定したテスト結果となった場合 F … failure(失敗)したテスト 想定したテスト結果と違う場合 E … error 予期せぬエラー(Fatal Error等)が 発生した場合
setUp() 30 各テストケースの直前に実行される関数 前処理をまとめるのに有効で、 例の様に予めオブジェクトを生成して propertiesに持たせる事が出来ます。 ※同じ様にtearDownと呼ばれる 後処理も存在します。
マネージドサービス のUnitTest 31 早速テストを記述していくに あたりModelの見直すべき点を 確認します すると認証情報が 直接指定されているため、 テストでも、Productionでも
同じS3に情報が保存されてしまう この部分を見直す必要があります。
Mock
Mocking 33 Aws\MockHandlerを利用すると 擬似結果を返す事が可能です。 Client生成時にhandlerに生成したmock Objectを渡すと、 Clientは追加された順番に 結果を返してくれます。
Mocking 34 Exceptionの擬似結果を返す事も 可能なので、意図的にExceptionを 発生させたい場合等にも利用できます
env
Laravel 36 PHPer御用達のWeb Framework、AWSや他のOSSとの相性も良い
Serveless Laravel (Bref) 37 https://bref.sh/docs/frameworks/laravel.html Laravelを利用したBrefを 整備する方法はBref公式ページに 説明があります。
手順をなぞるだけで、 なんの不自由もなくLaravelを 投入することが出来ます。 AWS Lambdaの場合はAPIとして 利用する事がほとんどですので、 今回はAPIモードで利用します
envファイル(.env.testing) 38 .env.testingという テストの時に利用する 環境変数を設定する事が出来ます
テスト時のIAM情報を設定できる 39 envファイルの中には AWS_ACCESS_KEY_IDや AWS_SECRET_ACCESS_KEY、 AWS_BUCKETまで 設定項目が最初から用意されてます .env.testingの中に
テスト用のIAMを記述する事で テストの時に利用するIAMを記述し、 本番と別の、テスト用のS3に データ保存を行う事が出来ます。 言語毎に設定していきます
認証情報の設定部分の切り出し 40
認証情報の設定部分の切り出し 41 認証情報を env ファイルから取得し、 コンストラクタにてs3Clientを生成して、propertiesに s3Clientを持たせる事で S3クライアントが何度も生成されることを分ける
現在のアーキテクチャを振り返る 42 マネージドサービス環境を振り分ける事で、 本番環境とテスト環境で利用する領域を分け、 マネージドサービスに対するテストの問題が 完全に解決 もちろんだがそんなことはない
Unit Testは大量に行われる 43 10テストくらいなら 気にならないかもしれないが 120テストならどうなのか またS3ではなくDynamoDBのテスト で高速に読み書きが 発生し続けるとどうなるか
それが更にCI/CDの導入により 日/100回行われるとどうなるか
アーキテクチャを考える 44 テスト数 × PR のAWSへのリクエスト発生は コスト観点から見ても効率的には思えない ではどうするべきなのか
04 マネージドサービスの エミュレート
MinIO 46 Amazon S3互換のObject Storage、Dockerの利用も可能 こちらを利用してS3をエミュレートが出来る
MinIO UI 47 実際ローカルにMinio Dockerを利用して立ち上げた様子です。 もちろんS3とUIは違いますが、S3と同じくBUCKETが作成出来ます。
AWS SDK endpoint 48 AWS SDKは「endpoint」オプションが存在して、 こちらにminioのURLを設定する事で接続先をminioにしながら S3のプログラムを書くことが出来、開発時にも役に立ちます。
dynamodb-local 49 Amazon DynamoDBをエミュレート出来る、DynamoDB local AWSが公式に出している安心感もあります。 同じ様にDockerで、気軽に利用する事が出来ます
ElasticMQ 50 Amazon SQS互換のMessage queue、同じくDockerの利用が可能
エミュレート対応(Model側) 51 外からConfigを渡せる様に ModelClassを作成します .envを利用したい場面も あるのでコンストラクタ側で 判定を行う
テスト側での対応 52 テストケースのsetUpにて $configを注入する事で テストの際の向き先を MINIOに向ける事が可能 テスト用のBucket生成等も 合わせて行う
ローカル エミュレート 53 互換サービスとDockerを利用する事でローカルで エミュレートすることが出来ました。
LocalStack
LocalStack 55 LocalstackはAWSのあらゆるサービスを擬似的に使用できる事が可能で、 MINIOやDynamoDB Localの様にendpointを提供してくれる為、 テスト時に利用する事が可能
LocalStackでAWS サービス再現 56 endpointが提供されて、互換性があるので他の互換サービスと同じ様に このようなテストアーキテクチャを設定する事が出来ます。
GitHub Actions等でも利用可能 57 公式サイトに各種CIに対する情報を提供してくれています。 ローカルテストだけでなく、CIに組み込む事も出来ます。
全てLocalStackで良いのでは?…本当に? 58 LocalStack(650MB) minio(76MB)
エミュレートはあくまでエミュレート 59 また、エミュレートはあくまでエミュレートで有ることは認識すべきです。 最新のサービスについていってない場合や、 思わぬ結果が返ってくる可能性も0ではありません。
ステージング 環境
ステージング環境 61 ステージング環境を作りましょう。 自動テストでも完全に担保出来ないので、 ステージング環境を動作させる事が 本当の状態を知る為に重要です。 テスト観点でもIaCを学ぶ事も重要だと考えます。 ※自動テストが不要という意味ではないです。 自動テストで担保出来るものはあります。
最善を尽くす事が重要だと考えます。
ロジックを絞り、エミュレーションしない 62 コード設計を綺麗にすることで、マネージドサービスへのアクセスロジックを 一箇所に集約するのも手です。しっかりしたコード設計が必要になりますが 完璧にやりきる事ができればインテグレーションテストが一つで済む
処理の単位で分割をする 63 - クライアント生成 - 保存情報生成 - 保存処理の実施
が一つ一つの処理単位となる 保存処理の分離で達成可能 だが全てのアプリケーションが 綺麗に分割出来るわけではない
05 まとめ
まとめ Point 2 アプリケーションコードはテストが出来る単位で処理分割すると Unit Test対応が出来ます 65 バグをなくすために自動テストを行いましょう Point
1 AWS サービスを各種OSSなどを利用することで、エミュレートして自動テストが出来ます。 Point 3 Point 4 テストは完璧ではないことを知り、様々な手法を学ぶことで、選択肢を知りましょう。
ご清聴いただきありがとうございました Thank You We are Hiring ! https://recruit.fusic.co.jp/