今回は、Seleniumで起動時にテストアカウント・接続先を選べるようにする手順について解説します。
ソースコードを載せています。同じ構成で作成すれば動くと思いますので、テスト自動化をより効率的に行いたい方は参考にしてみてください。
はじめに
テストを実施するにあたり、接続先が複数ある場合や、複数のアカウントを使う場合があります。
このような場合、Seleniumのソースコード内で接続先・接続先を毎回変更するのは面倒です。これを解決するのには、いくつか方法があります。
- Pythonのコマンドライン引数で実行時に引数を渡す
コマンドラインからPythonを実行する際に、接続先・アカウント・パスワードを一緒に渡す方法です。懸念点としては、これらの情報をコマンドライン上で入力する必要があるという点です。プログラム内でリストを定義していおいて、そのインデックスを引数にすると良いかもですが、どのインデックスにどの接続先/アカウントが紐づいているか分かりにくく、運用には注意が必要です。
- 接続用の画面を用意する
接続用の画面を作って、その画面上で接続先やアカウントを選択する方法です。画面を作る手間がありますが、一度作ってしまえば接続先とアカウントをワンクリックで選択できます。今回はこちらの方法を解説します。
Tkinterでテスト実施用の画面を作る
Pythonには、GUIライブラリがいくつか存在しますが、今回は「Tkinter」を使います。これを使って、以下のようなテスト実施用の画面を作ります。
左側には、接続先URL・ユーザー/パスワード、右側にはCSVファイルからインポートしたアカウント情報が表示されています。左側は手入力できるようになっており、右側のリストから選ぶこともできます。
プロジェクトのディレクトリ構成
今回作るプログラムのディレクトリ構成は以下のとおりです。
それぞれのソースコードと説明は後述します。
confing.py(接続先の設定)
config.pyでは、接続先を指定するプルダウンを生成します。
TEST_STAGING = "stg"
TEST_DEV1 = "dev1"
TEST_DEV2 = "dev2"
test_target = (TEST_STAGING, TEST_DEV1, TEST_DEV2)
たとえば、TEST_STAGINGを選んだ場合、後述のlogin.py内で
test_url = 'https://test-stg.com/login
というURLに変換されてブラウザを開きます。
account.csv(ログイン情報)
ユーザー・パスワードを登録したCSVファイルを作成します。
stg,test-stg1@test.com,password1
stg,test-stg2@test.com,password2
dev1,test-dev1@test.com,dev1
dev2,test-dev2@test.com,dev2
dev2,test-dev2-owner@test.com,dev
先頭カラムには、どの接続先で使うアカウントか分かるように接続先名を設定しています。
readCsv.py(CSVファイル読み込み)
readCsv.pyでは、CSVファイルの内容を読み込みます。
import csv
def read_csv():
# ファイルはpythonProjectのしたにおく
path = "./account.csv"
with open(path, encoding='utf8', newline='') as f:
reader = csv.reader(f)
csv_arr = []
for row in reader:
csv_arr.append(row)
return csv_arr
menu.py(画面生成・ブラウザ起動)
menu.pyでは画面の生成とブラウザ起動を行います。
ソースコード
import os
import signal
import time
import tkinter
from tkinter import messagebox
import tkinter.ttk as ttk
from selenium import webdriver
from selenium.webdriver.common.by import By
import readCsv
from config import test_target
# ウインドウの作成
root = tkinter.Tk()
root.title("〇〇システム テスト用")
root.geometry("840x400")
def loginMyPage(url, userid, pw):
try:
driver = webdriver.Chrome()
test_url = 'https://test-' + url + '.com//login'
driver.get(test_url)
driver.maximize_window()
time.sleep(3)
userId = driver.find_element(By.NAME, 'username')
password = driver.find_element(By.NAME, 'password')
userId.send_keys(userid)
password.send_keys(pw)
driver.execute_script("javascript:$('form').submit();")
# ログイン
time.sleep(5)
finally:
# 途中で落ちた場合プロセスを終了する
os.kill(driver.service.process.pid, signal.SIGTERM)
def list_selected(event):
selected_index = input_list.curselection()
# 各項目への転記
if selected_index:
selected_module = input_list.get(selected_index)
clear()
input_combo.insert(0, selected_module[0])
input_id.insert(0, selected_module[1])
input_password.insert(0, selected_module[2])
# 選択行の色を変更
input_list.itemconfig(selected_index, bg='blue', foreground='#faf0e6')
def login():
input_id_value = input_id.get()
input_combo_value = input_combo.get()
input_password_value = input_password.get()
if not input_combo_value or not input_id_value or not input_password_value:
messagebox.showinfo("入力内容", "未入力項目があります")
else:
loginMyPage(input_combo_value, input_id_value, input_password_value)
root.quit()
def clear():
input_combo.delete(0, tkinter.END)
input_id.delete(0, tkinter.END)
input_password.delete(0, tkinter.END)
input_list.select_clear(0, tkinter.END)
index = 0
for item in readCsv.read_csv():
input_list.itemconfig(index, bg='', foreground='')
index += 1
frame1 = tkinter.Frame(root, relief=tkinter.FLAT, bd=1, height=100, width=500, pady=10, padx=30)
frame1.grid(column=1, row=0)
# URL
input_combo = tkinter.Label(frame1, text="URL")
input_combo.grid(row=1, column=1, pady=10, padx=10)
variable = tkinter.StringVar()
input_combo = ttk.Combobox(frame1, values=test_target, textvariable=variable, width=32)
input_combo.grid(row=1, column=2, padx=10, pady=10)
# ID
input_id_label = tkinter.Label(frame1, text="ユーザーID/mail")
input_id_label.grid(row=2, column=1, padx=10, pady=10)
input_id = tkinter.Entry(frame1, width=35)
input_id.grid(row=2, column=2)
# パスワード
input_password_label = tkinter.Label(frame1, text="パスワード")
input_password_label.grid(row=3, column=1, padx=10, pady=10)
input_password = tkinter.Entry(frame1, width=35)
input_password.grid(row=3, column=2)
frame2 = tkinter.Frame(root, bd=2, height=100, width=500, pady=10, padx=10)
frame2.grid(column=4, row=0)
# コンボボックス(csv読み込み)
input_list_label = tkinter.Label(frame2, text="account.csvに登録してあるやつ")
input_list_label.grid(row=1, column=4, padx=10, )
var = tkinter.StringVar(frame2, value=readCsv.read_csv())
input_list = tkinter.Listbox(frame2, selectmode="single", selectbackground="blue", listvariable=var, height=15,
width=60)
input_list.bind('<<ListboxSelect>>', list_selected)
input_list.grid(row=2, column=4, padx=10, pady=10)
# ログインボタン
button = tkinter.Button(text="ログイン", command=login, width=20, height=1, padx=10, pady=10, bg='#dae3ea')
button.place(x=50, y=320)
# クリアボタン
button = tkinter.Button(text="クリア", command=clear, width=20, height=1, padx=10, pady=10, bg='#eee3ea')
button.place(x=235, y=320)
# 画面が閉じられたとき
def click_close():
root.destroy()
root.mainloop()
ソースコードの内容
tkinterでGUI画面を作成しています。tkinterの基本的な使い方はこちらの記事をご参照ください。
ボタンにイベントを設定し、ボタンが押されたらログイン処理等が行われます。
Basic認証が必要な場合
以下のようなポップアップが出る場合の対処法を記載します。
このような場合は、
test_url = https://user:password@test-' + url + '.com/login
というように、https://のあとにユーザー名:パスワードを追加します。
ログイン処理について
ログイン処理の関数は「loginMyPage」です。この関数では接続先(URL)、ID、パスワードを引数にしてログイン処理を行います。
ログインページの入力欄の要素を取得して、それぞれ入力したあとログインボタンを押します。詳しくはこちらの記事をご参照ください。
まとめ
今回は、Tkinter×Seleniumで起動時にアカウント・接続先を選べるようにする方法について解説しました。テスト環境やアカウントが沢山あって迷ってしまうという場合に役立つかと思います。
普段あまりPythonを触らないので、一般的な記述になっていない箇所があったらすみません・・・!何か指摘や疑問点等ありましたら、気軽にコメントいただければと思います。
コメント