我目前正在尝试使用 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 发送的请求,并在由驱动程序驱动的浏览器实例中显示假响应主体?任何帮助表示赞赏。