LoginSignup
3
4

More than 1 year has passed since last update.

[Python]Page Object Modelパターンを用いたSelenium テストの記述方法メモ

Posted at
  • Page Object Modelパターンを利用したSeleniumテストの記述方法についてメモする。

POM(Page Object Model)とは

  • ページをクラスオブジェクトとして扱うブラウザ自動化テストのデザインパターンの一つ。

  • 主な概念

    • テストクラス
      • 対象ページのテストケース。
    • ページオブジェクト
      • 各Webページオブジェクトを作成することを目的としたクラス。
      • テスト用コードとWebページアクセス用コードを分離。
    • ロケータ
      • ページ要素を取得させる。
  • 利点

    • 可読性の高いテストケースを書くことができる。
    • 複数のテストケース間で共有できる再利用可能なコードを作ることができる※コード重複を防ぐことができる。

構成

root    -  TestBase.py
        |_ test_GoogleSearch.py
        |_ chromedriver.exe
        |_ Pages    -- google_page.py
                    |_ Elements -  BasePageElement.py
                    |_ Locators -  GoogleSearchPageLocators.py
                                |_ GoogleSearchResultsPageLocators.py

コード

  • こちらを参考に"Selenium"でGoogle検索するテストケースを記述する。

  • TestBase.py

    • WebDriverの起動・停止などテストで共通する処理を集約する。
  import unittest
  from selenium import webdriver


  # 共通処理を行うベーステストクラス
  # Webドライバーのオープン/クローズ
  class TestBase(unittest.TestCase):
      def setUp(self):
          self.driver = webdriver.Chrome()
          self.driver.implicitly_wait(10)
          self.driver.maximize_window()

      def tearDown(self):
          if (self.driver != None):
              print("Cleanup of test environment")
              self.driver.close()
              self.driver.quit()

  • test_GoogleSearch.py

    • テストケースクラス
  import unittest
  from Pages import google_page
  from TestBase import TestBase


  # テストクラス
  class GoogleSearch(TestBase):
      # テストケース
      def test_search_in_google(self):

          # www.google.comへアクセス
          self.driver.get("https://www.google.com/")
          main_page = google_page.MainPage(self.driver)
          # タイトルに'Google'が含まれているかを確認
          assert main_page.is_title_matches(), "Google Title Doesn't Match."
          # 検索ボックスに"selenium"を入力
          main_page.search_text_element = "selenium"
          # "Google検索"ボタンを押下
          main_page.click_search_button()
          search_results_page = google_page.SearchResultsPage(self.driver)
          # 検証:検索結果が0件でないこと
          assert search_results_page.is_results_found(), "No Search Results Found."


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

  • Pages/google_page.py

    • ページオブジェクトクラス。
  from .Elements.BasePageElement import BasePageElement
  from .Locators.GoogleSearchPageLocators import GoogleSearchPageLocators
  from .Locators.GoogleSearchResultsPageLocators import GoogleSearchResultsPageLocators


  class SearchTextElement(BasePageElement):
      locator = 'q'


  class BasePage(object):

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


  class MainPage(BasePage):

      search_text_element = SearchTextElement()

      def is_title_matches(self):

          return "Google" in self.driver.title

      def click_search_button(self):
          element = self.driver.find_element(
              *GoogleSearchPageLocators.SEARCH_BUTTON)
          element.click()


  class SearchResultsPage(BasePage):

      def is_results_found(self):
          element = self.driver.find_element(
              *GoogleSearchResultsPageLocators.SEARCH_RESULT)
          return element != None

  • Pages/Elements/BasePageElement.py

    • ページ要素
  from selenium.webdriver.support.ui import WebDriverWait


  # ページ要素クラス
  class BasePageElement(object):

      def __set__(self, obj, value):
          # 対象ページ要素が読み込まれるまで待機 → 初期化 → 値入力
          driver = obj.driver
          WebDriverWait(driver, 100).until(
              lambda driver: driver.find_element_by_name(self.locator))
          driver.find_element_by_name(self.locator).clear()
          driver.find_element_by_name(self.locator).send_keys(value)

      def __get__(self, obj, owner):
          # 対象ページ要素が読み込まれるまで待機 → 値取得
          driver = obj.driver
          WebDriverWait(driver, 100).until(
              lambda driver: driver.find_element_by_name(self.locator))
          element = driver.find_element_by_name(self.locator)
          return element.get_attribute("value")

  • Pages/Locators/GoogleSearchPageLocators.py

    • Google検索ページ用ロケータ
  from selenium.webdriver.common.by import By

  # Google検索ページ用ロケータクラス
  class GoogleSearchPageLocators(object):
      # "Google検索"ボタンのロケータ
      SEARCH_BUTTON = (By.NAME, 'btnK')

  • Pages/Locators/GoogleSearchResultsPageLocators.py

    • Google検索結果ページ用ロケータ
  from selenium.webdriver.common.by import By


  # Google検索結果ページ用ロケータクラス
  class GoogleSearchResultsPageLocators(object):
      # 検索結果件数のロケータ
      SEARCH_RESULT = (By.ID, 'result-stats')

動作確認

python test_GoogleSearch.py

DevTools listening on ws://127.0.0.1:60803/devtools/browser/e2f1274d-85ea-49c2-afdb-e118aea6e63e
Cleanup of test environment
.
----------------------------------------------------------------------
Ran 1 test in 11.892s

OK

参考情報

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4