Amazon Web Services ブログ
AWS CodeStar プロジェクトにおける単体テストの実行
このブログ記事では、AWS CodeStar プロジェクトの一部として単体テストを実行する方法についてご紹介します。AWS CodeStar は AWS 上でアプリケーションを素早く開発、ビルド、そしてデプロイするのに役立ちます。AWS CodeStar を使えば、継続的デリバリ(CD)のツールチェーンを構築しソフトウェア開発を一箇所に集約して管理することができます。
単体テストはアプリケーションのコードの個々の単位をテストし、問題を素早く特定し取り去るのに役立ちます。単体テストは、自動化された CI/CD プロセスの1部分を構成することで、バッドコードが本番環境にデプロイされてしまうことを防ぐのにも役立てられます。
多くの AWS CodeStar プロジェクト テンプレートには、単体テストのフレームワークがあらかじめ設定されています。そのため、自信を持ってコードのデプロイを開始することができるでしょう。この AWS CodeStar プロジェクトの単体テストは、ビルドステージにおいて実行されるように設定されているので、もし単体テストがパスしなかったらそのコードがデプロイされることはありません。単体テストを内包している AWS CodeStar プロジェクト テンプレートの一覧については、AWS CodeStar ユーザガイドの AWS CodeStar プロジェクト テンプレートを参照してください。
シナリオ
私はスーパーヒーロー映画の大ファンです。なので、お気に入りの作品を一覧にして友人に投票してもらうウェブサービスを作ろうと思い立ちました。私が使ったのは、AWS Lambda で実行される Python のウェブフレームワークで、ソースコード リポジトリに AWS CodeCommit を使っているテンプレートです。CodeCommit はフルマネージドのソースコントロールサービスです。 Git リポジトリをホストし Git ベースの全てのツールと連携可能です。
ウェブサービスのエンドポイントを作成する方法は次のとおりです。
AWS CodeStar コンソールにサインインし、Start a project を選択します。すると、プロジェクト テンプレートの一覧が表示されます。
コード編集の方法として AWS Cloud9 を選択します。AWS Cloud9 は、コードの記述、実行、デバッグが全て実施可能なクラウドベースの統合開発環境 (IDE) です。
その他に必要な作業は次のとおりです。
- 必要に応じて投票データを保存および取得するためのデータベース テーブルの作成。
- 投票データの保存と取得のために作成された Lambda 関数のロジックの更新。
- (当たり前ですが)上記ロジックが期待通りに動作するかを検証する単体テストの更新。
データベースには Amazon DynamoDB を選択しました。Amazon DynamoDB は高速で柔軟な NoSQL データベースを提供します。
AWS Cloud9 で設定する
AWS CodeStar のコンソールから AWS Cloud9 のコンソールに移動してください。これにより、プロジェクトのコードが表示されます。トップレベルのフォルダでターミナルを開き、環境変数と必要なライブラリをセットします。
PYTHONPATH 環境変数を設定するために、ターミナル上で次のコマンドを実行してください。
プロジェクト内で単体テストを実行できるようにするために次のコマンドを使います。
コーディングを開始する
ローカル環境をセットアップしコードのコピーを手に入れたので、テンプレートファイルで DynamoDB テーブルを定義することによって DynamoDB テーブルをプロジェクトに追加してください。Serverless Application Model (SAM) のテンプレートファイルである template.yml を開いてください。Serverless Application Model (SAM) テンプレートは AWS CloudFormation を拡張して Amazon API Gateway の API、AWS Lambda の関数、そして Amazon DynamoDB のテーブルといったサーバレスアプリケーションで必要となるリソースを定義するためのシンプルな方法を提供します。
AWS サービスと接続するために Python の boto3 ライブラリを使います。それから、単体テストにおける AWS サービスの呼び出しをモックするために Python のモックライブラリを使います。次のコマンドを使ってこれらのライブラリをインストールしてください。
これらのライブラリを buildspec.yml に追加してください。buildspec.yml は、CodeBuild を実行する際に必要な YAML ファイルです。
index.py を開いてください。Lambda 関数のシンプルな投票ロジックをこのファイルに書きます。
上記のコードは、HTTPS リクエストの呼び出しをイベントとして受け取っています。HTTP GET リクエストの場合、投票結果をテーブルから取得します。HTTP POST リクエストの場合は、選択した候補で投票をセットします。また、悪意のあるリクエストを除外するために POST リクエストの中の入力値をバリデーションしています。
このサンプルコードでは投票候補リストを CANDIDATES 変数に保持していますが、そうではなく JSON ファイルに格納し Python の json ライブラリを使うことも可能です。
単体テストを更新してみましょう。tests フォルダ配下で test_handler.py を開いてロジックを検証するように変更してください。
サンプルコードにはコメントを丁寧に残しているので、各単体テストが何をやっているかは分かりやすいと思います。成功条件をテストするとともに、ロジック内で正常に取り扱われる失敗のパスもテストしています。
この単体テストでは、モックライブラリの patch デコレータ (@patch) を使用しています。@patch は、呼び出したい関数をモックするのに役立ちます(今回の場合で言えば、botocore ライブラリの BaseClient クラスの _make_api_call 関数です)。
変更を commit する前に、ローカルでテストを動かしてみましょう。ターミナルで、再度テストを実行してください。もし、全ての単体テストがパスしたらこんな感じの結果を目にすると思われます。
AWS にアップロードする
テストが通ったということは、いよいよコードを commit してリポジトリに push するときがきたということです。
変更を add する
ターミナルでプロジェクトのフォルダに移動し、push するつもりの変更内容を確認するために次のコマンドを使用してください。
変更したファイルのみを add するため、次のコマンドを使用してください。
(訳注: git add の -u オプションは、新規追加されたファイルは除いて、変更のあった部分のみを add します)
変更を commit する
(コミットメッセージを付けて)変更を commit するために、次のコマンドを使用してください。
AWS CodeCommit に変更を push する
commit した変更を CodeCommit に push するために、次のコマンドを使用してください。
AWS CodeStar のコンソールで、変更内容がパイプラインを経由してデプロイされるのを確認することができます。また、AWS CodeStar のコンソールには、このプロジェクトの「ビルド実行」に遷移するリンクがあるので、 AWS CodeBuild 上でテストが実行されるのを見ることができます。Build Runs テーブルの下の最新のリンクをクリックするとログが表示されます。
デプロイが完了すると、AWS Lambda 関数と DynamoDB テーブルが作成されるとともにこのプロジェクトに同期され、 AWS CodeStar で表示されるようになります。AWS CodeStar のナビーションバーにある Project というリンクをクリックすると、このプロジェクトに紐付けられた AWS リソースが表示されます。
新しいデータベーステーブルなので中身は空っぽです。なので何度か投票してみましょう。Postman をダウンロードすれば、アプリケーション エンドポイントの POST と GET の呼び出しをテストすることができます。テストするエンドポイントは AWS CodeStar コンソールの Application endpoints の下に表示されている URL です。
Postman を開いて結果を見てみましょう。POST リクエストで何度か投票を行って見ましょう。今回の例では、正しい投票は A, B, C, または D のうちどれかの値を持ちます。正しい POST リクエストはこんなふうになります。
A, B, C, あるいは D 以外のなんらかの値を使った場合にどのようになるかがこちらです。
それでは、データベースから投票結果を取得するために GET リクエストを利用したいと思います。
以上で終了です。AWS Lambda, Amazon API Gateway, そして DynamoDB を使ってシンプルな投票ウェブサービスを作成しました。そして、ロジックを検証する単体テストを導入しました。そのおかげでグッドコードを ship することができましたね!
Happy coding!
翻訳は SA 畑史彦が担当しました。原文は AWS DevOps Blog の『Performing Unit Testing in an AWS CodeStar Project』です。