Amazon Web Services ブログ

AWS CodePipeline, AWS CodeBuild, AWS Lambdaを使ったサーバーレス自動UIテスト

Webアプリケーションのユーザーインターフェイスをテストすることは、開発ライフサイクルの重要なパートです。 この記事では、 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のテストケースを作成しています。

この記事で紹介するAWS CloudFormationテンプレート、S3でホストされているテストおよびステータスWebサイト、AWS CodeBuildビルドスペックファイル、AWS Lambdaファンクション、テストを行うPythonスクリプトなどのリソースは、 serverless-automated-ui-testing GitHubリポジトリで公開しています。

 

S3にホストされるテストWebサイト: AWS CodeBuildはカスタムコンテナをサポートしているため、FirefoxとChromeブラウザのプレビルドを含むSelenium/standalone-FirefoxとSelenium/standalone-Chromeコンテナをそれぞれ使用できます。 Xvfbは、ディスプレイハードウェアなしで仮想メモリ内でグラフィカルオペレーションを実行します。 XvfbはインストールフェーズでCodeBuildコンテナにインストールされます。

 

Chrome and Firefoxテスト用のビルドスペック
ChromeとFirefoxのテストのビルドスペックには、複数のフェーズがあります:

  • 環境変数セクションには、ビルドプロジェクトの作成時またはビルドのトリガー時にオーバーライドされる一連のデフォルト変数が含まれます。
  • インストールフェーズの一部として、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千葉が担当しました。原文はこちら)