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.5k
AWSマネージドサービスとのテスタブルなアプリケーションコード
shiro seike
PRO
October 08, 2022
Tweet
Share
More Decks by shiro seike
See All by shiro seike
AWS X-Rayを利用したサーバーレスのパフォーマンス分析 / Serverless performance analysis using AWS X-Ray
seike460
PRO
2
26
Cloudflare Workers x AWS Lambdaの組み合わせユースケース / Cloudflare Workers x AWS Lambda Combination Use Case
seike460
PRO
2
390
技術力を高め合う “開けた”企業間コミュニティの形成 / Formation of an "open" inter-company community to enhance technological capabilities
seike460
PRO
1
77
有効な使い方を正しく理解して実装する PHP8.3の最新機能の「ウラ側」 / Understanding and Implementing Effective Usage Correctly The "Uraside" of PHP 8.3's Latest Features
seike460
PRO
1
120
有効な使い方を正しく理解して実装する PHP8.3の最新機能 / Proper understanding and implementation of effective usage Latest features in PHP 8.3
seike460
PRO
2
320
事例から見るサーバーレスの効果 / Serverless Effectiveness as Seen in Case Studies
seike460
PRO
1
110
Secure Serverless Architecture
seike460
PRO
2
610
地方こそサーバーレス、その意義に迫るサーバーレスPHP / Serverless PHP: The Rural Areas, and Why Serverless PHP Matters
seike460
PRO
2
210
サーバーレスらしさを意識した AWSにおける開発手法 / Development methodologies in AWS that are serverless-like
seike460
PRO
1
87
Other Decks in Programming
See All in Programming
Method Swizzlingを行うライブラリにおけるマルチモジュール設計
yoshikma
0
110
実践!難読化ガイド
mitchan
0
110
Go Code Generation at newmo / 2024-08-27 #newmo_layerx_go
genkey6
0
550
長期運用プロダクトの開発速度を維持し続けるためのリファクタリング実践例
wataruss
8
2.7k
開発を加速する共有Swift Package実践
elmetal
PRO
0
390
サーバーレスで負荷試験!Step Functions + Lambdaを使ったk6の分散実行
shuntakahashi
6
1.5k
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
210
Swiftコードバトル必勝法
toshi0383
0
150
Android開発以外のAndroid開発経験の活かしどころ
konifar
2
440
Kotlin 2.0 and Beyond
antonarhipov
2
140
エンジニア1年目で複雑なコードの改善に取り組んだ話
mtnmr
3
1.8k
2024 컴포즈 정원사
jisungbin
0
150
Featured
See All Featured
Web Components: a chance to create the future
zenorocha
308
42k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
43
2k
The Art of Programming - Codeland 2020
erikaheidi
48
13k
Rails Girls Zürich Keynote
gr2m
93
13k
WebSockets: Embracing the real-time Web
robhawkes
59
7.3k
Build The Right Thing And Hit Your Dates
maggiecrowley
30
2.2k
Git: the NoSQL Database
bkeepers
PRO
425
64k
KATA
mclloyd
27
13k
Fashionably flexible responsive web design (full day workshop)
malarkey
401
65k
Building a Scalable Design System with Sketch
lauravandoore
458
32k
Docker and Python
trallard
39
3k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
41
6.5k
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/