サマリ
SeleniumとPytestでブラウザ自動テストをしようとすると、テスト実行をするまでの環境構築がそれなりに面倒。ブラウザを入れ、ブラウザのバージョンに合ったwebdriverを入れ、Pythonを入れ、Pytestを入れ…としていると、インストールだけで数時間近く経ってしまうことも。
そこで今回はDocker Composeを使い、SeleniumとPytestの実行環境立ち上げを簡略化していく。インスタントにブラウザテストの実行環境がほしい場合や、プロジェクト内で実行環境を統一したい場合などに参考にしてほしい。
システム構成
Docker Composeで以下の2つのコンテナを立ち上げ、コンテナ間をリモートで接続する。
- chrome (Chrome+Selenium実行環境)
- pytest (Pytest実行環境)
chromeコンテナにはselenium/standalone-chrome-debugを利用する。これはSelenium公式が提供しているイメージで、その名の通りスタンドアローンでChrome + Seleniumが実行できる。(内部的にはSelenium Grid Hubに1ノードのChromeが接続されている)
pytestコンテナはDocker公式のpythonイメージをベースに自分でDockerfileを記述しビルドする。
ファイル構成
ローカル作業ディレクトリ
docker-pytest
├── Dockerfile_pytest
├── docker-compose.yml
├── screenshots
└── tests
└── test_google.py
pytestコンテナ内部ディレクトリ
/
└── docker-pytest
├── screenshots
└── tests
└── test_google.py
各ファイルの中身
docker-compose.yml
version: "3"
services:
chrome:
image: selenium/standalone-chrome-debug:4.0.0-alpha-7-prerelease-20200826
container_name: chrome
volumes:
- /dev/shm:/dev/shm
ports:
- 4444:4444
- 5900:5900
pytest:
build:
context: ./
dockerfile: Dockerfile_pytest
container_name: pytest
volumes:
- ./screenshots:/docker-pytest/screenshots/
tty: true
chromeコンテナの記述はselenium/standalone-chrome-debugに記載されているdockerコマンドをYAML形式とした。
pytestコンテナはバインドマウントを利用しており、ローカルのdocker-pytest/screenshots
ディレクトリをpytestコンテナの/docker-pytest/screenshots
ディレクトリにマウントしている。これでpytestコンテナ内でpytestを実行した際に保存されるスクリーンショットをローカルから参照できるようになる。
Dockerfile_pytest
テストスクリプト内で日時を利用するのでタイムゾーンだけ変更する。
FROM python:3
RUN pip install --upgrade pip && \
pip install selenium pytest
ENV TZ "Asia/Tokyo"
WORKDIR /docker-pytest
COPY ./tests/ /docker-pytest/tests
test_google.py
ポイントはドライバの指定の仕方。docker-composeするとコンテナ名で名前解決できる。
chromeコンテナ・4444ポートのSelenium Grid Hubに接続するにはhttp://chrome:4444/wd/hub
に接続すればよい。
import os
from datetime import datetime
from selenium import webdriver
class TestGoogle:
@classmethod
def setup_class(cls):
cls.driver = webdriver.Remote(
command_executor="http://chrome:4444/wd/hub",
options=webdriver.ChromeOptions(),
)
def test_access_google(self):
"""
Googleトップページにアクセスする。
Googleトップページ(https://www.google.com/)にアクセスする。
アクセス時にスクリーンショットを撮影し、
そのファイル名はテストを実行した日時(YYMMDD_hhmmss.png)とする。
成否は「ブラウザの現在のURLがGoogleトップページになっているか」で判定する。
"""
driver = TestGoogle.driver
file_name = datetime.now().strftime("%y%m%d_%H%M%S.png")
screenshot_path = os.path.join("/docker-pytest/screenshots/", file_name)
driver.get("https://www.google.com/")
driver.get_screenshot_as_file(screenshot_path)
assert driver.current_url == "https://www.google.com/"
@classmethod
def teardown_class(cls):
cls.driver.quit()
使い方
- ローカルで
docker-pytest
フォルダ内に移動 -
docker-compose up -d --build
を実行 -
docker-compose exec pytest bash
を実行し、pytestコンテナに接続 -
pytest tests
を実行 - ローカルの
docker-pytest/screenshots
フォルダにスクリーンショットが生成されていたら完了!
※終了したい時はdocker-compose down
を実行
実行の様子の確認
Selenium公式が配布しているDockerイメージには通常版とデバッグ版があり、デバッグ版を利用するとVNC接続をすることでテスト実行している画面をGUIで確認することができる。
接続先はvnc://localhost:5900
。接続の仕方は下記記事を参照。
Dockerのselenium/standalone-chrome-debugコンテナにVNC接続する
今後の展望
今回は1ノードのSelenium Grid Hubであるselenium/standalone-chrome-debugを利用したが、これを複数ノードにすればマルチブラウザテストが実行可能になる。
詳しくは以下を参考に。
SeleniumHQ/docker-selenium#selenium-grid-hub-and-nodes
参考資料
- 書籍
-
たった1日で基本が身に付く!Docker/Kubernetes超入門
- Docker初心者だったので非常に助けになった。良書。
-
たった1日で基本が身に付く!Docker/Kubernetes超入門
- docker-compose.yml, Dockerfileを書くにあたって参考にした記事