この記事の目的
この記事は、
Docker-composeとSeleniumを使って
自動UIテスト環境を一発起動するために試したときのメモ
を目的としています。
要約
WebアプリケーションのUIテストを自動化したい。
できれば、テストは仮想環境で実行して、あとから結果(スクショ)を確認したい。
仮想環境はコンテナを使って、マルチ実行を用意にできるようにしたい。
CI(継続的インテグレーション)に組み込みたい。
という考えのもと、SeleniumとDockerを使って環境を用意しました。
www.kinakomotitti.net
今回は、前回の結果を改良して、Docker-Composeを使って
環境用意からテスト実行までをコマンド一発でやれる仕組みを実装しました。
やったことは、以下の2点です。
・dokcer-composeファイルの作成
・dockerコンテナの起動順序保証用のbashスクリプトの作成。
前回同様、最終的なソリューションは以下のGithubに登録してあります。
github.com
本題
★docker-compose.ymlの作成
Visual Studioの「コンテナーオーケストレーターのサポート追加」
前回は、【Dockerサポート】を追加して、DockerFileのひな型を作成しました。
今回は、Docker-Compose.ymlのひな型を作成します。
docker-compose.ymlの編集
デフォルトでは、サポートを追加したプロジェクトのイメージだけを対象としたymlが作成されます。今回は、このプロジェクト(Seleniumクライアント)だけではなく、テスト実行環境(Seleniumサーバ)のイメージも必要となるので、それの定義を追加します。
version: '3.4' services: unittestproject: #Seleiumクライアントといっているコンテナ image: ${DOCKER_REGISTRY-}unittestproject build: context: . #カレントディレクトリは、docker-compose.ymlの場所を指定 #Dockerfileの場所の指定に注意が必要 dockerfile: UnitTestProject/Dockerfile volumes: - ./UnitTestProject/mnt/images:/app/images - ./UnitTestProject/mnt/result:/app/result networks: - selenium-test-nw depends_on: #SeleniumServerが起動していないとだめなので、依存関係を設定 #だたし、必ずしも起動が保証されるわけではないので、Bashスクリプトで別途保証する。 - selenium-server environment: #コードに直打ちしておくのが嫌だったので、環境変数として外出し。 - WEB_DRIVER_HOST=unittestproject_selenium-server_1 #Seleniumサーバのホスト名 - RESULT_DIR=/app/result - IMAGE_DIR=/app/images - EXECUTE_TEST_MODULE=UnitTestProject.dll #テスト実行モジュール名 selenium-server: #Seleiumサーバといっているコンテナ image: selenium/standalone-chrome-debug #今回は、Chromeが利用できるコンテナを利用 ports: - 4444:4444 - 5900:5900 networks: - selenium-test-nw networks: selenium-test-nw: external: false
よくあることですが、depens_onでは、
コンテナの実行順序(コンテナのステータスがcreatedになる順番)は保証されますが、
コンテナの起動完了順序(コンテナのステータスがrunningになる順番)は保証されません。
今回は、起動完了の順序も保証したいので、別途bashスクリプトを作成して対応します。
There are several things to be aware of when using depends_on:
depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started.
If you need to wait for a service to be ready,
see Controlling startup order for more on this problem and strategies for solving it.
★起動順序保証.bashの作成
ファイルの作成
前のステップで用意したdocker-composeファイルにより、
UnitTestプロジェクト(Seleniumクライアント)のコンテナが起動した後、
Seleniumサーバの起動が完了するまでテスト実行を保留するスクリプトを作成します。
このスクリプトは、UnitTestプロジェクト(Seleniumクライアント)起動時に
コンテナの中で実行される必要があります。
そのため、UnitTestプロジェクト(Seleniumクライアント)のイメージを作成(docker build)する際に
COPYしやすい場所にファイルを作成します。
※DockerFileにパスを指定すればよいので、任意の場所に作成すればよいですね・・・
スクリプトの実装
#!/bin/bash for i in {1..10} ; do #実行中の情報を表示する echo $i #テスト実行環境(Seleniumサーバ)の起動状態を、CURLを使って状態を確認する(待機ポイント) if [ `curl http://$WEB_DRIVER_HOST:4444/ -o /dev/null -w '%{http_code}\n' -s` = 200 ]; then #テスト開始フラグファイルを作成する(これは不要かも) echo start >> /app/result/test-start.flag #実行環境にインストールされたdotnetバージョンを確認する(デバッグ用) dotnet --version #テストを実行する dotnet vstest $EXECUTE_TEST_MODULE --logger:"trx;LogFileName=test.trx" --ResultsDirectory:/app/result #テスト完了フラグファイルを作成する(これは不要かも) echo start >> /app/result/test-end.flag exit fi #1回6S、最大60秒間待機する。 sleep 6 done
上記のコメント以外では、環境変数を使って・・・
・vstestの実行対象モジュールの変更を容易にする
・テスト実行環境(Seleniumサーバ)のホスト名の変更を容易にする
といったことをしています。
DockerFileの修正
上記の待機bashを追加するために、前回作成したDockerFileを修正します。
※差分だけ表示しています。
#前回 CMD ["dotnet","vstest","UnitTestProject.dll"] #今回 RUN tr '\r' '\n' < wait-for-selenium-server.bash > edited_file.bash CMD ["bash","edited_file.bash"]
変更点としては、改行コードの修正処理の追加と、コンテナ起動時のコマンドでした。
Seleniumクライアントとして利用しているベースイメージはLinuxなので、
改行コードはLFとなっています。
VisualStudioで作成したbashスクリプトはCRLFなので、
ファイルをそのままコピーして実行しようとすると、エラーが発生しました。
そのため、ここを参考に、上記コマンドを追加して、改行コードの変更をしています。
コマンドの変更点は、これまで引数で、テスト対象のモジュールを指定していたところや、
dotnetコマンドを直打ちしていたところを修正しました。
なお、bashファイルは、「出力ディレクトリにコピー」設定をしていたので、
COPYコマンド周りの設定の変更はありませんでした。