きなこもち.net

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

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

この記事の目的

この記事は、
DockerとSeleniumを使って自動UIテストを試したときのメモ
を目的としています。
Seleniumとは
oss.infoscience.co.jp


要約

WEBアプリケーションのCIを構築するうえで、考えなければいけないことの一つに、画面を操作して確認するテストがあります。従来は、あらかじめ用意していたテスト手順に従い、手動でテストを実行し、1操作ごとに、スクリーンショットをとり、Excelに張っていく・・・という作業で実現していました。
これに対し、Seleniumが登場したことにより、テスト手順(Seleniumライブラリを使ったプログラミング)を用意して、実行することで自動でテストを実行することができるようになりました。
しかし、Seleniumを実行する環境をローカルで用意しておくと、テストケース増加したときに、テスト実行環境を増やしたいと思ったときにさっと増やすことができないということがあります。
ということで、簡単に環境を用意するために、Dockerを使って、Seleniumによる自動UIテスト環境を用意しようと思いました。

今回は、Helloworldということで、Dockerに設定したSelenium実行環境の中で、このブログをGoolge検索するところまで動かしてみました。とりあえず動くところまでをゴールとしていますが、後々は、CIに組み込めるようにしていきたいと考えています。

・・・ということで、今後こんな構成でできるところまでもっていきたいの図↓
f:id:kinakomotitti:20190630180455p:plain

追記)サンプルソースはここで管理しています。
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で接続すると、コンテナにアクセスできます。
f:id:kinakomotitti:20190630180511p:plain
※途中で聞かれるパスワードは[secret]です。
接続を維持しておくと、後々Seleniumを実行したときに
ブラウザが動いているところを確認できます。

★テストプロジェクトの準備

Visual Studio 2019を起動

起動しないと始まらない・・・


MS Test テストプロジェクト(.NET core)の作成

今回は、Linuxコンテナの上で動作できるプロジェクトにしたいので、
,NET Core版のMS Testプロジェクトを選択します。
※.NET core 3.0で進めています。
f:id:kinakomotitti:20190630180523p:plain


Nuget Packageの取得

Seleniumのコードを実装・実行するために必要なNuGetパッケージをインストールします。
Selenium Web Driverだけだと、Selenium Serverへ接続する際に、
Newtonsoft.Jsonがないというエラーが発生して失敗したので、インストールしています。
f:id:kinakomotitti:20190630180532p:plain


テストコードの実装

テストコードを実行します。
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にコピーすることができます。

★動作確認

DockerFileと同じフォルダにて、以下のコマンドを実行して動作確認を行います。

#test(:latest)という名前でイメージを作成。
 docker build . -t test

#終わったら消えるようにrmオプションを指定。
 docker run --rm -it test

テストが実行されると、VNC Viewerで接続しているコンテナで、
Chromeが動作し、Googleで検索を始める様子を確認することができます。

動作に失敗した場合や、テスト結果については、
標準出力から確認することができます。

まとめ

Selenium をDockerで実行することで、
煩雑なSeleniumサーバーやクライアントの設定作業がなしで、
自動UIテスト環境を構築することができます。
テストケースの増加に伴い、Selenium クライアントを増やしたいと思ったとき、
新しいコンテナを起動させるだけで対応することができます。

これって、CIに非常に向いていると思います(=゚ω゚)ノ
引き続き調べていこう。そうしよう。