簡體   English   中英

模擬Selenium WebDriver在Python中發送的請求,並在由驅動程序驅動的瀏覽器實例中顯示假響應

[英]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 WebDriverPytest測試框架一起使用,以對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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM