Jenkins + Selenium + Chrome で テストを実行する CI/CD 環境 を作ってみる。

こんにちは。
最近、WSL に Selenium をインストールして遊んでいました。
そこで、ふと思ったのですが、これを CI/CD パイプラインに組み込んだら面白いのではないかと考えました。
Jenkinsの勉強も兼ねて、環境を構築してみることにします。
具体的には、以下のようなパイプラインを作成します。

1. サーバにコンテンツをデプロイする。
2. デプロイ後に Selenium でテストを行う。
3. テスト結果を Slack に通知する。

この一連の流れを自動化し、効率的に運用できる環境を目指します。

Jenkins 構築

CentOS7 に Jenkins / Selenium / Chrome のパッケージを導入します。

yum install wget unzip git
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install epel-release
yum install java-11-openjdk-devel
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
yum install jenkins
systemctl start jenkins.service
systemctl enable jenkins.service

cat << "EOF" >> /etc/yum.repos.d/google.chrome.repo
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
EOF

yum install xorg-x11-server-Xvfb
yum install google-chrome-stable
yum install ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts

yum install python3
pip3 install selenium

cd /usr/local/src/
wget https://chromedriver.storage.googleapis.com/93.0.4577.15/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
mv chromedriver /usr/local/bin/

Jenkins の UI から Xvfb / Slack Notification のプラグインを導入します。
※ Slack 側で Jenkins CI を予め追加しておいてください。
Jenkinsの管理 > プラグインの管理 > 利用可能 > Xvfb > Download now and install after

Jenkinsの管理 > Global Tool Configuration > Xvfb installation追加 > Name に Xvfb を入力 > Save

Jenkinsの管理 > プラグインの管理 > 利用可能 > Slack Notification > Download now and install after

Jenkinsの管理 > システムの設定 > Slack > Workspace に チームサブドメインを入力

Jenkinsの管理 > システムの設定 > Slack > Credential 追加 > Jenkins > 種類 Secret text 

Secret : インテグレーション用トークン認証情報 ID
ID : 任意

> 保存

デプロイジョブの作成

デプロイはシンプルに、ターゲットサーバに SSH 接続して develop ブランチを git pull するだけとします。
Jenkins は jenkins ユーザとして実行されるため、ホームディレクトリ配下にターゲットサーバに設定した公開鍵と対になる秘密鍵を配置しておきます。

mkdir /var/lib/jenkins/.ssh
vi /var/lib/jenkins/.ssh/id_rsa
chown -R jenkins:jenkins /var/lib/jenkins/.ssh
chmod 700 /var/lib/jenkins/.ssh
chmod 600 /var/lib/jenkins/.ssh/id_rsa

新規ジョブ作成 > フリースタイル・プロジェクトのビルド

から

ビルド手順の追加 > シェルの実行
で下記のワンライナーを実行するだけです。

ssh -oStrictHostKeyChecking=no target@xxx.xxx.xxx.xxx "cd /path/to/hoge; git pull origin develop"

ビルド後の処理の追加 > 他のプロジェクトのビルド
で 後述の テストジョブを指定します。

テストジョブの作成

Jenkins サーバの適当なディレクトリに Selenium のスクリプトを配置しておきます。
※ 今回は個人的に作った以下 WEB ツール上で、適当に画面を偏移するスクリプトを用意しました。
https://github.com/snkk1210/ease

#!/usr/bin/python3

import time
import datetime
from selenium import webdriver

URL='http://xxx.xxx.xxx.xxx'
USER="xxx@localhost"
PASSWD="xxx"

def clickHref(link):
    driver.find_element_by_link_text(link).click()
    time.sleep(1)
    return 0

def clickBtn(xpath):
    driver.find_element_by_xpath(xpath).click()
    time.sleep(1)
    return 0

def inputForm(element, input):
    driver.find_element_by_name(element).send_keys(input)
    time.sleep(1)
    return 0

def dialogboxThrough():
    driver.switch_to_alert().accept()
    time.sleep(1)
    return 0

driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver')

driver.get(URL)

# login check

inputForm("email", USER)

inputForm("password", PASSWD)

clickBtn("//button[@class='btn btn-block btn-flat btn-primary']")

# sidemenu check

side_menus = ['Playbooks','Make Playbook','Authentications','Make Auth','Archives','Upload Files','Profile','Members']
for side_menu in side_menus:
    clickHref(side_menu)

# make playbook check

clickHref("Make Playbook")

inputForm("name", "test-playbook" + str(time.time()))

inputForm("private_key", "aaa")

inputForm("inventory", "bbb")

clickBtn("//input[@class='btn btn-success']")

# edit playbook check

clickHref("Playbooks")

clickBtn("//input[@class='btn btn-success']")

inputForm("private_key", "aaa")

inputForm("inventory", "bbb")

clickBtn("//input[@class='btn btn-success']")

# archive playbook check

clickHref("Playbooks")

clickBtn("//input[@class='btn btn-warning']")

# delete playbook check

clickHref("Archives")

clickBtn("//input[@class='btn btn-danger']")

dialogboxThrough()

# exit

time.sleep(5)
driver.quit()

新規ジョブ作成 > フリースタイル・プロジェクトのビルド

から

ビルド環境 > Start Xvfb before the build, and shut it down after.
に チェックを入れます。

ビルド手順の追加 > シェルの実行
で上記のスクリプトを実行するように指定してあげるだけで OK です。

ビルド後の処理の追加 > Slack Notifications
を設定しておけば、ジョブの実行結果を Slack に通知することが可能です。