Seleniumと通信環境が悪い状態の試験
目的
Selenium + Pythonを用いてなるべく通信環境が悪い状態の試験を行う。
以下の読者を対象とする
- pythonの基本的な操作を行えること
- seleniumの基本的な操作を行えること
- webアプリケーションの開発経験があること
手動で通信環境の悪い試験を行う方法
手動試験で通信環境の悪いネットワーク環境を再現した試験を行う場合、2つの方法がある。
- OS全体の通信状態を設定する
- ブラウザの開発者ツールを使って通信状態を設定する
OS全体の通信状態を設定する
macの場合はNetwork link conditionerを使用する。
Windowsの場合はClumsyを使用する。
linuxの場合はlinuxはtc & netemを使用する。
この手法のメリットはOS全体の通信状態を悪くするため、ブラウザだけでなくネイティブアプリの試験にも使用できることである。
このメリットは同時にデメリットになる。たとえばネットワークドライブをマウントしている場合、フリーズする場合があるし、リモートデスクトップで操作している場合も正常に動作しなくなる。
ブラウザの開発者ツールを使って通信状態を設定する。
Chrome97の場合
ディベロッパーツールのネットワークタブにて「その他のネットワークの状態」アイコンを押下する。
ネットワークスロトリングを押下して任意の状態を選ぶ。
追加により任意の状態を追加することが可能
Firefox96の場合
ウェブ開発ツールのネットワークタブにて「帯域制限なし」のリストを変更する
Seleniumで通信環境の悪い試験を行う方法
今回はChromeを対象としてSeleniumで通信環境が悪い状況での試験を行う方法について紹介する。
ChromeDriverを使用してローカルのchromeを操作する
ローカルのChromeに対して通信環境の設定を行うにはset_network_conditionsを使用する。
from selenium import webdriver
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
import datetime
chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument('--headless')
chromeOptions.add_argument('--disable-gpu')
chromeOptions.add_argument('--no-sandbox')
chromeOptions.add_argument("--lang=ja")
driver = Chrome(options=chromeOptions)
driver.set_network_conditions(
offline = False,
latency = 10000, # 10秒遅延させる
download_throughput = 500 * 1024,
upload_throughput = 500 * 1024
)
print(datetime.datetime.now())
driver.get('https://needtec.sakura.ne.jp/')
print(driver.find_element(by=By.TAG_NAME, value='h1').text)
print(datetime.datetime.now())
driver.quit()
RemoteDriverを使用してリモートのchromeを操作する
RemoteDriverの場合、set_network_conditionsが使用できないので、send_command_and_get_resultを直接POSTしてNetwork.emulateNetworkConditionsを直接実行する
from selenium import webdriver
from selenium.webdriver.common.by import By
import datetime
import json
chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument('--headless')
chromeOptions.add_argument('--disable-gpu')
chromeOptions.add_argument('--no-sandbox')
chromeOptions.add_argument("--lang=ja")
def sendCommand(driver, cmd, params={}):
resource = "/session/%s/chromium/send_command_and_get_result" % driver.session_id
url = driver.command_executor._url + resource
body = json.dumps({'cmd': cmd, 'params': params})
response = driver.command_executor._request('POST', url, body)
return response.get('value')
driver = webdriver.Remote('http://127.0.0.1:4444/wd/hub', chromeOptions.to_capabilities())
res = sendCommand(
driver,
'Network.emulateNetworkConditions',
dict({
'offline': False,
'latency': 10000, #10秒遅延
'downloadThroughput': 500 * 1024,
'uploadThroughput': 500 * 1024
})
)
print(res)
print(datetime.datetime.now())
driver.get('https://needtec.sakura.ne.jp/')
print(driver.find_element(by=By.TAG_NAME, value='h1').text)
print(datetime.datetime.now())
driver.quit()
参考
・Add Vendor specific commands for Remote webdriver #7914
・Enable execute_cdp for webdriver.Remote ? #8672
Discussion