TravisCIでDockerに入ったWebアプリのSeleniumテスト

 WebアプリをDockerでビルドして、そこでできたイメージをデプロイしてコンテナを走らせるってケースは増えてきているはず。そのイメージを使ってTravisCI上でSeleniumを使ってテストしてみる。


 Dockerイメージは既にDocker Hubにアップしてあるものとする。今回使うのは、Webアプリで、リクエストを送ると世界へのあいさつを返すだけのごく初歩的なものだ。テストはSeleniumを使ってリクエストを送り、レスポンスのHTMLのタイトルをチェックするものとする。

 テストに使うSeleniumを用意する。Seleniumはホスト環境に用意するのもいいが、仮想ディスプレイを使ったりすると、自分の環境でTravisCIでやるコマンドをちょっと試したかったりする場合に用意が手間になる。SeleniumもDockerで公式のものが用意されているので、今回はDockerで用意されたものを使う。

 Seleniumを動かすテストコードは、今回はPythonを使う。
 DockerコンテナとしてWebアプリとSeleniumが動いており、ホストにSeleniumを動かすPythonがあるというのが今回の環境。コンテナが二つあるので、ここらはdocker-composeを使うことにする。

 まずWebアプリとSeleniumのある環境の準備のためにdocker-compose。docker-compose.ymlを用意する。
docker-compose.yml

version: '2'

services:
tornadoapp:
image: matoba/tornadoapp
ports:
- "80:80"
selenium:
image: selenium/standalone-chrome
ports:
- "4444:4444"
links:
- tornadoapp

 WebアプリはTornadoを使って作ったのでtornadoappという名前にしてある。ポートバインドで、ホストのポート80でこのWebアプリがlistenされることになっている。
 あとSeleniumは、Pythonドライバで接続するためにポート4444でlistenしているのと、Webアプリに名前でアクセスができるようにlinksで設定してある。
 環境はこれでOK。

 ホストで動く、Seleniumを動かすPythonを用意する。"python setup.py test"のコマンドで動かすので、setup.pyと実際のテストコードを用意する。./TestWithSelenium以下にsetup.pyと、tests/s_test.pyが必要。
setup.py

from setuptools import setup
import sys

sys.path.append('./tests')

setup(
name='browsertest',
version='1.0',
description='test a project on browser',
test_suite = 's_test.suite',
install_requires=[
'selenium',
],
)


s_test.py

import unittest

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

#HOST = "http://172.17.0.1"
HOST = "http://tornadoapp"

class BrowserTests(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Remote(
command_executor = 'http://127.0.0.1:4444/wd/hub',
desired_capabilities = DesiredCapabilities.CHROME
)
self.driver.implicitly_wait(10)

def test_top(self):
"""top page"""
self.driver.get(HOST + "/")
self.assertIn("foo", self.driver.title)

def suite():
"""run tests"""
suite = unittest.TestSuite()
suite.addTests([unittest.makeSuite(BrowserTests)])
return suite


if __name__ == '__main__':
unittest.main()

 SeleniumからWebアプリへのアクセスはdocker-composeで設定した名前で行っている。その他の手段としては、ポートがホストにバインドされていれば、IPでアクセスできる。Dockerネットワークのデフォルトは172.17.0.*なのでこれを使っていいはず。

 テストが用意できたら、あとはこれをTravisCIで動かすための設定ファイルを用意する。
.travis.yml

sudo: required

language: python

python:
- 3.6

services:
- docker

env:
- DOCKER_COMPOSE_VERSION=1.8.0

before_install:
- sudo rm /usr/local/bin/docker-compose
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin
- docker-compose build
- docker-compose up -d
- pip install selenium

script:
- cd ./TestWithSelenium
- python setup.py test

matrix:
fast_finish: true

 やっていること↓
前準備
・Dockerを使えるように
・docker-composeコマンドを使えるように
・WebアプリコンテナとSeleniumコンテナを用意
・PythonのSeleniumドライバを用意
テスト
・Pythonコードを走らせる

 これでTravisCIでコンテナに入ったWebアプリを、Seleniumでテストする準備ができた。あとはアップするだけ。設定などを間違えていなければこれでテストは通る。




今回のTravisCI
https://travis-ci.org/hMatoba/PlayDockerTest
comment: 0