きなこもち.net

.NET Framework × UiPath,Orchestrator × Azure × AWS × SIer

Docker-Compose×Selemium×自動UIテスト試してみた

この記事の目的

この記事は、
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のひな型を作成します。


f:id:kinakomotitti:20190704103156p:plain

コンテナーオーケストレーターのサポート追加


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コマンド周りの設定の変更はありませんでした。

f:id:kinakomotitti:20190704113416p:plain
bashファイルのプロパティ(詳細部)


★その他やったこと、やってないこと

やったこと

テストコードのリファクタリングをしました。
一部、直打ちしていた環境依存の設定情報を環境変数を参照するようにしたり、
よく実装するコードを共通メソッドとして定義したりしました。
きなこもち用Seleniumということで、Keleniumとか名前つけてますが、
センスがなさ過ぎて引きますね。

やってないこと

テスト完了時に、自発的にdocker-compose downしてくれる仕組みを導入したかったですが、
優先度はあまり高くないので、保留としています。
いつかやるw

まとめ

「docker-compose up -d」で自動UIテスト環境構築~テスト実行までを1発起動することができました。
ハイライトは以下の点です。
・極力DockerImageのビルド回数を減らすために、設定値を環境変数に外だし
bashスクリプトで、依存があるコンテナの起動確認+待機処理を実行
bashスクリプトの改行コードを修正