2022-10-14 –, pyconjp_2
Language: 日本語
PythonのWeb自動テストではSeleniumを使う方法が有名ですが、
作成・メンテナンスするのに、結構手間がかかります。
他の言語であれば、PupeteerやCypressという選択肢もありますが
できればPythonで実装したいと感じていました。
Playwrightは、TypeScriptで作成されたテスト自動化フレームワークで
多言語対応されており、Pythonでも利用できます。
このトークでは、Pythonで実装できるいくつかの自動化の方法と比較し、
Playwrightを使うことでより簡単に実装できることをお話します。
Playwrightは、Microsoft社製のWebテスト・自動化のための
フレームワークです。
言語はTypeScriptですが、多言語対応されているため
python用のライブラリも公開されています。
私はこれまで、
Selenium IDE
Selenium Webdriver(pythonによる)
Robot Framework + SeleniumLibrary
Pylenium.io
と、いくつかの方法を試してきました。
それぞれとても良いツール、ライブラリで、
作成することは当然可能なのですが、
もっと簡単に作成できる方法はないかなと感じていたところに
Playwrightの存在を知りました。
Playwrightは直感的に書けるだけでなく、
Selenium IDEのようなレコーディング機能も用意されており
これまでの方法に比べて圧倒的に簡単に作成することができます。
このトークではPythonを使ったテスト自動化について、
私が試してきた方法を例として取り上げて、
それぞれの特徴と比較しつつ、Playwrightの良さを伝えたいと考えています。
参考)実装例
① Chromeを起動
② Googleのサイトを表示
③ PyConJP2022を検索
④ 検索結果にPyConJP2022という文字がある要素をリンク
⑤ PyConJP2022のサイトを表示する
Seleniumを使った実装
Seleniumでテストを作った場合は、
以下のようなロジックになります。
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome(ChromeDriverManager().install())
try:
wait = WebDriverWait(driver, timeout=10)
driver.get('https://google.com')
search = driver.find_element(By.NAME, 'q')
search.send_keys('PyConJP 2022')
btn = driver.find_element(By.NAME, 'btnK')
btn.submit()
elements = driver.find_elements_by_xpath("//a[@href]")
for element in elements:
if element.text.count('PyCon JP 2022') >= 1:
element.click()
break
finally:
driver.quit()
今回は単純なものなので、それほど難しいコードにはなっていませんが、
複雑なものになると、待ちを入れたり動作させるまでの手間は増えていくと考えています。
RobotFramework + Seleniumを使った実装
RobotFrameworkは、Pythonで作成された自動化フレームワークです。
テスト自動化やRPAに使用することができます。
RobotFramework用のテストは独自の記法になりますが、
Pythonでメソッドを作成することもできます。
*** Settings ***
Documentation Search PyConJP 2022 Site
Library SeleniumLibrary
Library my_library.py
*** Test Cases ***
PyConJP2022のサイトを検索して開く
Chromeで https://google.com を開く
ブラウザで PyCon JP 2022 を検索する
検索結果から PyCon JP 2022 をクリックする
[Teardown]
ブラウザを閉じる
*** Keywords ***
Chromeで ${URL} を開く
${driver_path} = my_library.Get Driver
Create Webdriver Chrome chrome executable_path=${driver_path}
Go To ${URL}
ブラウザで ${KEYWORD} を検索する
Wait Until Element Is Visible CSS=[name=q]
Input Text CSS=[name=q] ${KEYWORD}
Wait Until Element Is Visible CSS=[name=btnK]
Click Element CSS=[name=btnK]
検索結果から ${KEYWORD} をクリックする
@{elements} = Get WebElements xpath=//a[@href]
FOR ${element} IN @{elements}
${el_text} = Get Text ${element}
${el_text} = Replace Lf ${el_text}
${check_result} = Check Include Str ${el_text} PyCon JP 2022
Run Keyword If ${check_result}
... Click Element ${element}
Exit For Loop If ${check_result}
END
ブラウザを閉じる
Close Browser
コード量は、むしろ普通にSeleniumを使うよりも多くなっていますが、
RobotFrameworkを使うことで、可読性の高いテストが作れるところが魅力です。
例のような日本語のテストも作ることができます。
また標準で実行結果のレポートも作成してくれるところも魅力です。
Pylenium.ioを使った実装
Pylenium.ioはCypressのように使いやすい構文でSeleniumを使いやすくした
フレームワークになっており
- 簡単にテスト環境をセットアップできる
- Webドライバーの自動インストール - Cypressのように使いやすい構文でSeleniumを利用できる
を実現したPythonのフレームワークです。
def test_pyconjp_google_search(py):
py.visit('https://google.com')
py.get('[name="q"]').type('PyConJP 2022')
py.get('[name="btnK"]').submit()
elements = py.findx('//a[@href]')
for element in elements:
if 'PyCon JP 2022' in element.text():
element.click()
break
マイナーなフレームワークですが、seleniumで普通にコーディングするよりも
コード量は、圧倒的に少なく書くことができます。
尚、このフレームワークは基本的にはSeleniumを使いやすくしたものになるので
Seleniumで出来ていたことは基本実施できます。
但しpytest上で動作することが前提なので、自動化への利用には向いていないかと思います。
Githubのスター数は少ないですが、私は個人的にはとても気に入っています。
4.Playwrightを使った実装
(1)Playwright-pythonを使った実装
playwright-pythonは標準のpython用ライブラリです。
Playwright InspectorというGUIツールを呼び出すことができます。
このツールを使うことで、操作をレコードすることができ、
以下のコードであれば、すぐに生成できます
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.google.com/webhp")
page.locator("[aria-label=\"検索\"]").click()
page.locator("[aria-label=\"検索\"]").fill("PyConJP 2022")
with page.expect_navigation():
page.locator("[aria-label=\"検索\"]").press("Enter")
with page.expect_navigation():
page.locator("text=PyCon JP 2022https://pycon.jp >> h3").click()
これで動作としては同じように動作します。
尚、これまでの例と同じような書き方をしたい場合は、
以下のように書くことも可能です。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.google.com/webhp")
page.locator("[name=q]").fill("PyConJP 2022")
with page.expect_navigation():
page.locator("[aria-label=\"検索\"]").press("Enter")
for element in page.query_selector_all('//a[@href]'):
if 'PyCon JP 2022' in element.text_content():
element.click()
break
作成までに掛かる時間が圧倒的に短く、Seleniumよりも高速に動作します。
(2)RobotFramework-Browserを使った実装
robotframework用のライブラリとして、playwrightを使ったPlaywight-browserというライブラリがあります。
Seleniumlibraryと書き方は異なりますが、同じように書くことはできそうです。
*** Settings ***
Library Browser
Library my_library.py
*** Test Cases ***
PyConJP2022のサイトを検索して開く
Chromeで https://google.com を開く
ブラウザで PyCon JP 2022 を検索する
検索結果から PyCon JP 2022 をクリックする
*** Keywords ***
Chromeで ${URL} を開く
Open Browser ${URL} headless=False
ブラウザで ${KEYWORD} を検索する
Fill Text [name=q] ${KEYWORD}
@{btns} = Get Elements [name=btnK]
FOR ${btn} IN @{btns}
Click ${btn}
Exit For Loop
END
検索結果から ${KEYWORD} をクリックする
@{elements} = Get Elements xpath=//a[@href]
FOR ${element} IN @{elements}
${el_text} = Get Text ${element}
${el_text} = Replace Lf ${el_text}
${check_result} = Check Include Str ${el_text} ${KEYWORD}
Run Keyword If ${check_result}
... Click ${element}
Exit For Loop If ${check_result}
END
今回作成した程度では、速度比較は難しいですが、
実際にはSeleniumlibraryよりも高速により安定的に動作するようです。
robotframeworkでWEB自動化を行う場合は、今後はこちらが使われることが多くなりそうです。
福岡在住の地方エンジニアです。
P九州でPythonのコミュニティ活動も行っています。
・PyConKyushu実行委員会(運営代表)
・Python Boot Camp Fukuoka2nd(スタッフ)など。