14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Selenium Grid on Kubernetes

Last updated at Posted at 2017-06-27
1 / 24

Kubernetes Meetup Tokyo #5の登壇資料です。


アジェンダ

  • Why Selenium Grid?
  • Why Selenium Grid on Kubernetes?
  • How-tos
  • Gotachas

Why Selenium Grid?

  • 複数ブラウザを使ったE2Eテストを並列化するため

Selenium

ブラウザのオートメーションツール。WebアプリケーションのE2Eテストなどに使う

Selenium Grid

複数のマシンやコンテナにSeleniumのテストを分散並列実行させるためのプロキシFirefoxやChromeなど複数ブラウザを使ったE2Eテストを並列化するなどの目的で使う


Why Selenium Grid on Kubernetes?

Dev/Prod Parity & Self-hosting


Selenium Grid: Pain Points

  • Selenium GridのURLがローカルと非ローカル環境で異なる(Dev/Prod Parity)
  • 経費的な問題でBrowserStack、SauceLabsなどの有償サービスを使いたくない→Self-hosting
  • Selenium Gridの構築がめんどくさい

Selenium Grid on Kubernetes: Good Points

  • Selenium GridのURLがローカルと非ローカル環境で一緒(Dev/Prod Parity)
  • Self-hosting
  • Selenium Gridの構築がコマンド一発

How-tos

  • Kubernetes(K8S)クラスタ作成: ローカル & AWS
  • K8SにSelenium Gridをインストール
  • Chromeノードにリモートデスクトップ接続して観察・デバッグ
  • Pythonのreplでテストコードを書く
  • pytestでテスト実行
  • K8SにConcourseをインストール
  • テスト実行の様子を観察
  • プロセス並列で実行

K8Sクラスタ作成: ローカルマシン上に

kubernetes/minikubeという便利なツールが

minikube start --cpus 4 --memory 4096

  • CPUは4コア(Concourse Web/Workerでそれぞれ1コア+その他で2コア)
    •  minikubeVMのデフォルトメモリサイズは1024M
    •  MySQL, Redis, Selenium Grid Hub, Selenium Node
      Firefox/Chromeを起動するとだいたい4GBくらい

K8Sクラスタ作成: AWS上に

kubernetes-incubator/kube-awsという便利なツールが

$ mkdir my-cluster
$ cd my-cluster
$ kube-aws init --cluster-name=mycluster \
--external-dns-name=mycluster.example.com \
--region=ap-northeast-1 \
--availability-zone=ap-northeast-1a \
--key-name=mykeypair \
--kms-key-arn="arn:aws:kms:ap-northeast-1:xxxxxxxxxx:key/xxxxxxxxxxxxxxxxxxx" \
--hosted-zone-id=myhostedzoneid
$ kube-aws render credentials --generate-ca
$ kube-aws render stack
$ kube-aws up --s3-uri s3://<your-bucket>/<optional-prefix>

※メンテナです。宣伝乙ごめんね


Selenium Gridインストール

  • Kubernetesにアプリをインストールする場合は基本的にhelmというツール使用
  • VNCクライアントでWebDriver Podにリモートデスクトップ接続して、ブラウザが動く様子をみたい
    • (chrome|firefox)Debug.enabled=true
helm install stable/selenium \
  --set chromeDebug.enabled=true \
  --set firefoxDebug.enabled=true
  --name selenium-grid

Seleniumテストを書く環境作成: kubectl exec

ブラウザ=SeleniumのRemoteWebDriver

kubectl run selenium-python --image=google/python-hello
export PODNAME=`kubectl get pods --selector="run=selenium-python" --output=template --template="{{with index .items 0}}{{.metadata.name}}{{end}}"`

# 初回はdocker pullに時間がかかるので数分待ってから・・・
kubectl exec --stdin=true --tty=true $PODNAME bash
pip install selenium
python

Seleniumテストを書く環境作成: telepresence

telepresence という、ローカルマシンからK8Sネットワークに透過的にアクセスできるようにするツール

$ telepresence --new-deployment telepresence \
  --method inject-tcp \
  --namespace default \
  --run-shell
Starting proxy...
@minikube|bash-3.2$

macOS内のbashとそこから起動したプロセスすべてが「K8Sクラスタのネットワーク」に繋がった状態になる

pip install selenium
python

Pythonのreplでテストコードを書く

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

driver = webdriver.Remote(
  command_executor='http://selenium-grid-selenium-hub:4444/wd/hub',
  desired_capabilities=getattr(DesiredCapabilities, "CHROME")
)
driver.get("http://google.com")
assert "google" in driver.page_source
driver.close()

pytestでテスト実行

pip install -U pytest
import time

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities im
port DesiredCapabilities

def test_chrome():
        driver = webdriver.Remote(
          command_executor='http://selenium-grid-selen
ium-hub:4444/wd/hub',
          desired_capabilities=getattr(DesiredCapabili
ties, "CHROME")
        )
        driver.get("http://google.com")
        time.sleep(5)
        assert "google" in driver.page_source
        driver.close()
pytest

しばらく待つとテストが通る。


だいたいおわり


Gotachas

  • Debugging
  • Distributed Testing

ChromeノードにVNCで接続

  • VNC: いわゆるリモートデスクトップ
  • kubectl port-forwardコマンドを使うと、Kubernetesクラスタ内のpodのポートをローカルマシン側にバインドできる(!)
kubectl port-forward --namespace default \
  $(kubectl get pods --namespace default \
    -l app=selenium-grid-selenium-chrome-debug \
    -o jsonpath='{ .items[0].metadata.name }') 5900

macOS標準装備のVNCクライアントで接続

open vnc://127.0.0.1:5900

テスト実行の様子を観察

driver.get("http://google.com")

実際、VNCクライアントで見てみるとChromeが動いていることがわかる。


複数プロセスでテストを分散並列実行

pytest-xdistを使う。

pip install --upgrade setuptools
pip install pytest-xdist

...

pytest -n <プロセス数>

setuptoolsをアップグレードしないと-nオプションが認識されない。pythonあるあるなの?


複数マシンでテストを分散並列実行

Why?

  • 素朴にpytest -nすると、1コンテナに割り当てたCPU・メモリでさばけるプロセス数までしかスケールしない

How?

  • テスト配布元マシン 1 --同期--> N テスト実行マシン
  • submitter --> ファイルストレージ --> master --> worker

Example


参考リンク


まとめ

  • Dev-Prod Parity
    • ローカルマシンでも本番サーバでも全く同じテストスクリプトでSelenium Gridを使ったテストが可能
  • 環境構築の容易さ
    • K8SさえあればSelenium Gridはhelm install一発
  • デバッグ
    • VNCでブラウザの動く様を観察する
  • 分散テスト
    • プロセス並列、マシン並列
  • 登場したツール
    • Kubernetes, Selenium Grid, minikube, kube-aws, helm, VNC, kubectl port-forward, open vpn://..., telepresence, pytest-xdist

自己紹介 & おわり

twitter/github/slack.k8s.io: @mumoshu (むもしゅ)
Primary maintainer of kubernetes-incubator/kube-aws

Fin :bow: :clap:

14
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?