【備忘録】Python✖SeleniumでE2Eテストを自動化

# 1.よく使うライブラリ
テストコードを書く際に自分が高頻度で使うライブラリを記載します。

## 1-1.Seleniumがサポートしているライブラリ

|ライブラリ名|説明|import文|
|:-|:-|:-|
|<b>webdriver</b>|Webdriverを読み込む|from selenium import webdriver|
|<b>keys</b>|キーボード入力を行う|from selenium.webdriver.common.keys import Keys|
|<b>~Exception</b>|例外を定義する|<例>from selenium.common.exceptions import NoSuchElementException|
|By|要素の抽出条件等を指定する|from selenium.webdriver.common.by import By|
|Options|Webdriverの実行オプションを設定する|from selenium.webdriver.chrome.options import Options|
|chromedriver_binary|chromedriver-binaryを読み込む|import chromedriver_binary|
|WebDriverWait|明示的待機を定義する|from selenium.webdriver.support.ui import WebDriverWait|
|expected_conditions|明示的待機の条件を指定する|from selenium.webdriver.support import expected_conditions as EC|

## 1-2.Python標準ライブラリ

|ライブラリ名|説明|
|:-|:-|
|time|強制待機(time.sleep(n))を設定|
|date|日付を取得|
|os|パスの取得やディレクトリの作成|
|logging|ロガーを設定|
|requests|結果連携用のSlackAPIの実行|

# 2.導入

## 2-1.ディレクトリ構成

```python:workdir
workdir/
   ∟ ph_main.py
   ∟ test_pattern.csv
   ∟ chromedriver
   ∟ each_ph_pkg/
```

## 2-2.test_pattern.csvファイルの作成

|パターン名|メールアドレス|パスワード|項目1|項目2|
|:-|:-|:-|:-|:-|
|基本購入シナリオ1|hogehuga001@example.com|Passw0rd|0|0|
|基本購入シナリオ2|hogehuga002@example.com|Passw0rd|1|0|

```csvs:test_pattern.csv
パターン名,メールアドレス,パスワード,項目1,項目2
基本購入シナリオ1,hogehuga001@example.com,Passw0rd,0,0
基本購入シナリオ2,hogehuga002@example.com,Passw0rd,1,0
```

## 2-3.メインスクリプト(ph_main.py)の作成

```python:test.py
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from datetime import date
import os
import time
import requests

driver = webdriver.Chrome(executable_path='./chromedriver') #カレントディレクトリにあるchromedriverを指定
driver.implicitly_wait(10) #暗黙的な待機(要素が見つかるまで最大10秒待つ)

#ファイル命名用の現在日付の取得
current_time = datetime.now()
datetime_str = current_time.strftime("%Y%m%d%H%M%S")

#エビデンスキャプチャ格納用フォルダ作成
evidence_folder = os.path.join(os.getcwd(), "evidence")
if os.path.exsists(evidence_folder):
    pass
else:
    os.makedirs(evidence_folder)

#試験結果を書き込むログファイル用のフォルダを準備
result_folder = ps.path.join(os.getcwd(), "result")
if os.path.exsists(result_folder):
    pass
else:
    os.makedirs(result_folder)

result_list = []

#test_pattern.csvファイルの読み込み/試験実行
with open("test_pattern.csv", "r") as t:
    row = csv.reader(t)
    test_patterns = [row for row in reader]

for n in range(1, len(test_patterns)+1):
    pattern_name = test_patterns[n][1]
    email_address = test_patterns[n][2]
    password = test_patterns[n][3]
    item1 = test_patterns[n][4]
    item2 = test_patterns[n][5]

    for _ in range(2): #失敗時1回のみ再実行
        retry_count = 0
        try:
            #処理を記述
            driver.get("https://example.com")

            retry_count = 0
        except:
            #失敗時の処理を記述
            retry_count += 1
        else:
            break
    else:
        #リトライも失敗した際の処理を記述
        evidence_file_name = pattern_name + "_" + datetime_str
        driver.save_screenshot(evidence_folder)

    if retry_count = 0:
        result_row = pattern_name + ": OK"
    else:
        result_row = pattern_name + ": NG"

    result_list.append(result_row)

#試験結果の書き込み
with open("./result/result_{}.csv".format(datetime_str), "w") as r:
    writer = csv.writer(r, lineterminater="¥n")
    for results in result_list:
        writer.writerow(results)

#Slackのチャンネルに結果を連携
class SendResultToSlack:

    def __init__(self, token):
        self.token = token

    def send_result(self, message, channel):
        params = {"channel": channel,
                  "text": message}

        r = requests.post('https://slack.com/api/chat.postMessage',
                          headers={'Authorization': 'Bearer ' + self.token},
                          params=params)
        print("return ", r.json())

with open("./result/result_{}.csv".format(datetime_str), "r") as r:
    texts = r.read()

test_result = "本日のリグレッションテストの結果です。\n" + texts
token = '<TOKEN>'
slack = SendResultToSlack(token)
slack.send_result(test_result, "<CHANNEL_NAME>")

driver.quit()

```