Amazon Web Services ブログ
AWS CodePipeline, AWS CodeBuild, AWS Lambdaを使ったサーバーレス自動UIテスト
S3でホストされているUIテスト用のWebサイトを構築しました。Seleniumを使用して、Chrome、Firefox、PhantomJS、およびWebDriver Wire Protocolの実装であるGhost DriverのヘッドレスWebKitブラウザで、クロスブラウザのUIテストを実行します。 テストが実行されているブラウザに基づいて、Pythonを使ってChromeDriver、FirefoxDriver、またはPhatomJSDriverのテストケースを作成しています。
- 環境変数セクションには、ビルドプロジェクトの作成時またはビルドのトリガー時にオーバーライドされる一連のデフォルト変数が含まれます。
- インストールフェーズの一部として、XvfbやSeleniumなどの必須パッケージがyumを使用してインストールされます。
- pre_buildフェーズでは、テスト実行のためにテストベッドが準備されます。
- ビルドフェーズでは、適切なDISPLAYが設定され、テストが実行されます。
version: 0.2
env:
variables:
BROWSER: "chrome"
WebURL: your s3 url
ArtifactBucket: "codebuild-demo-artifact-repository"
MODULES: "mod1"
ModuleTable: "test-modules"
StatusTable: "blog-test-status"
phases:
install:
commands:
- apt-get update
- apt-get -y upgrade
- apt-get install xvfb python python-pip build-essential -y
- pip install --upgrade pip
- pip install selenium
- pip install awscli
- pip install requests
- pip install boto3
- cp xvfb.init /etc/init.d/xvfb
- chmod +x /etc/init.d/xvfb
- update-rc.d xvfb defaults
- service xvfb start
- export PATH="$PATH:`pwd`/webdrivers"
pre_build:
commands:
- python prepare_test.py
build:
commands:
- export DISPLAY=:5
- cd tests
- echo "Executing simple test..."
- python testsuite.py
Ghost Driverはヘッドレスで動作するため、AWS Lambdaで実行できます。 Fire-and-forgetモデルに合わせて、CodeBuildを使ってPhantomJS Lambdaファンクションを作成し、Lambdaのテスト実行を並行して起動します。Lambdaで多くのテストを並行して実行できることは強力な機能です。
PhantomJS用のビルドスペック
PhantomJSテストのビルドスペックにも、複数のフェーズが含まれています。テスト実行にAWS Lambdaを使用しているため、前の例と少し異なります。
- 環境変数セクションには、ビルドプロジェクトの作成時またはビルドのトリガー時にオーバーライドされる一連のデフォルト変数が含まれます。
- インストールフェーズの一部として、SeleniumやAWS CLIなどの必須パッケージがyumを使用してインストールされます。
- pre_buildフェーズでは、テスト実行のためにテストベッドが準備されます。
- ビルドフェーズでは、PhantomJS Lambdaファンクションの作成に使用されるzipファイルが作成され、Lambdaファンクションでテストが実行されます。
version: 0.2
env:
variables:
BROWSER: "phantomjs"
WebURL: "https://sampletestweb.s3-eu-west-1.amazonaws.com/website/index.html"
ArtifactBucket: "codebuild-demo-artifact-repository"
MODULES: "mod1"
ModuleTable: "test-modules"
StatusTable: "blog-test-status"
LambdaRole: "arn:aws:iam::account-id:role/role-name"
phases:
install:
commands:
- apt-get update
- apt-get -y upgrade
- apt-get install python python-pip build-essential -y
- apt-get install zip unzip -y
- pip install --upgrade pip
- pip install selenium
- pip install awscli
- pip install requests
- pip install boto3
pre_build:
commands:
- python prepare_test.py
build:
commands:
- cd lambda_function
- echo "Packaging Lambda Function..."
- zip -r /tmp/lambda_function.zip ./*
- func_name=`echo $CODEBUILD_BUILD_ID | awk -F ':' '{print $1}'`-phantomjs
- echo "Creating Lambda Function..."
- chmod 777 phantomjs
- |
func_list=`aws lambda list-functions | grep FunctionName | awk -F':' '{print $2}' | tr -d ', "'`
if echo "$func_list" | grep -qw $func_name
then
echo "Lambda function already exists."
else
aws lambda create-function --function-name $func_name --runtime "python2.7" --role $LambdaRole --handler "testsuite.lambda_handler" --zip-file fileb:///tmp/lambda_function.zip --timeout 150 --memory-size 1024 --environment Variables="{WebURL=$WebURL, StatusTable=$StatusTable}" --tags Name=$func_name
fi
- export PhantomJSFunction=$func_name
- cd ../tests/
- python testsuite.py
各ケースに属するテストケースとテストモジュールのリストは、Amazon DynamoDBテーブルに格納されています。
CodeBuildプロジェクトに引数として渡されたモジュールのリストに基づいて、CodeBuildはそのテーブルからテストケースを取得し実行します。テストの実行状況と結果は別のAmazon DynamoDBテーブルに保存されます。 DynamoDBのステータステーブルからテストステータスを読み取り、表示します。
AWS CodeBuildとAWS Lambdaはテストを個別のタスクとして実行します。 AWS CodePipelineは、継続的デリバリーと並列実行によるテストの最適化を可能にするという点で、重要な役割を果たします。
AWS CodePipelineには、以下の4つのステージを持ったパイプラインが作られます:
- Source (AWS CodeCommit)
- UI testing (AWS Lambdaと AWS CodeBuild)
- Approval (手動承認)
- Production (AWS Lambda)
次の図に、パイプラインステージ、各ステージのアクション、およびステージ間の遷移を示します。
AWS CodePipelineで実装されるデザインは、次のようになります。
CodePipelineはソースリポジトリの変更を自動的に検出し、パイプラインの実行をトリガします。
UITestステージには、2つの並列アクションがあります:
- DeployTestWebsiteは、S3にテストウェブサイトを展開するためのLambdaファンクションを呼び出します。
- DeployStatusPageは別のLambdaファンクションを呼び出して、ステータスWebサイトをS3に並列にデプロイします。
次に、CodeBuildプロジェクトを起動する3つの並行アクションがあります:
- TestOnChromeは、Chrome上でSeleniumテストを実行するためのコンテナを起動します。
- TestOnFirefoxは、FirefoxでSeleniumテストを実行する別のコンテナを起動します。
- TestOnPhantomJSはLambdaファンクションを作成し、テストケースごとに個別のLambdaファンクションを呼び出して、テストケースを並列実行します。
次の図のように、ステータスWebサイトでテスト実行のステータスを監視できます:
UIテストが正常に完了すると、パイプラインはApprovalステージに進み、通知が構成済みのSNSトピックに送信されます。指名されたチームメンバーは、テストのステータスを確認し、デプロイを承認または拒否します。承認されると、パイプラインはProductionステージに進み、そこでLambdaファンクションを呼び出し、ウェブサイトをプロダクションS3バケットに配備します。
は、CloudFormationテンプレートを使用して、継続的デリバリーパイプラインを設定しました。 GitHubから入手できるautomated-ui-testing.yamlテンプレートを利用して全機能のパイプラインを設定することが可能です。
テンプレートを使用してパイプラインを作成するときは、次の項目を指定します:
- AWS CodeCommitリポジトリ
- 承認通知を送信するSNSトピック
- 成果物が格納されるS3バケット名
スタック名は、S3バケット名の一部になるため、S3バケット命名規則に従ってください。
スタックが正常に作成されると、次のようにテストWebサイトとステータスWebサイトのURLが[Outputs]セクションに表示されます:
まとめ
この記事では、AWS CodePipeline、AWS CodeBuild、AWS Lambda、および手動承認プロセスを使用してサーバーレス自動UIテスト用の継続的デリバリーパイプラインを作成する方法をご紹介しました。 Amazon EC2インスタンスまたはAWS Elastic Beanstalk上で実行されるWebサイトも同様の方法でテストできます。
著者紹介
Prakash PalanisamyはAmazon Web ServicesのSolutions Architectです。 Serverless、DevOps、Alexaを担当する他、Project Eulerでの問題解決をおこなっています。彼はまた、教育ドキュメンタリーを見て楽しんでいます。
(翻訳はSA千葉が担当しました。原文はこちら)