[英]Mocking requests sent by the Selenium WebDriver in Python and having the fake responses displayed in the browser instance driven by the driver instead
我目前正在嘗試將Python版本的Selenium WebDriver與Pytest測試框架一起使用,以對Web應用程序進行自動化測試。 嘗試在Selenium代碼中進行HTTP請求模擬時遇到了一個問題。 我編寫了一個名為“ Selenium_WebDriver_Mocking_test.py”的模塊,在其中導航至Python官方網站,並在頁面頂部的搜索框中填寫搜索詞,然后按Enter進入結果頁面。 當我不嘗試模擬任何東西時,代碼可以完美運行。 假設您同時安裝了Selenium和Pytest,則可以通過輸入以下命令從命令行界面運行它:
py.test full/path/to/module/Selenium_WebDriver_Mocking_test.py
或通過鍵入以下內容:
python -m pytest full/path/to/module/Selenium_WebDriver_Mocking_test.py
代碼如下所示。
# contents of Selenium_WebDriver_Mocking_test.py
import selenium.webdriver
import selenium.webdriver.common.keys as common
import selenium.webdriver.support.ui as user_interface
import selenium.webdriver.support.expected_conditions as expected_conditions
import selenium.webdriver.common.by as locate
import re
import pytest
browsers = {
"firefox_driver": selenium.webdriver.Firefox(),
"chrome_driver": selenium.webdriver.Chrome()
}
website_homepage_url = "http://www.python.org"
title_1 = "Welcome to Python.org"
# Test set-up and tear down functions
@pytest.fixture(scope = 'session', params = browsers.keys())
def browser(request):
driver = browsers[request.param]
driver.maximize_window()
def close_browser():
driver.quit()
request.addfinalizer(close_browser)
return driver
@pytest.mark.parametrize(
"search_term",
[
("pycon"),
("tkinter"),
("django"),
]
)
def test_mocking_get_request_works_properly(search_term, browser):
browser.get(website_homepage_url)
assert title_1 in browser.title # Check you are on the right page
search_text_box = browser.find_element_by_css_selector("#id-search-field")
search_text_box.send_keys(search_term)
search_text_box.send_keys(common.Keys.RETURN)
search_page_title = user_interface.WebDriverWait(browser, 10).until(
expected_conditions.visibility_of_element_located(
(locate.By.XPATH, "//h2[contains(., 'Search')]")))
assert search_page_title.is_displayed() # Check you are on the right page
然后,我為偽造的結果頁面編寫了一些HTML,並嘗試使用Gabriel Falcao編寫的HTTPretty工具將該頁面作為響應返回到該頁面,而不是真正的Python.org結果頁面。 修改后的代碼如下所示。
# contents of Selenium_WebDriver_Mocking_test.py
import selenium.webdriver
import selenium.webdriver.common.keys as common
import selenium.webdriver.support.ui as user_interface
import selenium.webdriver.support.expected_conditions as expected_conditions
import selenium.webdriver.common.by as locate
import time
import httpretty
import re
import pytest
browsers = {
"firefox_driver": selenium.webdriver.Firefox(),
"chrome_driver": selenium.webdriver.Chrome()
}
website_homepage_url = "http://www.python.org"
title_1 = "Welcome to Python.org"
request_url_pattern = re.compile('https://www.python.org/search/.*')
response_html_lines = ["<!DOCTYPE html>",
"<html>",
"<head>",
"<title>Welcome to my fun page</title>",
"<meta charset=\"UTF-8\">"
"</head>",
"<body>",
"<h2>Search Python.org</h2>",
"<h2>So far so good (^_^)</h2>",
"<img src = \"http://i.imgur.com/EjcKmEj.gif\">",
"</body>",
"</html>"]
fake_response_html = "\n".join(response_html_lines)
# Test set-up and tear down functions
@pytest.fixture(scope = 'session', params = browsers.keys())
def browser(request):
driver = browsers[request.param]
driver.maximize_window()
def close_browser():
driver.quit()
request.addfinalizer(close_browser)
return driver
@pytest.mark.parametrize(
"search_term",
[
("pycon"),
("tkinter"),
("django"),
]
)
def test_mocking_get_request_works_properly(search_term, browser):
httpretty.enable()
httpretty.register_uri(httpretty.GET,
request_url_pattern,
body = fake_response_html)
browser.get(website_homepage_url)
assert title_1 in browser.title # Check you are on the right page
search_text_box = browser.find_element_by_css_selector("#id-search-field")
search_text_box.send_keys(search_term)
search_text_box.send_keys(common.Keys.RETURN)
search_page_title = user_interface.WebDriverWait(browser, 10).until(
expected_conditions.visibility_of_element_located(
(locate.By.XPATH, "//h2[contains(., 'Search')]")))
assert search_page_title.is_displayed() # Check you are on the right page
time.sleep(10)
httpretty.disable()
httpretty.reset()
這種方法行不通,並且我在一次測試迭代的日志中收到以下消息:
C:\Python27\python.exe "C:\Program Files (x86)\JetBrains\PyCharm
Community Edition 4.0.4\helpers\pycharm\pytestrunner.py" -p pytest_teamcity C:/Users/johnsmith/Computer_Code/Python/Automation_Testing/Selenium_WebDriver_Mocking_test.py
Testing started at 10:10 ...
============================= test session starts =============================
platform win32 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
plugins: xdist
collected 6 items
../../../../../../Users/johnsmith/Computer_Code/Python/Automation_Testing/Selenium_WebDriver_Mocking_test.py F
search_term = 'pycon'
browser = <selenium.webdriver.firefox.webdriver.WebDriver object at 0x0000000002E67EB8>
@pytest.mark.parametrize(
"search_term",
[
("pycon"),
("tkinter"),
("django"),
]
)
def test_mocking_get_request_works_properly(search_term, browser):
httpretty.enable()
httpretty.register_uri(httpretty.GET,
request_url_pattern,
body = fake_response_html)
> browser.get(website_homepage_url)
C:\Users\johnsmith\Computer_Code\Python\Automation_Testing\Selenium_WebDriver_Mocking_test.py:70:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py:187: in get
self.execute(Command.GET, {'url': url})
C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py:173: in execute
response = self.command_executor.execute(driver_command, params)
C:\Python27\lib\site-packages\selenium\webdriver\remote\remote_connection.py:349: in execute
return self._request(command_info[0], url, body=data)
C:\Python27\lib\site-packages\selenium\webdriver\remote\remote_connection.py:379: in _request
self._conn.request(method, parsed_url.path, body, headers)
C:\Python27\lib\httplib.py:973: in request
self._send_request(method, url, body, headers)
C:\Python27\lib\httplib.py:1007: in _send_request
self.endheaders(body)
C:\Python27\lib\httplib.py:969: in endheaders
self._send_output(message_body)
C:\Python27\lib\httplib.py:829: in _send_output
self.send(msg)
C:\Python27\lib\httplib.py:791: in send
self.connect()
C:\Python27\lib\httplib.py:772: in connect
self.timeout, self.source_address)
C:\Python27\lib\site-packages\httpretty\core.py:477: in create_fake_connection
s.connect(address)
C:\Python27\lib\site-packages\httpretty\core.py:311: in connect
self.truesock.connect(self._address)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'connect', self = <socket._socketobject object at 0x000000000385F9A0>
args = (('127.0.0.1', '49952'),)
def meth(name,self,*args):
> return getattr(self._sock,name)(*args)
E TypeError: an integer is required
C:\Python27\lib\socket.py:224: TypeError
我還嘗試使用David Cramer編寫的響應工具。 盡管那沒有返回任何錯誤,但它也什么也沒做,測試就好像沒有發生任何模擬一樣進行。 我的問題是:Python中有沒有辦法模擬Selenium WebDriver發送的請求,並在驅動程序驅動的瀏覽器實例中顯示偽造的響應主體? 任何幫助表示贊賞。
對於您的情況,您不能使用“標准”模擬方法,因為您顯然會干擾Webdriver的通信。 相反,我建議您使用https://pypi.python.org/pypi/pytest-localserver,因此實際上您可以在某個隨機端口上運行本地服務器,並且服務器需要您所需要的。 我使用該技術來測試pytest-splinter(我也建議您實際使用它進行測試),在這里您可以看到它的工作原理: https : //github.com/pytest-dev/pytest-splinter/blob/master /tests/test_plugin.py
如果您使用pytest-splinter,您的代碼將如下所示:
"""Testing fake html page with pytest-splinter."""
import pytest
from pytest_localserver.http import WSGIServer
import urlparse
browsers = [
"firefox",
"chrome"
]
title_1 = "Welcome to my fun page"
response_html = """
<!DOCTYPE html>
<html>
<head>
<title>Welcome to my fun page</title>
<meta charset="UTF-8">
</head>
<body>
<h2>Search Python.org</h2>
<form action="/">
<input id="id-search-field" name="search" />
</form>
</body>
</html>
"""
def simple_app(environ, start_response):
"""Simplest possible WSGI application."""
status = '200 OK'
response_headers = [('Content-type', 'text/html')]
start_response(status, response_headers)
query = urlparse.parse_qs(environ['QUERY_STRING'])
if 'search' in query:
search_term = query['search'][0]
return ["""
<!DOCTYPE html>
<html>
<body>
<h2>So far so good (^_^)</h2>
<p>You searched for: "{search_term}"</p>
<img src="http://i.imgur.com/EjcKmEj.gif">
</body>
</html>
""".format(search_term=search_term)]
else:
return [response_html]
@pytest.yield_fixture
def testserver():
"""Define the testserver."""
server = WSGIServer(application=simple_app)
server.start()
yield server
server.stop()
@pytest.fixture(params=browsers)
def splinter_webdriver(request):
return request.param
@pytest.mark.parametrize(
"search_term",
[
("pycon"),
("tkinter"),
("django"),
]
)
def test_get_request_works_properly(search_term, browser, testserver):
browser.visit(testserver.url)
assert title_1 in browser.title # Check you are on the right page
assert browser.find_by_xpath("//h2[contains(., 'Search')]").visible # Check you are on the right page
browser.find_by_css("#id-search-field").fill(search_term + '\r')
assert browser.find_by_xpath(
"""//p[contains(., 'You searched for: "{search_term}"')]""".format(search_term=search_term)).visible
assert browser.find_by_xpath(
"//img[contains(@src, 'i.imgur.com/EjcKmEj.gif')]").visible # Check you get results
我為此使用的要求是:
pytest pytest-splinter pytest-本地服務器
(所有最新)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.