J'essaie actuellement d'utiliser la version Python de avec le framework de test Pytest pour faire des tests d'automatisation de web applications. Je suis tombé sur un problème en essayant de faire une requête HTTP moqueuse dans mon code Selenium. J'ai écrit un module intitulé "Selenium_WebDriver_Mocking_test.py" où je navigue vers le site officiel de Python et remplis un terme de recherche dans la boîte de recherche en haut de la page, puis appuie sur Entrée pour aller à la page des résultats. Le code fonctionne parfaitement quand je n'essaie pas de me moquer de quoi que ce soit. En supposant que vous avez à la fois Sélénium et Pytest installé, vous pouvez l'exécuter à partir de l'interface de ligne de commande en tapant la commande suivante:Requêtes de simulation envoyées par le Selenium WebDriver en Python et ayant les fausses réponses affichées dans l'instance de navigateur pilotée par le pilote à la place
py.test full/path/to/module/Selenium_WebDriver_Mocking_test.py
ou en tapant la commande suivante:
python -m pytest full/path/to/module/Selenium_WebDriver_Mocking_test.py
Le code est illustré ci-dessous.
Page# 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
J'ai alors écrit quelques HTML pour un résultats faux et ont essayé d'utiliser l'outil HTTPretty écrit par Gabriel Falcao pour retourner cette page comme une réponse qui apparaît dans le navigateur au lieu de la vraie page de résultats Python.org. Le code modifié est indiqué ci-dessous.
# 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()
Cette approche n'a pas fonctionné et je reçu le message suivant dans le journal d'une des itérations de test:
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
J'ai aussi essayé d'utiliser l'outil de réponses écrites par David Cramer. Bien que cela n'ait renvoyé aucune erreur, il n'a rien fait du tout et le test s'est déroulé comme si aucune moquerie n'avait eu lieu. Ma question est la suivante: y a-t-il un moyen en Python de se moquer des requêtes envoyées par le Selenium WebDriver et d'avoir les faux corps de réponse affichés dans l'instance du navigateur pilotée par le pilote à la place? Toute aide est appréciée.
Merci pour votre réponse. J'ai installé pytest-localserver et j'ai ensuite essayé de suivre les exemples donnés et votre exemple mais sans succès. Chaque fois que je tape httpserver dans mon éditeur IDE, j'obtiens une erreur de référence non résolue. Pourriez-vous préciser comment implémenter votre méthode dans le fichier Selenium_WebDriver_Mocking_test.py que j'ai posté ci-dessus. –
Je vais avoir un peu de temps plus tard aujourd'hui pour écrire un exemple pour vous –
mais pour l'instant - votre IDE ne devrait pas essayer de résoudre les appareils du tout.Les appareils sont fournis par des machines pytest, il suffit de les utiliser comme arguments de la fonction - comme dans mon test. –