要約
WEBアプリケーションのCIを構築するうえで、考えなければいけないことの一つに、画面を操作して確認するテストがあります。従来は、あらかじめ用意していたテスト手順に従い、手動でテストを実行し、1操作ごとに、スクリーンショットをとり、Excelに張っていく・・・という作業で実現していました。
これに対し、Seleniumが登場したことにより、テスト手順(Seleniumライブラリを使ったプログラミング)を用意して、実行することで自動でテストを実行することができるようになりました。
しかし、Seleniumを実行する環境をローカルで用意しておくと、テストケース増加したときに、テスト実行環境を増やしたいと思ったときにさっと増やすことができないということがあります。
ということで、簡単に環境を用意するために、Dockerを使って、Seleniumによる自動UIテスト環境を用意しようと思いました。
今回は、Helloworldということで、Dockerに設定したSelenium実行環境の中で、このブログをGoolge検索するところまで動かしてみました。とりあえず動くところまでをゴールとしていますが、後々は、CIに組み込めるようにしていきたいと考えています。
・・・ということで、今後こんな構成でできるところまでもっていきたいの図↓
追記)サンプルソースはここで管理しています。
github.com
本題
★SeleniumServerのDokcerImageの準備
selenium/standalone-chrome-debug
まず、あらかじめ、自動UIテストを実行するDockerコンテナを作成します。
上図の、タコの右手のコンテナにあたります。
今回利用するブラウザは、Chromeです。
SeleniumのDockerHubから、Chrome用のSelenium実行環境を持ったDocker Imageを取得し、
コンテナを起動します。
hub.docker.com
docker pull selenium/standalone-chrome-debug docker run -d -p 4444:4444 -p 5900:5900 --shm-size=2g --name sscd selenium/standalone-chrome-debug
VNC Viewerの準備
前のステップで起動したコンテナには、VNCサーバが含まれています。
そのため、VNCViewerを使うことでコンテナに接続できます。
www.realvnc.com
これで、localhost:5900で接続すると、コンテナにアクセスできます。
※途中で聞かれるパスワードは[secret]です。
接続を維持しておくと、後々Seleniumを実行したときに
ブラウザが動いているところを確認できます。
★テストプロジェクトの準備
Visual Studio 2019を起動
起動しないと始まらない・・・
MS Test テストプロジェクト(.NET core)の作成
今回は、Linuxコンテナの上で動作できるプロジェクトにしたいので、
,NET Core版のMS Testプロジェクトを選択します。
※.NET core 3.0で進めています。
Nuget Packageの取得
Seleniumのコードを実装・実行するために必要なNuGetパッケージをインストールします。
Selenium Web Driverだけだと、Selenium Serverへ接続する際に、
Newtonsoft.Jsonがないというエラーが発生して失敗したので、インストールしています。
テストコードの実装
テストコードを実行します。
Googleにアクセスし、このブログのトップページを検索することができたら成功。
できなかったら失敗。
というちょっとしたコードになっています。
一か所、修正が必要になります。
IWebDriver のインスタンスを生成するときの、
Remote Web DriverのURLですが、
localhost(タコの左:自分自身)に対して接続しようとしています。
接続先は、先のステップで起動しておいたVNCサーバを含んだコンテナ(タコの右)なので、
そのコンテナのIPアドレスに変更する必要があります。
接続先のIPアドレスは、以下のコマンドなどで取得することができますし、
VNC Viewerの接続が維持されていたら、
そこから操作することで、IPアドレスを取得することができます。
docker exec -it <container id> hostname -i
using Microsoft.VisualStudio.TestTools.UnitTesting; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Remote; using System; namespace UnitTestProject { [TestClass] public class UnitTest1 { public static object Assertion { get; private set; } [TestMethod] public void TestMethod1() { IWebDriver driver = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"), new ChromeOptions()); // ← ここ try { driver.Navigate().GoToUrl("https://www.google.com"); driver.FindElement(By.ClassName("gLFyf")).SendKeys("きな粉餅,net"); driver.FindElement(By.ClassName("gLFyf")).SendKeys(Keys.Enter); driver.FindElement(By.TagName("h3")).Click(); var actual = driver.FindElement(By.TagName("h1")).Text; var expected = "きなこもち.net"; Assert.AreEqual(expected, actual); } catch (Exception ex) { Console.WriteLine(ex.GetBaseException().ToString()); throw ex; } finally { driver.Quit(); } } } }
DockerFileの追加と修正
Visual Studioの「Dockerサポートの追加」をして、
DockerFileをプロジェクトに作成します。
そのままの設定では利用することができないので、
以下のように設定を変更します。
#テスト実行には、SDKが必要 FROM mcr.microsoft.com/dotnet/core/sdk:3.0-stretch WORKDIR /app #日本語対応は必須ではないが、出力結果が日本語になるので追加。 RUN apt-get update && apt-get install -y apt-utils && apt-get install -y locales && apt-get install -y vim && locale-gen ja_JP.UTF-8 && localedef -f UTF-8 -i ja_JP ja_JP.utf8 ENV LAND=ja_JP.UTF-8 ENV LANG ja_JP.UTF-8 ENV LC_CTYPE ja_JP.UTF-8 #コンパイルした結果だけをコンテナに追加 COPY ["./bin/Debug/netcoreapp3.0/", "/app"] #DLLを利用したテストの実行は、vstestオプションを利用する。 CMD ["dotnet","vstest","UnitTestProject.dll"]
デフォルトで生成されるDockerFileのように、
コンテナ内でテストプロジェクトをビルドし、
ビルド結果だけをコンテナに残すようにする手段だと、
ビルド時に、Unit Testのクラスが認識されず、
実行可能なテストがないDLLが生成されてしまいました。
その対応として、Docker Fileには、開発端末でビルドが成功したときに生成されたDLLを
コピーするように設定をしています。
DockerBuild前に、一度プロジェクトのビルドをしないといけないという手間が発生しますが、
これで、テストを含んだDLLをDocker Imageにコピーすることができます。