Selenium WebDriver で Web アプリのテストを自動化中
開発部の本橋です。
ブラウザ自動化ツールの Selenium WebDriver を使って Web アプリケーションのテスト自動化を試しています。
今回は弊社 Web サイトを例として、Python3 を使って Google Chrome を操作してみます。
の前に Selenium WebDriver とは
一言で言えば Web ブラウザ自動化ツールです。以前提供されていた Selenium RC のアーキテクチャはすでに非推奨となり、現在は Selenium WebDriver の開発が活発に行われています。
Selenium WebDriver は W3C で WebDriver として標準化されています。
Selenium WebDriver の Python バインディング
Selenium WebDriver は様々なプログラミング言語で利用できますが、今回は Python3 を使いました。ドキュメントはこちらを参考に。
https://seleniumhq.github.io/selenium/docs/api/py/api.html
環境構築
必要なものをインストールします。Mac で Homebrew を使うことを想定しています。
- Python3 をインストール
- Homebrew なら
brew install python3
- Homebrew なら
- Google Chrome をインストール
- Homebrew なら
brew cask install google-chrome
- Homebrew なら
- ChromeDriver をインストール
- Homebrew なら
brew install chromedriver
- Homebrew なら
- selenium の Python バインディングをインストール
- pip なら
sudo pip3 install selenium
- pip なら
Selenium WebDriver 基本
アサーションはひとまず置いといて、Selenium WebDriver を使ってみます。
www.google.co.jp
で「株式会社Knowlbo」を検索し、トップページから会社案内ページへ遷移してみます。
# selenium_test.py from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() # Google で Knowlbo を検索 driver.get('https://www.google.co.jp') elem = driver.find_element(By.NAME, 'q') elem.send_keys('株式会社Knowlbo') elem.send_keys(Keys.RETURN) # www.knowlbo.co.jp へのリンクが表示されるまで待ち、遷移 WebDriverWait(driver, 10) \ .until(EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, '株式会社ナルボ'))) \ .click() # www.knowlbo.co.jp のページが表示されるまで待ち、会社案内ページに遷移 WebDriverWait(driver, 10) \ .until(EC.title_contains('株式会社ナルボ')) driver.find_element(By.LINK_TEXT, '会社案内') \ .click()
$ python3 selenium_test.py
unittest モジュールと組み合わせる
次は unittest
モジュールを使ってアサーションしてみます。(www.google.co.jp
からの遷移は省略します。)
# selenium_test3.py import unittest from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class WedDriverTest(unittest.TestCase): def _to_knowlbo(self): # トップページへ遷移 driver.get('https://www.knowlbo.co.jp') WebDriverWait(driver, 10) \ .until(EC.title_contains('株式会社ナルボ')) def setUp(self): self._to_knowlbo() def test_company_page_link(self): # トップページに会社案内のリンクが表示されることのアサーション elem = driver.find_element(By.LINK_TEXT, '会社案内') self.assertIsNotNone(elem, 'トップページに会社案内のリンクが表示されること') def test_company_page_content(self): # 会社案内ページへ遷移 driver.find_element(By.LINK_TEXT, '会社案内') \ .click() WebDriverWait(driver, 10) \ .until(EC.title_contains('会社案内')) # 会社案内ページの内容のアサーション elem = driver.find_element(By.CSS_SELECTOR, '.page-title') self.assertEqual(elem.text, '会社案内', '会社案内ページが表示されること') def tearDown(self): pass if __name__ == '__main__': driver = webdriver.Chrome() unittest.main()
$ python3 selenium_test2.py .. ---------------------------------------------------------------------- Ran 2 tests in 11.026s OK
gif
Chrome を自動操作している gif 動画を取ってみました。イメージ伝わりますかね。
WebDriver は動作に Web ブラウザが必要なのでCIと組み合わせるのは厳しい気がしますが、この調子でどんどん自動化していけたらいいなと思います。
自作の ASP.NET アプリを乗せた Windows コンテナをビルドする
開発部の本橋です。
Windows コンテナで ASP.NET (4.6) Web アプリを実行しようとしてみたら意外と簡単にできたのでメモっておきます。
Web アプリを用意
簡単な Web アプリを用意します。今回は以下のような仕様としました。
- ASP.NET MVC 5 (.NET Framework 4.6.2) で実装。
- テキストエリアに任意の文字列を入力可能。
- “POST” ボタンをクリックするとサーバー上にテキストファイルを出力。
- 出力したテキストファイルはブラウザからアクセス可能。
コード
コントローラーとビューのコードは以下のようにしました。(ASP.NET MVC プロジェクトの作り方は省略します。)
// コントローラー using System.IO; using System.Web.Mvc; namespace MyWebApp.Controllers { public class HomeController : Controller { // GET: Home/Index // POST: Home/Index public ActionResult Index() { if (this.Request.HttpMethod.ToLower() == "post") { var text = this.Request.Form["text"]; var path = Path.Combine(this.Request.PhysicalApplicationPath, "out.txt"); using (var sw = new StreamWriter(path, false)) { sw.Write(text); } var appPath = this.Request.ApplicationPath.EndsWith("/") ? this.Request.ApplicationPath : this.Request.ApplicationPath + "/"; this.ViewBag.file = appPath + "out.txt"; } return this.View(); } } }
// ビュー @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div> <form action="~/" method="post"> <textarea name="text"></textarea> <button type="submit">POST</button> </form> @if (this.ViewBag.file != null) { <a href="@this.ViewBag.file" target="_blank">@this.ViewBag.file</a> } </div> </body> </html>
コンテナイメージを作る
Web アプリを発行
上記のコードをどこかのフォルダに発行します。今回は “C:\_work\MyWebApp\app” フォルダに発行したとして進みます。
Dockerfile
dockerhub のマイクロソフト公式アカウントに microsoft/aspnet というコンテナイメージがあるのでこれを使うと簡単です。
以下の内容を “C:\_work\MyWebApp\Dockerfile” として保存します。
FROM microsoft/aspnet:4.6.2 RUN mkdir c:\inetpub\wwwroot\MyWebApp COPY app\* c:/inetpub/wwwroot/MyWebApp RUN powershell -Command "New-WebApplication -Site 'Default Web Site' -Name 'MyWebApp' -PhysicalPath 'c:\inetpub\wwwroot\MyWebApp' -ApplicationPool 'DefaultAppPool'" \ && icacls c:\inetpub\wwwroot\MyWebApp /grant IIS_IUSRS:F
やってることは簡単で、
- 発行した Web アプリをコンテナにコピー
- Web アプリケーションを作成
- フォルダにアクセス権限を与える
です。COPY
命令のコピー先フォルダのパス区切り文字は \
でなく /
にする必要があるので気をつけます。
また、今回はコンテナ上にファイルを出力するため Web アプリケーションの物理フォルダに書き込めるようアクセス権限を設定します。
注:通常、コンテナ上に永続的な目的のファイルを出力するべきではありません。今回は実装の簡略化のためにコンテナ上に出力していますが、本来はホストのファイルシステムをマウントしたり、データボリュームコンテナを利用したりします。
コンテナイメージをビルド
docker build
コマンドでイメージをビルドします。ベースイメージである microsoft/aspnet
の容量が10GBほどあるため、キャッシュがない場合は結構時間がかかります。
cd c:\_work\MyWebApp docker build -t mywebwpp .
実行
docker run
コマンドでビルドしたコンテナを実行します。
docker run -d mywebapp
ブラウザでアクセスしてみましょう。
“POST” ボタンをクリック↓
“/MyWebApp/out.txt” のリンクをクリック↓
ちゃんと動いている事が確認できます。これで自作の Web アプリケーションを Windows コンテナで実行できました!
Docker for Windows 1.13.0 が出たので Linux コンテナと Windows コンテナの切り替え機能を試してみる
開発部の本橋です。
Docker 1.13.0 の安定版がリリースされました。それに伴って Docker for Windows 1.13.0 の安定版もリリースされています。
従来 Linux コンテナと Windows コンテナの共存は「出来なくはないがとても面倒」な状況でしたが、Docker for Windows 1.13.0 では簡単に共存、そして切り替えが出来るようになりました。ということで早速使ってみました。
コンテナの切り替え
タスクトレイの Docker アイコン右クリックすると「Switch to Windows Containers…」 または 「Switch to Linux Containers…」 というメニューが出て来るのでクリックします。
数秒時間がかかりますが、「Docker is switching…」のアイコンが消えれば完了です。
どっちのコンテナを使っているか?
docker version
の出力の Server の OS/Arch でわかります。
Linux コンテナの場合は「linux/amd64」となっています。
> docker version Client: Version: 1.13.0 API version: 1.25 Go version: go1.7.3 Git commit: 49bf474 Built: Wed Jan 18 16:20:26 2017 OS/Arch: windows/amd64 Server: Version: 1.13.0 API version: 1.25 (minimum version 1.12) Go version: go1.7.3 Git commit: 49bf474 Built: Wed Jan 18 16:20:26 2017 OS/Arch: linux/amd64 Experimental: true
Windows コンテナの場合は「windows/amd64」となっています。
>docker version Client: Version: 1.13.0 API version: 1.25 Go version: go1.7.3 Git commit: 49bf474 Built: Wed Jan 18 16:20:26 2017 OS/Arch: windows/amd64 Server: Version: 1.13.0 API version: 1.25 (minimum version 1.24) Go version: go1.7.3 Git commit: 49bf474 Built: Wed Jan 18 16:20:26 2017 OS/Arch: windows/amd64 Experimental: true
Linux コンテナ
ごく普通に使えます。
> docker pull debian > docker run -it debian /bin/bash (ここからコンテナ) # uname -a Linux 9c4b258fd680 4.9.4-moby #1 SMP Wed Jan 18 17:04:43 UTC 2017 x86_64 GNU/Linux
Windows コンテナ
こちらもごく普通に使えますね。
> docker pull microsoft/windowsservercore > docker run -it microsoft/windowsservercore cmd (ここからコンテナ) > systeminfo Host Name: E631F61C1E29 OS Name: Microsoft Windows Server 2016 Datacenter OS Version: 10.0.14393 N/A Build 14393 OS Manufacturer: Microsoft Corporation OS Configuration: Standalone Server (略)
images とか ps
docker images
や docker ps
で見えるイメージやコンテナの一覧は現在有効な方しか表示されないようです。
> docker images REPOSITORY TAG IMAGE ID CREATED SIZE debian latest e5599115b6a6 8 days ago 123 MB (ここで切り替え) > docker images REPOSITORY TAG IMAGE ID CREATED SIZE microsoft/aspnet latest e761eca2f8df 6 days ago 10.1 GB microsoft/windowsservercore latest 4d83c32ad497 2 weeks ago 9.56 GB
コンテナが動いている時に切り替えると?
ステータスが「Up」のコンテナがあるときに切り替えても「Exited」になったりはしないようです。ただし docker ps
してもコンテナは見えません。
> docker run -d -p 8081:80 nginx (ブラウザで http://localhost:8081 にアクセスすると nginx がちゃんと返してくれる) (ここで切り替え) (切り替え後も nginx はちゃんと返してくれる) (ただし ps しても nginx は見えない) > docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e631f61c1e29 microsoft/windowsservercore "cmd" 11 minutes ago Up 10 minutes festive_boyd
Linux コンテナも Windows コンテナも両方気軽に使えるようになりました!