フロントエンドテストの自動化に関しては、理想的なプログラミング言語を選択することが非常に重要になります。Pythonはそのようなリストのトップに位置する言語の1つであり、使用の容易さと広範なコミュニティのサポートが理由です。
さらに、Python自動化テストを使用すると、Selenium、pytest、Robotなどの人気のあるライブラリやフレームワークが提供する機能を活用できます。Pythonと一緒にSeleniumを使用することで、Seleniumの強力なブラウザ自動化機能とPythonのシンプルさと拡張性を最大限に活用できます。全体として、Python自動化テストは、特にSelenium WebDriverと共に、QAsによって広く使用されています。
このブログでは、Pythonのフロントエンドの観点から微妙な点について詳しく掘り下げていきます。このブログの学びは、シンプルなフロントエンドシナリオや複雑なシナリオを自動化するためにPythonの機能を活用するのに役立ちます。
Python自動化テストとは何ですか?
その名前が示すように、Python自動化テストは、テストを自動化するためにPythonスクリプトを使用するプロセスです。これは、手作業で繰り返されるタスクの自動化に最も求められるプログラミング言語の1つです。
Pythonを使用した自動化テストの簡単な例は、pytestフレームワークとSeleniumを活用して、eコマースプラットフォームでフロントエンドテストを自動化することです。eコマースウェブサイトの登録機能を検証し、同じセッションを使用してサイトを巡回し、必要なアイテムをショッピングカートに追加することができます。このテストの最後までに、eコマースウェブサイトの登録、ログイン、およびカートの機能を検証することができます。
最後に、Pythonを使用してシステム管理、メールの自動化、およびデータ処理タスクを自動化することもできます。Pythonは自動化テストの前提条件であるため、Pythonのインストールについて詳しく説明した以下のビデオを参照してください。
自動テストのためのPythonの利点は何ですか?
テスターがSeleniumとPythonを好む理由がわかったところで、Pythonを自動化テストに選択する際のいくつかの重要な理由を見てみましょう:
1. 幅広いライブラリとフレームワーク
PyUnit(またはunittest)はPythonで単体テストを実行するためのデフォルトのテストフレームワークです。PyUnitはすぐに使用できますが、Pythonはpytest、Behave、Robot、Lettuce、Nose2などの人気のある他のフレームワークもサポートしています。
これらすべては、SeleniumとPlaywrightフレームワークと徹底的に組み合わせて、ウェブブラウザテストを自動化するために使用できます。
2. 超簡単な並列テスト実行
SeleniumとPythonにおける並列テストは、さまざまなブラウザとプラットフォームの組み合わせでウェブブラウザの自動化テストを実行するために広範囲に使用できます。Seleniumがサポートするすべての言語が並列テストの実行をサポートしていますが、Pythonとの使用は非常に簡単です。
3. マルチパラダイムプログラミング言語
Pythonはマルチパラダイムプログラミング言語です。したがって、オブジェクト指向プログラミングと構造化プログラミングに完全なサポートがあります。Pythonの多くの機能は、関数型プログラミングやアスペクト指向プログラミングをサポートしています。Pythonは、Seleniumとともに、ウェブサイトやウェブアプリケーションの機能テストにも使用できます。
4. ダイナミックタイピング
Python言語はダイナミックタイピングと遅延バインディング(または動的名前解決)を使用しており、実行中にメソッドと変数名をバインドします。この機能はPythonのテスト自動化に非常に便利です。
PythonにはPyre(Python 3用の高性能な型チェッカー)やMypyなどの人気のある静的型チェッカーなどのオプションもあります。これらのチェッカーを使用することで、Pythonは動的型と静的型のパワーを組み合わせることができます。
5. ウェブスクレイピング
Pythonを使用したウェブスクレイピングとは、ウェブサイトから意味のある情報/データを抽出するプロセスです。これは主に学術研究、競合他社分析、コンテンツの集約などに使用されます。
Pythonには、BeautifulSoup(bs4)、Selenium、Puppeteer、Pyppeteerなどのライブラリやフレームワークが多数あり、ウェブサイトからコンテンツをスクレイピングする作業を容易にしています。
6. パワフルで手間のかからないレポーティング
テスト自動化の報告により、テスト実行の微妙なニュアンス(つまり、合格/不合格のテストのパーセンテージ、テスト環境、スクリーンショットなど)がより明確になります。適切な情報を簡潔で理解しやすい形で提供する強力なレポートを必要なステークホルダー(チーム内)に送信することで、テストの進捗状況を把握できるようになります。
Python自動化テストの実行方法は?
Python自動化テストの重要性を見てきたので、いくつかのテストを実行してみましょう。私たちの議論は主に、Pythonを使用したフロントテスト自動化テストに焦点を当てます。
テストを開始する前に、環境と依存関係をよりよく管理するのに役立つ仮想環境(venv
)を設定しましょう。 venv
は、ベース環境にインストールされたパッケージとの隔離を提供する重要な役割を果たします。
仮想環境を作成するには、ターミナルでコマンド virtualenv venv
および source venv
/bin
/activate
を実行します。プロジェクトの実行に必要な依存関係(またはPythonパッケージ)は、requirements.txt ファイルに利用できます。
pytest-selenium
pytest-xdist
selenium>=4.6.0
urllib3==1.26.12
requests
py
依存関係
依存関係は、ターミナルで pip install -r requirements.txt
をトリガーすることでインストールできます。Selenium v4.6.0(またはそれ以上)はインストール手順の一部としてインストールされます。
デモンストレーションとして、pytestとPyUnit(またはunittest)フレームワークを使用して、シンプルなSelenium Pythonテストを実行します。これらのフレームワークのいずれかに精通している場合は、Pythonでフィクスチャを使用し、Selenium PythonでのPage Object Modelを使用することをお勧めします。テストのメンテナンスを向上させるためです。 Seleniumパッケージ自体にはテストツールやフレームワークが提供されていないため、Webページ上の要素とのやり取りを自動化するためにSeleniumをpytestおよびPyUnitと共に使用します。
テストシナリオ
- LambdaTest Selenium Playgroundに移動します。
- ページ上のInput Form Submitリンクを見つけます。
- ページに必要な情報を入力します。
- 詳細を送信し、情報が正常に送信されていないかどうかをアサートします。
実装(pytestフレームワーク)
上記のテストシナリオのテストスクリプトは以下の通りです。
import os
import pytest
from os import environ
import time
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
exec_platform = os.getenv('EXEC_PLATFORM')
time_sleep = 2
########################## Locators #########################
xSubmitForm = "//a[.='Input Form Submit']"
xInpName = "//input[@id='name']"
cInpName = "#name"
xInpEmail = "//form[@id='seleniumform']//input[@name='email']"
xInpPassword = "//input[@name='password']"
cssCompany = "#company"
cWebName = "#websitename"
xInpCountry = "//select[@name='country']"
xInpCity = "//input[@id='inputCity']"
cssAddress1 = "[placeholder='Address 1']"
cssAddress2 = "[placeholder='Address 2']"
cssInpState = "#inputState"
cssInpZip = "#inputZip"
cssInpButton = ".bg-lambda-900"
nameSearchBox = "search"
class TestFormInput:
def setup_method(self):
if exec_platform == 'cloud':
username = environ.get('LT_USERNAME', None)
access_key = environ.get('LT_ACCESS_KEY', None)
ch_options = webdriver.ChromeOptions()
lt_options = {}
lt_options["build"] = "Build: Getting Started with Selenium PyTest"
lt_options["project"] = "Project: Getting Started with Selenium PyTest"
lt_options["name"] = "Test: Getting Started with Selenium PyTest"
lt_options["browserName"] = "Chrome"
lt_options["browserVersion"] = "latest"
lt_options["platformName"] = "macOS Sonoma"
lt_options["geoLocation"] = "US"
lt_options["console"] = "error"
lt_options["w3c"] = True
lt_options["headless"] = False
ch_options.set_capability('LT:Options', lt_options)
gridURL = "https://{}:{}@hub.lambdatest.com/wd/hub".format(username, access_key)
self.driver = webdriver.Remote(
command_executor = gridURL,
options = ch_options
)
elif exec_platform == 'local':
ch_options = ChromeOptions()
self.driver = webdriver.Chrome(options=ch_options)
def test_enter_form_details(self):
resultant_str = "Thanks for contacting us, we will get back to you shortly."
driver = self.driver
driver.get("https://www.lambdatest.com/selenium-playground/")
# Commented once the tests are executed in non-headless mode
driver.maximize_window()
wait = WebDriverWait(driver, 5)
try:
element = driver.find_element(By.XPATH, xSubmitForm)
element.click()
elem_name = driver.find_element(By.XPATH, xInpName)
elem_name.send_keys("Testing")
time.sleep(time_sleep)
elem_email = driver.find_element(By.XPATH, xInpEmail)
elem_email.send_keys("[email protected]")
time.sleep(time_sleep)
elem_pass = driver.find_element(By.XPATH, xInpPassword)
elem_pass.send_keys("password")
time.sleep(time_sleep)
elem_comp = driver.find_element(By.CSS_SELECTOR, cssCompany)
elem_comp.send_keys("LambdaTest")
elem = driver.find_element(By.CSS_SELECTOR, cWebName)
elem.send_keys("https://wwww.lambdatest.com")
country_dropdown = Select(driver.find_element(By.XPATH, xInpCountry))
country_dropdown.select_by_visible_text("United States")
time.sleep(time_sleep)
elem = driver.find_element(By.XPATH, xInpCity)
elem.send_keys("San Jose")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssAddress1)
elem.send_keys("Googleplex, 1600 Amphitheatre Pkwy")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssAddress2)
elem.send_keys("Mountain View, CA 94043")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssInpState)
elem.send_keys("California")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssInpZip)
elem.send_keys("94088")
time.sleep(time_sleep)
# Click on the Submit button
submit_button = driver.find_element(By.CSS_SELECTOR, cssInpButton)
submit_button.click()
time.sleep(2)
try:
element = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".success-msg"))
)
assert resultant_str in element.text, f"'{resultant_str}' not found in the specified element."
except Exception as e:
if exec_platform == 'cloud':
driver.execute_script("lambda-status=failed")
pytest.fail(f"Text '{resultant_str}' not found: {str(e)}")
time.sleep(2)
except Exception as e:
# Catch other exceptions
print(f"Failed: Input Form Demo, generic exception - {e}")
if exec_platform == 'cloud':
driver.execute_script("lambda-status=failed")
if exec_platform == 'cloud':
driver.execute_script("lambda-status=passed")
print(f"PyTest Demo: Test Passed")
def teardown_method(self):
if (self.driver != None):
# self.driver.close()
self.driver.quit()
if __name__ == "__main__":
pytest.main()
コードの概要
始めるには、テストの実装に必要なモジュールを最初にインポートします。pytestを使用しているため、pytest
モジュールもコードにインポートされています。
selenium.webdriver.support.uiモジュールからWebDriverWait
クラスをインポートして、WebElementsが動的に配置されるシナリオで明示的な待機を使用できるようにします。expected_conditions
モジュールは、Seleniumで明示的な待機と一緒に使用できる事前定義されたExpectedConditionsのセットを提供します。
要素を操作する前に要素がどこにあるかを特定する必要がありますので、まず、必要な要素の要素ロケータを定義します。ID、名前、XPath、リンクテキスト、部分リンクテキストなど、広く使用されているWebロケータは、Document Object Model(DOM)内の要素を見つけるのに役立ちます。
Webロケータが特定されたら、Webブラウザにネイティブで利用可能な検査ツールまたはPOM Builderのようなプラグイン(またはアドオン)を使用して、WebElementのXPath/CSSセレクタを見つけることができます。
Webロケータが特定されると、Selenium Pythonのfind_element()
または find_elements()
メソッドと組み合わせて、対応するWebElementが特定されます。find_element()
メソッドは単一のWebElementを返し、find_elements()
はロケータ条件に一致するWebElementのリストを返します。
前述のように、setup_method()
は初期化の一部であるpytestフィクスチャです。このメソッドは、指定されたテストクラスの下に実装される各テスト関数の前に呼び出されます。
実装されているテストは、ローカルマシンにインストールされたSeleniumやクラウドテストで提供されているオンラインSeleniumグリッド上でも実行できます。LambdaTestは、異なるブラウザやオペレーティングシステム上でPython自動化テストをスケールで実行できるAIパワードテスト実行プラットフォームです。メンテナンスの削減、コストの低減、およびテスト実行の加速が主な利点です。
実装に関しては、唯一の変更点は、テストをクラウドグリッドで実行する際にSeleniumのRemote WebDriverがインスタンス化される点に関連しています。Automation Capabilities Generatorは、テストで使用するテスト組み合わせのためのCapabilitiesを生成するのに役立ちます。
Selenium 4では、Desired Capabilitiesの代わりにブラウザオプションが使用されます。Selenium 3とSelenium 4の違いについて詳しく知りたい場合は、Selenium 3とSelenium 4の違いに関するブログをチェックしてください。
環境変数LT_USERNAME
とLT_ACCESS_KEY
は、LambdaTestアカウントの設定>パスワード&セキュリティから取得できます。この組み合わせは、LambdaTestグリッドURLと共に渡され、クラウドグリッドでテストを実行するのに役立ちます。test_enter_form_details()
メソッドでは、最初にdriver.get()
メソッドを呼び出してテストURLに移動します。
次に、インスタンス化されたブラウザウィンドウを最大化します。これはSeleniumのベストプラクティスの1つとされています。
次に、Input Form Submit要素を、SeleniumのXPathロケーターを使用してfind_element()
メソッドで検索します。検出された後、Seleniumでボタンクリックが呼び出され、以前の手順で検出されたボタン要素にクリックアクションがシミュレートされます。
すべてのテストステップは要素の検出とアクションの実行に関わるため、わずかなメソッドに焦点を当てます。SeleniumでCSSセレクターを使用して企業要素を検出するアプローチは以下の通りです。Selenium WebDriverのsend_keys()
は、検出された要素にテキスト入力を送信するのに役立ちます。
ドロップダウンはウェブサイトで広く使用されており、したがって、Seleniumを使用してドロップダウンとの対話を自動化することは、テストケースにとって絶対に必要です。 Select
クラスは、selenium.webdriver.support.ui モジュールのメソッドを提供し、Seleniumでドロップダウンを操作できます。
ここでは、XPath で見つかったドロップダウン WebElement を入力として持つ Select
クラスのオブジェクト(つまり、country_dropdown
)が作成されます。 Select
クラスの select_by_visible_text()
メソッドは、指定された文字列(つまり、United States)と一致する表示テキストを持つアイテムを選択するのに役立ちます。
フォームのすべての情報が入力され、送信 ボタンがクリックされると、ページ上に成功メッセージ文字列(デフォルト:非表示)が表示されるまで待機します。成功メッセージがページ上に表示されるまで、ExpectedCondition(つまり、要素の存在)を持つ明示的な待機が行われます。
結果の文字列がページ上に存在しない場合は、アサーションが発生します。クラウドでの実行のために、lambda-status
変数は、passed/failed の状態に応じてマークされます。
teardown_method()
フィクスチャには、クラスでのテストの実行後にリソースや状態をクリンナップするための実装が含まれています。 if __name__ == "__main__":
構文は、スクリプトが直接実行された場合にのみコードの実行が行われることを保証します。 pytest.main()
は、スクリプト内のすべての有効化された(つまり、スキップとしてマークされていない)テストをさらに検出して実行する pytest フレームワークを呼び出します。
テスト実行(pytestフレームワーク)
EXEC_PLATFORM
をクラウドに設定した後、LambdaTestクラウドグリッドでpytestテストを実行するには、ターミナルで次のコマンドを呼び出してください:
pytest --verbose --capture=no tests/pytest/pytest_selenium_demo.py
以下は、テスト実行が成功したことを示すLambdaTest Web Automationダッシュボードのスクリーンショットです:
実装(PyUnitフレームワーク)
上記のシナリオのテストスクリプトは、PyUnitフレームワークを使用してtests/pyunit/pyunit_selenium_demo.pyにあります。
テストのコアロジックは、pytestからPyUnit(またはunittest)フレームワークに移行する際に変更されません。 pytest
モジュールの代わりに、コードにunittest
モジュールをインポートします。 テストケースクラスは、unittest.TestCase
を継承したもので、これによりunittestモジュールにこのテストケースであることが通知されます。
pytestのfixtures setup_method()
/teardown()
は、PyUnitフレームワークのsetUp()
/tearDown()
メソッドと類似しています。 setUp()
およびtearDown()
メソッドには、初期化および後始末を行う責任がある実装が含まれています。
以下に、テストスイートを実行するためのボイラープレートコードが示されています:
if __name__ == "__main__":
unittest.main()
テスト実行(PyUnitフレームワーク)
EXEC_PLATFORM
をクラウドに設定した後、次のコマンドをターミナルで実行してPyUnitテストをクラウドグリッドで実行します。
python tests/pyunit/pyunit_selenium_demo.py
以下は、LambdaTest Web Automationダッシュボードのスクリーンショットで、テスト実行が成功したことを示しています。
上記のテストをローカルマシンにインストールされたSeleniumで実行したい場合は、EXEC_PLATFORM
をlocal,に設定し、ローカル実行が完了します。
トップのPythonテストフレームワーク
Pythonは多くのテスト自動化フレームワークをサポートしているため、プロジェクトに適したフレームワークを選択することは非常に重要です。選択は実際には効率的なテストのための基盤を築くことになります。フレームワークの機能だけでなく、該当フレームワークの内部的な専門知識も見ておく必要があります。以下は、いくつかのベストなPythonテストフレームワークです:
PyUnit(unittest)
Pythonで利用可能なデフォルトのフレームワークです。その名前が示すように、主にユニットテストに使用されます。PyUnitはJavaのJUnitフレームワークからインスパイアされており、類似の構造と機能を共有しています。
unittestフレームワークは、テストの自動化のためのセットアップとシャットダウンコードの共有、テストの報告フレームワークからの独立、などをサポートしています。オブジェクト指向の方法でテストスイートやテストケースをサポートします。また、テストランナーも備えており、テストの実行をオーケストレートする責任を持つコンポーネントです。
pytest
これはPythonにおける最も人気のあるテスト自動化フレームワークの1つです。テストの実装において冗長でユーザーフレンドリーな構文を使用します。pytestは、単体テストからウェブサイトやWebアプリケーションの複雑な機能テストまで実装するのに活用できます。
pytestを使用して書かれたテストは、フレームワークが冗長なコードを必要としないため、はるかにコンパクトです。pytestには、テストモジュールと関数の自動検出を支援する組込み機能があります。
Robot
これは、Robot Process Automation(RPA)やテスト自動化に主に使用される、キーワード駆動のオープンソースPythonフレームワークです。pytestフレームワークと同様に、Robotも拡張可能です。人間が読みやすい構文/キーワードの使用は、Robotを学習する際の学習曲線を最小限に抑えます。
Robotで書かれたテストは、.robot
拡張子で保存されます。フロントエンドのテストにRobotを使用する場合、Robot Framework用のWebテストライブラリであるSeleniumLibraryを使用できます。このライブラリはさまざまなキーワード(Click Button、Click Image、Open Browser、Drag and Dropなど)をサポートしています。
Nose2
Noseの後継であり、PyUnit(またはunittest)フレームワークの機能を拡張したPythonテストフレームワークです。unittestの作業経験がある場合、Nose2を始めるのは比較的簡単です。
Nose2の大きな利点は、テストをより簡単かつ迅速にする多数の組み込みNoseプラグインが利用可能であることです。Nose2のプラグインは、テストのパラメータ化、テストのより良い組織化、フィクスチャのサポート、テストの検出などに役立ちます。
Behave
これは、振る舞い駆動開発(BDD)に使用されるPythonフレームワークです。テストは、Given-When-Then形式に基づくGherkin構文に基づいています。
テストはシナリオファイルやフィーチャーファイルで実装されているため、非技術者でもQAプロセスの一部となることができます。SpecFlow(C#)やCucumber(Java、JS、Ruby)などが他の一般的なBDDフレームワークです。
結論
これまで見てきたように、Pythonは自動テストにおいて最も優れたスクリプト言語です。Pythonの自動化テストを始めるのは比較的簡単です。その幅広いテストフレームワークは、ユニットテスト、クロスブラウザーテストなどに使用できます。Seleniumテストのための好きなプログラミング言語と、自動化テストの王者であるPythonとの比較評価を以下にお知らせください。ハッピーなテスト!
Source:
https://dzone.com/articles/python-automation-testing-with-examples