デジハリ 新しい自分に生まれ変わろう
デジハリ 新しい自分に生まれ変わろう
2020.01.21

Selenium × Pythonで管理画面へのログインを自動化してみた

セイト

こんにちは、LIGフィリピン支社代表のセイト(@seito_horiguchi)です。

前に趣味でPyQという学習サービスでPythonをちょろっと勉強してみました。しかし実際の業務で使うことはなく、経過すること早2年……。ここへきて僕のPython熱がふたたび。

今回はだるい単純作業をちょっとしたスクリプトで解決しようと思います。

テーマ:管理画面の自動ログイン

さて、今回のテーマとなるやっつけたい非効率的な作業はこちら。


いいオフィス会員様向けアプリ

これはグループ会社でもある「株式会社いいオフィス」が運営するコワーキングスペースの会員様向けWebモバイルアプリケーションで、主にセブ支社で開発をしています。

僕は以前までこの開発にPM(プロジェクトマネージャー)として関わっていたのですが、何が面倒なのかというとテストです。

息の長いプロジェクトなので何度もリリースがあり、その度リリース前に僕もPMとして最終チェックやらモンキーテストを行うのですが、このアプリ管理画面が多いんですよね。

  • マスター管理画面
  • FC(フランチャイズ)店舗様管理画面

テストでは主に上記の管理画面にアクセスする必要があるんですが、FCは挙動をいくつか試すために最低でも3店舗分はアクセスする必要がありました。

また開発環境もDevelop(開発)、Staging、Production(本番)と3つあるため、 4管理画面 × 3環境 = 12画面に対して何度もログイン・ログアウトしながらテストをするという。

せめてログイン作業でも楽にしたい……ということで簡単にしちゃいます。

課題と解決策

設計

今回はいたってシンプルに行いたかったので、下記の仕様を目指しました。

設計
  1. コマンドを入力したら勝手に画面が開いてログインされる
  2. コマンドにはいくつかのパターンを用意しておき、それらの組み合わせで4管理画面 × 3環境 = 12画面にログインできるようにする

使用するもの:Selenium

今回はテストツールで有名なSeleniumを使います。

Seleniumとは、クロスブラウザ、クロスプラットフォームのUIテストツールです。 ブラウザに表示される要素を操作し、取得して想定されうる状態になっているかをテストできます。

(引用:WebのUIテスト自動化 – Seleniumを使ってみる|Qiita

SeleniumはJava、C#、Rubyなどさまざまなプログラミング言語に対応しているため、お好みで使いやすいものを選択することができます。

僕はJavaScriptが慣れているのでそれでもよかったんですが、せっかく勉強中でもあるのでPythonをチョイスします。また、今回は機能テストのみカバーできればOKなので、使うブラウザはGoogle Chrome一択にします。

Google Chrome上でSeleniumをPythonで実行するにはまず下記をインストールする必要があります。

  • Python(v3.x推奨)
  • Selenium
  • Chrome Driver

これらについてはバチクソわかりやすい記事があるのでこちらを貼っておきます。

Python3インストール(Mac編) – Qiita
Python + Selenium で Chrome の自動操作を一通り|Qiita

実際に書いたコードと設計

さて、百聞は一見に如かず。

実際に書いたサンプルコードはLIG Philippinesの「GitLab」に置きましたのでご参照ください。

サンプルコード
auto-login in Gitlab

ファイル構造

まず冗長になるのを避けるため、ファイルを2つに分割しました。

といっても中身はシンプルで、

  • const.py ・・・ ログイン時に使うID、パスワード、URLなどの定数を置いておくファイル
  • login.py ・・・ 実行に使うメインのファイル

主要なコード

コードぜんぶ書くと長ったらしいので、本記事では一部だけ抜粋してざっくり解説します。

下記は主要なファイルであるlogin.pyのコードをピックアップ。

# Const
import const as CONST
import chromedriver_binary # ChromeDriver

# library & module
from selenium import webdriver # Smodule elenium webdriver
from selenium.webdriver.support.ui import WebDriverWait

# arguments from comand line
import sys 
args = sys.argv

# Open browser
# /Users/Kenta/Desktop/Selenium/chromedriver
driver = webdriver.Chrome()

# Seeting of Timeout
wait = WebDriverWait(driver, 10)

# Try login
def login_to_time_records(args):

  url = args[1]
  login = args[2]

  # URL
  if url == 'dev':
    driver.get(CONST.URL_LOGIN['DEV'])
  elif url == 'stg':
    driver.get(CONST.URL_LOGIN['STG'])
  elif url == 'prd':
    driver.get(CONST.URL_LOGIN['PRD'])


  # ID, PW
  login_id = ''
  login_pw = ''

  if login == 'master':
    login_id = CONST.MASTER['ID']
    login_pw = CONST.MASTER['PW']
  elif login == 'fc1':
    login_id = CONST.FC1['ID']
    login_pw = CONST.FC1['PW']
  elif login == 'fc2':
    login_id = CONST.FC2['ID']
    login_pw = CONST.FC2['PW']
  elif login == 'fc3':
    login_id = CONST.FC3['ID']
    login_pw = CONST.FC3['PW']

  input_id = driver.find_element_by_name('email')
  input_password = driver.find_element_by_name('password')

  input_id.send_keys(login_id)
  input_password.send_keys(login_pw)

  button_login = driver.find_element_by_class_name('form__submit--login')
  button_login.click()

  ## Transfer to Time records page
  print('-------Complete login-------')

login_to_time_records(args)

 

解説

  1. Line 2 – 7 (import const as CONST … )
    • 必要な外部ファイル、ライブラリ、モジュールを読み込みます。
      constは自前で書いたconst.py、chromedriver_binaryはChromeブラウザを操作するためのもの。
  2. Line 10 – 11 (import sys … )
    • コマンドライン上からプログラムを実行するために必要な記述。
  3. Line 15 (driver = webdriver.Chrome())
    • Chromeを起動
  4. Line18 (wait = WebDriverWait(driver, 10))
    • ページ上のすべての要素が読み込まれるまで待機。ただし10秒でタイムアウト判定して停止。
  5. Line 21 – 24 (def login_to_time_records(args): … )
    • コマンドラインで引数を2つまで設定できるように。
  6. Line 26 – 32 ( if url == ‘dev’: … )
    • 引数その1。
      dev/stg/prdのいずれかを入力したら、それに対応したURLをconst.pyから取得し、ブラウザ上で開く。
  7. Line 36 – 50 (login_id = ” … )
    • 引数その3。
      master/fc1/fc2/fc3のいずれかを入力したら、それに対応したログインID・パスワードをconst.pyから取得。
  8. Line 52 – 56 (input_id = driver.find_element_by_name(‘email’) … )
    • HTMLのid, class, name属性から、ログインページにあるID・パスワード入力フォームを取得し、ログインID・パスワードを自動入力。
  9. Line 58 – 59 (button_login = driver.find_element_by_class_name(‘form__submit–login’) … )
    • HTMLのclass属性からログインボタンを取得し、クリック。
  10. Line 62 (print(‘——-Complete login——-‘))
    • 成功・完了したのがわかるようコマンドライン上にCompleteと表示。

これを実際にコマンドで打つと、
python login.py dev master
python login.py stg fc3
などとなります。

上記を実際に実行した様子がこちら。

ちと大人の事情で画質荒いし見にくいかもですがそこはご愛嬌……

まとめと宣伝(採用のお知らせ)

いかがでしたか。

テクノロジーを使えばこういった日々の雑務も効率化することができます。コーディングがメインの業務でなくとも、PMやディレクターさんがこんなんできたら作業も捗るかと思いますのでぜひトライしてみてください。

あと関係ないですがLIGセブ支社では各種ポジション募集中なので、興味ある方はぜひ!