【selenium】pytest + jenkins でまとめてテスト実行

この記事は [Selenium/Appium Advent Calendar](https://qiita.com/advent-calendar/2018/selenium_and_appium) 2018の12日目の記事です。

みなさん、今年もSeleniumのテストコードをたくさん書いたのではないでしょうか。
今年の集大成として、書いてきたコードをまとめて実行してみませんか！？
ということで、 **pytest + jenkins** で、実行とテスト結果をまとめる話をしていきます！


###アジェンダ
1. テストコードをpytestで実行・結果が出力されるような記述にする
2. Jenkinsでseleniumを動かす設定をする

##環境
MacBook Pro
バージョン： 10.14.1
Python: 3.7.0


# 1. pytestで実行・結果が出力されるような記述にする

### pytestとは
![pytest1.png](https://qiita-image-store.s3.amazonaws.com/0/8222/95bfb45d-4dd9-2dd3-5ecb-5bfc3ca6d57f.png)

pytestフレームワークは、小さなテストを簡単に作成するだけでなく、
アプリケーションやライブラリの複雑な機能テストもサポートしています。
(　[pytest公式より　](https://docs.pytest.org/en/latest/))

ということで、端的にいうとpython用のテストフレームワークです。

pytestは、テストが失敗したときの出力が特に分かりやすいこともあり、
自分はSeleniumと組み合わせて使っています。

##ファイル名を 「test_○○」 で始める
pytestはテストコードが配置されているディレクトリで、
pytestとコマンド打つと、自動でtest_から始まるファイルをサーチして、
実行してくれます。

##関数名を 「test_○○」 で始める
pytestは自動でtest_から始まるファイルをサーチして、
さらに、そのファイル内に入っているtest_から始まる関数をテスト対象として、
見つけ出して、実行してくれます。

ですので、pytestの実行ファイルは以下のような、コードになります。
サンプルとして、Selenium公式HPをテストしています。

```test_seleniumhq_1.py
import unittest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import pytest
import requests


class GetRoot(unittest.TestCase):
    options = Options()
    # ヘッドレスモードで起動
    options.add_argument('--headless')
    driver = webdriver.Chrome(chrome_options=options)

    @classmethod
    def setUpClass(cls):
        # Seleniumの公式HPを指定
        cls.base_url = "https://www.seleniumhq.org/"
        cls.driver.implicitly_wait(30)
        cls.verificationErrors = []
        cls.accept_next_alert = True
        cls.driver.get(cls.base_url)

    @pytest.mark.parametrize()
    def test_get_page(self):
        driver = self.driver
        # HTTPステータスを確認
        r = requests.get(driver.current_url)
        self.assertEqual(r.status_code, 200)
        # ページのタイトルをチェック
        title_target = "Selenium - Web Browser Automation"
        print(driver.title)
        self.assertEqual(title_target, driver.title)

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()


if __name__ == "__main__":
    unittest.main()
```

pytestで実行すると以下のような出力で出てきます。
実行したファイル名の横のドットは、
PASSしたテスト(test_○○と名付けて実行した関数)です。
失敗するとドットではなく、Fになります。

```sh
$ pytest test_seleniumhq_1.py 
=========================== test session starts ===========================
platform darwin -- Python 3.7.0, pytest-3.8.0, py-1.6.0, pluggy-0.7.1
rootdir: /Users/XXXX/Documents, inifile:
plugins: remotedata-0.3.0, openfiles-0.3.0, doctestplus-0.1.3, arraydiff-0.2
collected 1 item                                                          

test_seleniumhq_1.py .                                              [100%]

======================== 1 passed in 4.70 seconds =========================
```

#2. Jenkinsの設定をする
![256.png](https://qiita-image-store.s3.amazonaws.com/0/8222/e5b70944-67d2-8d44-a168-af21279f853c.png)

jenkinsのインストール方法については、過去記事や参考記事が色々あるので、割愛します。
[HomebrewでJenkinsをインストール](https://qiita.com/hujuu/items/5bfc80c265ae7d162966)

##jenkinsでpythonを実行できるようにする
 ShiningPanda Plugin というプラグインをインストールします。

 **jenkinsのトップ画面 > Jenkinsの管理 > プラグインの管理**

で、プラグインを設定するページへ遷移することができます。
利用可能のタブを選択して、 **「ShiningPanda Plugin」** を探して、インストールします。
![スクリーンショット 2018-12-10 14.46.33.png](https://qiita-image-store.s3.amazonaws.com/0/8222/f684c537-d2cc-e8f4-ea07-49449ab618be.png)

続いて、python3で動かせるように設定をします。

 **jenkinsのトップ画面 > Jenkinsの管理 > Global Tool Configuration**

デフォルトは、2系しか入っていないため、ここに3系の情報を入れます。
自分の環境数台では、以下のような設定で動かせました。
![スクリーンショット 2018-12-10 18.49.14.png](https://qiita-image-store.s3.amazonaws.com/0/8222/f9a6113f-f5ea-80e8-fa1e-9771e4e6fc71.png)

##chromedriverをパス指定無しで動かすための設定
/usr/local/bin にあるコマンドファイルを実行できるように、環境変数の設定をします。

 **jenkinsのトップ画面 > Jenkinsの管理 > システムの設定**

環境変数にチェックボックスを入れて、テキストボックスを表示させたら以下のように記入します。

![スクリーンショット 2018-12-10 18.55.32.png](https://qiita-image-store.s3.amazonaws.com/0/8222/28b48d3b-6217-3419-05d8-bb90521fc37c.png)

これで、ひとまずJenkins全体に関わる設定は終わりました。

#ジョブの設定

今回はテストコードの管理を、Githubでおこなうので、
リポジトリのURLを入力して、jenkinsと連携させます。
各ジョブの画面で設定をクリックして、以下のようにリポジトリのURLを入れていきます。
(図はオープンリポジトリの場合です。プライベートリポジトリの場合は認証設定が必要です。)

![スクリーンショット 2018-12-10 14.36.17.png](https://qiita-image-store.s3.amazonaws.com/0/8222/85ce9c30-0086-86c9-61df-27e4d1a099cc.png)

次に、実行するコマンドを指定します。
pipでインストールするものは、自分の作成したコードに合わせて適宜、調整してもらえればと思います。
![スクリーンショット 2018-12-10 18.58.46.png](https://qiita-image-store.s3.amazonaws.com/0/8222/3830f19e-72c2-ed74-4268-80afedf66ca2.png)

後は、ビルド実行してみましょう！！
今年書きためたテストが一気に実行されるはずです！！