Mais conteúdo relacionado
Semelhante a AWS Lambdaのテストで役立つ各種ツール (20)
Mais de Masaki Suzuki (7)
AWS Lambdaのテストで役立つ各種ツール
- 1. JAWS DAYS 2021 re:Connect
AWS Lambdaのテストで役立つ各種ツール
Author: Masaki Suzuki
@makky12
JAWS DAYS 2021 re:Connect
- 2. 自己紹介
• 名前:鈴木 正樹 (Masaki Suzuki)
• 在住:愛知県半田市
• 職業:フリーランスエンジニア
• 業務:サーバーレスアプリのアーキテクチャ構築/設計/開発/テスト など
• 技術:
• AWS/Serverless Framework/サーバーレス全般
• JavaScript/TypeScript/AWS Amplify/Jest/MS系技術
• 各種イベント・SNS・ブログでのクラウド普及活動(個人的に)
• SNS:
http://makky12.hatenablog.com/
https://github.com/smt7174
@makky12 (Masaki Suzuki@フリーランスクラウドエンジニア)
名古屋市
豊橋市
JAWS DAYS 2021 re:Connect
- 3. 本日紹介するツール&資料・ソース
• 単体テスト
• AWS-SDK-Mock
• 結合テスト
• Serverless Framework(概要のみ)
• Serverless Offline
• Serverless-DynamoDB-Local / Serverless-S3-Local
• 本日の発表資料&参考ソースは、以下の場所で公開してます
• SlideShare:
• GitHub:https://github.com/smt7174/jawsugdays2021
JAWS DAYS 2021 re:Connect
- 6. AWS-SDK-Mockとは
• AWS SDK(AWS SDK for JavaScript)の各関数をMock化するためのnpmモジュール
• 単体テストで便利
• 「AWSリソースにアクセスする部分」だけをピンポイントでMock化できる
• 「上記処理を内包している関数」自体のモック化は不要(右下コード参照)
• とてもシンプルなコードでMock化が可能
• Mock化の手間を削減可能
• 自分で1からMock関数を定義する必要がない
• GitHubページ:
• https://github.com/dwyl/aws-sdk-mock
JAWS DAYS 2021 re:Connect
// getContents関数自体はMock化しなくていい
async function getContents() {
const param = {Bucket:’a’, Key:’b.json’};
// ここ(s3.getObject関数)だけをMock化できる
const res = await s3.getObject(param);
const contents = res.Body.toString();
return contents;
}
- 7. コード例
定義
// トップレベルのnode_modulesフォルダにaws-sdkが
// ある場合、自動でaws-sdkを読み込んでくれます。
// 以下は明示的にaws-sdkを指定する場合の例です。
const aws = require(‘aws-sdk’);
const awsMock = require(“aws-sdk-mock”);
// aws-sdkのインスタンスを指定する場合
awsMock.setSDKInstance(aws);
// aws-sdkのパスを指定する場合
awsMock.setSDK(‘./node_modules/aws-sdk’);
関数のMock化
// aws-sdk関数の引数そのままの形式で指定する場合
// ※第3引数を文字列/バッファにすると、それをそのまま返す
awsMock.mock(‘S3’, ‘getObject’, (prm, cb) => {
callback(null, {Body: Buffer.from(‘aaa’)})
});
// callbackを使用しない(=asyncを使用する)場合の書き方
awsMock.mock(‘S3’, ‘getObject’, async(prm) => {
return {Body: Buffer.from(‘aaa’)}
});
// Mock化の終了
awsMock.restore(‘S3’, ‘getObject’);
JAWS DAYS 2021 re:Connect
- 8. メリット&デメリット(注意点)
メリット
• Mock化が簡単
• 自分で定義するより手間がかからない
• ピンポイントでMock化できる
• AWS SDK関数の戻り値だけを指定可能
• 他の箇所に影響しない(そのまま使用可能)
• エラー時のテストが行いやすくなる
• AWSリソースの処理でエラー発生したケース
• (例) S3からのデータ読込に失敗した…など
• E2Eテストではなかなか実施できない部分
デメリット(注意点)
• aws-sdkの自動読み込みにクセがある
• aws-sdkの自動読込が行われない場合がある
• ルートのnode_modulesフォルダにaws-sdkがない
• TypeScriptやES6でコードが掛かれている
• パス/インスタンスを明示的に指定すればOK
• setSDK, setSDKInstanceなど
• 「参考リンクその1」の各サイトを参照
• ネストされたAWSリソース(※)の扱い
• 下記順序で実施しないとMock&Restoreできない
• Mock時は子→親の順
• Restore時は親→子の順
• (※) DynamoDB.DocumentClientなど
JAWS DAYS 2021 re:Connect
- 11. Serverless Frameworkとは
• サーバーレスアプリの構築・開発・運用管理をサポートするOSS
• 公式URL: https://serverless.com/
• CloudFormation(以下Cfn)機構を利用したリソース管理&環境構築が可能
• Cfnテンプレートに比べて、定義がシンプル(特にLambda関連)
• AWS・Azure・GCPなど、多数のクラウドに対応(一番機能が豊富なのはAWS)
• プラグインによる機能拡張が可能(プラグインの自作も可能)
• 「結合テスト」で紹介するツールは全てこの「プラグイン」
• その他、以下の特徴がある
• 公式ページのダッシュボードでCI/CD・モニタリングなども対応
• 公式ドキュメントが結構充実&英語が読みやすい(個人的に)
JAWS DAYS 2021 re:Connect
- 13. Serverless Offlineとは
• ローカル環境にAPI Gateway+Lambdaの実行環境を構築する
• ローカルホストのエンドポイントURLから、Lambdaをローカル実行可能
• REST/HTTP APIを API Gateway経由で実施するのと同じ
• 「Serverless Offline上での動作かどうか」を判定できる
• 環境変数「process.evn.IS_OFFLINE」にて判定可能
• 「デメリット・注意点」参照
• GitHubページ:
• https://github.com/dherault/serverless-offline
JAWS DAYS 2021 re:Connect
- 14. メリット&デメリット(注意点)
メリット
• 導入が簡単
• npm install –save-dev でインストールするだけ
• あとはserverless offline コマンドで起動可能
• 定義が必要な設定がほとんどない
• 全てデフォルト値でも問題なく動く
• ローカルで起動できる
• 実際にAWSにアクセスする必要がない
• オフラインでもテスト可能&コスト削減
• 動作環境を判定できる
• テスト時のみの挙動を設定可能
• (例) DynamoDB, RDSの接続先など
デメリット(注意点)
• これだけではあくまでも「動く」だけ
• AWSリソースの代わりは別途必要
• これから紹介するツールなど
• テスト専用ロジックをソースに含める危険性
• 「Test Logic in production」アンチパターン
• http://xunitpatterns.com/Test%20Logic%20in%2
0Production.html
• https://speakerdeck.com/hgsgtk/testing-anti-
pattern-learned-in-xunit-test-pattern?slide=16
• テスト専用コードを極力ソースに埋め込まないよ
うにする。(外部(=テストコード)から注入する)
• 後述ツールのエンドポイント設定など
JAWS DAYS 2021 re:Connect
- 16. Serverless-DynamoDB-Local & S3-Localとは
• Serverless-DynamoDB-Local
• AWS公式のDynamoDB-Localの環境を起動時に構築する
• 「serverless」コマンド経由でDynamoDB-Localをインストールできる
• ローカルホストのURLから、DynamoDB-Localを操作可能
• テーブル定義はserverless.ymlの定義をそのまま使用可能(専用の定義は不要)
• GitHubページ:https://github.com/99x/serverless-dynamodb-local
• Serverless-S3-Local
• ローカルPCのフォルダにS3バケット&キーを構築できる
• ローカルホストのURLから、上記バケット&キーを操作可能
• GitHubページ:https://github.com/ar90n/serverless-s3-local
• Serverless-Offlineの環境上で使用可能
• 「AWSリソース(DynamoDB/S3)の代わり」となる
JAWS DAYS 2021 re:Connect
- 17. メリット&デメリット(DynamoDB-Local)
メリット
• ローカルでDynamoDBのテストができる
• aws-sdkのメソッドを介して実際にR/Wが行える
• AWSで用意されている機構での動作が可能
• Mock的な「テスト専用コード」が必要ない
• AWS公式ツールなので、信頼性もある
• テーブルのマイグレートが簡単
• serverless.ymlのテーブル定義から起動時にテー
ブルを作成できる
• seed設定をしておけば、初期値も設定できる
• jsonファイルなどから読み込み可能
デメリット(注意点)
• 最新版だと起動できないケースがある(バグ?)
• [0.2.36] 'sls dynamodb install' shows nothing
#195
• 旧バージョン(0.2.30)なら大丈夫だが、画面が
少々使いにくい…
• AWS公式ページからDLしたものをそのまま使う
のもありかも…(少々手間かもしれないけど)
• 対処方法は「参考情報その1」に記載
• DynamoDBインスタンス生成時に追加設定が必
要(エンドポイントなど)
• 「Test Logic in production」アンチパターンに注
意する
• 設定はできる限りテストソース側から注入する
JAWS DAYS 2021 re:Connect
- 18. メリット&デメリット(S3-Local)
メリット
• ローカルでS3のテストができる
• aws-sdkのメソッドを介して実際にR/Wが行える
• AWSで用意されている機構での動作が可能
• Mock的な「テスト専用コード」が必要ない
• 各種S3イベントのトリガを発火できる
• createObjectなど、S3の各種イベントでのイベ
ント発火も対応
• イベントでLambda起動などの確認も可能
• もちろん、イベント発火対象のLambdaの結合テ
ストも可能
デメリット(注意点)
• 自分でキーを作成するのが若干手間
• S3-Local専用の形式に従う必要がある
• バケットフォルダにファイルを置くだけではダメ
• キーとして認識してくれない
• putObjectなどで、事前に作成しておくとよい
• 形式に沿えば、自分で作成することも可能
• S3-Local専用の形式は「参考情報その2」に記載
• AWS S3と全く同じ形式ではない
• S3-Local独自の形式に従う必要がある
• 「AWSの再現性」という意味では、Serverless-
DynamoDB-Localに比べてどう感じるか
• 「ローカルでの確認」という点では十分
JAWS DAYS 2021 re:Connect
- 19. まとめ
• テスト時に役に立つ便利なツールがたくさんある
• 本日紹介したツールは、あくまでもその中の一部
• ツールを活用して、テスト作業を効率的に行える
• もちろん他にも、役立つツールはたくさんある
• 「自分にとって使いやすいものを使用する」ことが大切
• 「テストを効率的に行える」事が大切
• ツール・手法に固執しすぎるのもよくない(手段が目的にならないように)
• 本セッションも「効率化の手段の一つ」として参考にして頂ければ
• Pluginを活用しよう(Serverless Framework)
• テスト以外にも役立つPluginが非常に多いので、一度探してみるのをお勧め
• URL:https://www.serverless.com/plugins/
• 個人的にはServerless Framework(とAWS)が大好きです!
JAWS DAYS 2021 re:Connect
- 20. 参考情報その1
• Serverless-DynamoDB-Localの「最新版だと起動できないケースがある」の対処法
• 参考:[0.2.36] 'sls dynamodb install' shows nothing #195
• 「serverless dynamodb install」時に「--localPath ./bin」オプションをつける
• https://github.com/99x/serverless-dynamodb-local/issues/195#issuecomment-453212948
• 専用のスクリプトを用意する
• https://github.com/99x/serverless-dynamodb-local/issues/195#issuecomment-456021438
• Ver0.2.30をインストールする
• 「ローカルでの動作確認」は問題なく実施可能
• ただ、画面がちょっと使いにくい…
JAWS DAYS 2021 re:Connect
- 21. 参考情報その2
• Serverless-S3-Localで必要となるキーファイル
• ただバケット対象のフォルダにファイルを置くだけではだめ
• 下の画像の3ファイルが必要(元のキーファイル名が「abc.json」の場合)
• 一度putObjectなどで動かしてみるとわかりやすい
• 「S3rver」の箇所は、「アクセスキー」に設定された値が入る。
• デフォルト値が「S3RVER」
• md5暗号化での暗号化については、こちらを参照
• Coding.Tools:https://coding.tools/md5
• md5.js:https://labs.cybozu.co.jp/blog/mitsunari/2007/07/md5js_1.html
JAWS DAYS 2021 re:Connect
// abc.jsonのメタデータ(content-type等)が記載されたファイル
// abc.jsonと同じ本文のファイル(=これが本体)
// abc.jsonの本文をmd5で暗号化した内容が記載されたファイル
- 22. 参考リンクその1
• AWS-SDK-Mockについて
• AWS SDKを使ってもAWS環境にアクセスせずにユニットテストを回す方法
• https://qiita.com/horike37/items/41f9586d315c91d49305
• aws-sdk-mockを使ってもS3がモックに差し変わらずに困りました
• https://qiita.com/nyandora/items/d551d2bed153c724455a
• 【AWS】aws-sdk-mockでLambdaテストを行う(私のAdventCalendar 2020の記事)
• https://makky12.hatenablog.com/entry/2020/12/25/070000
• Serverless Frameworkについて
• 公式ページ
• https://www.serverless.com/
• Serverless Frameworkでローカル環境のセットアップからAWSへDeployまでを試してみる
• https://www.serverless.com/
• Serverless Frameworkはじめの一歩(私のAdventCalendar 2020の記事)
• https://makky12.hatenablog.com/entry/2020/12/18/070000?_ga=2.73413648.381045335.160975716
4-493705487.1601719323
JAWS DAYS 2021 re:Connect
- 23. 参考リンクその2
• Serverless-Offline/Serverless-DynamoDB-Local/Serverless-S3-Localついて
• Serverlessアプリケーションをローカルで開発する
• https://qiita.com/noralife/items/e36621ddd0e5b8ff4447
• Serverless-Offlineを導入してServerless Framework + TypeScriptで作ったLambda関数をVS
Codeでステップ実行する
• https://note.com/dafujii/n/naf05740a253b
• Serverless Framework + TypeScript + DynamoDBのローカル環境
• https://zenn.dev/maruware/articles/cac0052812c2e3293dd5
• Serverless framework (AWS) のプラグインについて
• https://qiita.com/okky_eng/items/fc91801bcbdf5df277f8#serverless-s3-local
• ローカル環境でLambda+S3のテストをする
• https://qiita.com/billthelizard/items/22d2457f3d6386d21796
• 今回紹介したツールは載っていないが、設定をテストソース側から注入するやり方の参考
JAWS DAYS 2021 re:Connect