我对
ChromeDriver
的详细日志记录有疑问
当硒测试失败时,除了终端中的标准错误日志之外,我还会收到如下回溯消息:
Stacktrace:
Backtrace:
Ordinal0 [0x00B378B3+2193587]
Ordinal0 [0x00AD0681+1771137]
Ordinal0 [0x009E41A8+803240]
...
如何禁用此回溯? (Python 中最好的:)
我的设置:
Windows 10
Python 3.8.3
Selenium 4.4.3
Chrome: 105.0.5195.127
ChromeDriver: 105.0.5195.52
我已经阅读了下面的讨论,但没有找到明确的答案:
https://github.com/SeleniumHQ/selenium/issues/9977
https://bugs.chromium.org/p/chromedriver/issues/detail?id=3944
选中的选项:
service.log_file = -1
opts.add_argument('--incognito')
opts.add_argument('--log-level=0')
opts.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = Chrome(service=service, options=opts, service_log_path='NUL')
示例代码
from unittest import TestCase
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
class SelBacktrace(TestCase):
def setUp(self):
service = ChromeService(ChromeDriverManager().install())
service.log_file = -1
opts = webdriver.ChromeOptions()
opts.add_argument("--log-level=0")
opts.add_experimental_option('excludeSwitches', ['enable-logging'])
self.driver = webdriver.Chrome(service=service, options=opts, service_log_path='NUL')
self.driver.get('https://httpbin.org/anything/')
def tearDown(self):
self.driver.quit()
def test_backtrace(self):
element_located = expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, '.unexisting'))
WebDriverWait(self.driver, 1).until(element_located)
输出示例
Error
Traceback (most recent call last):
File "C:\backtrace\test.py", line 27, in test_backtrace
WebDriverWait(self.driver, 1).until(element_located)
File "C:\backtrace\venv\lib\site-packages\selenium\webdriver\support\wait.py", line 90, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x0023DF13+2219795]
Ordinal0 [0x001D2841+1779777]
Ordinal0 [0x000E423D+803389]
Ordinal0 [0x00113025+995365]
Ordinal0 [0x001131EB+995819]
Ordinal0 [0x00140F52+1183570]
Ordinal0 [0x0012E844+1108036]
Ordinal0 [0x0013F192+1175954]
Ordinal0 [0x0012E616+1107478]
Ordinal0 [0x00107F89+950153]
Ordinal0 [0x00108F56+954198]
GetHandleVerifier [0x00532CB2+3040210]
GetHandleVerifier [0x00522BB4+2974420]
GetHandleVerifier [0x002D6A0A+565546]
GetHandleVerifier [0x002D5680+560544]
Ordinal0 [0x001D9A5C+1808988]
Ordinal0 [0x001DE3A8+1827752]
Ordinal0 [0x001DE495+1827989]
Ordinal0 [0x001E80A4+1867940]
BaseThreadInitThunk [0x75CE6739+25]
RtlGetFullPathName_UEx [0x772990AF+1215]
RtlGetFullPathName_UEx [0x7729907D+1165]
(No symbol) [0x00000000]
Process finished with exit code 1
您可以使用更清晰的错误输出来包装基本的 selenium 调用。这是一个完整的示例,您可以使用
pytest
或 pythom -m unittest
运行(我将文件命名为 refined_raw.py
):
import sys
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from unittest import TestCase
class RefinedRawSelenium(TestCase):
def setUp(self):
self.driver = None
options = webdriver.ChromeOptions()
options.add_argument("--disable-notifications")
if "linux" in sys.platform:
options.add_argument("--headless")
options.add_experimental_option(
"excludeSwitches", ["enable-automation", "enable-logging"],
)
prefs = {
"credentials_enable_service": False,
"profile.password_manager_enabled": False,
}
options.add_experimental_option("prefs", prefs)
self.driver = webdriver.Chrome(options=options)
def tearDown(self):
if self.driver:
try:
if self.driver.service.process:
self.driver.quit()
except Exception:
pass
def wait_for_element_visible(
self, selector, by="css selector", timeout=5
):
try:
return WebDriverWait(self.driver, timeout).until(
EC.visibility_of_element_located((by, selector))
)
except Exception:
raise Exception(
"Selector {%s} was not visible after %s seconds!"
% (selector, timeout)
)
def open(self, url):
self.driver.get(url)
def click(self, selector, by="css selector", timeout=5):
el = self.wait_for_element_visible(selector, by=by, timeout=timeout)
el.click()
def type(self, selector, text, by="css selector", timeout=5):
el = self.wait_for_element_visible(selector, by=by, timeout=timeout)
el.clear()
if not text.endswith("\n"):
el.send_keys(text)
else:
el.send_keys(text[:-1])
el.submit()
def assert_element(self, selector, by="css selector", timeout=5):
self.wait_for_element_visible(selector, by=by, timeout=timeout)
def assert_text(self, text, selector="html", by="css selector", timeout=5):
el = self.wait_for_element_visible(selector, by=by, timeout=timeout)
self.assertIn(text, el.text)
def assert_exact_text(self, text, selector, by="css selector", timeout=5):
el = self.wait_for_element_visible(selector, by=by, timeout=timeout)
self.assertEqual(text, el.text)
def test_add_item_to_cart(self):
self.open("https://www.saucedemo.com")
self.type("#user-name", "standard_user")
self.type("#password", "secret_sauce\n")
self.assert_element("div.inventory_list")
self.assert_text("PRODUCTS", "span.title")
self.click('button[name*="backpack"]')
self.click("#shopping_cart_container a")
self.assert_exact_text("YOUR CART", "span.title")
self.assert_text("Backpack", "div.cart_item")
self.click("#react-burger-menu-btn")
self.click("a#logout_sidebar_link")
self.assert_element("input#login-button")
这是使用
pytest
运行测试时的样子:
$ pytest refined_raw.py
======================================= test session starts
platform darwin -- Python 3.10.5, pytest-7.1.3, pluggy-1.0.0
collected 1 item
refined_raw.py .
======================================== 1 passed in 4.62s
这是使用
python -m unittest
运行测试时的样子:
$ python -m unittest refined_raw.py
.
----------------------------------------------------------------------
Ran 1 test in 4.199s
OK
如果您将选择器更改为假的,导致测试故意失败,则输出可能如下所示:
Exception: Selector {fake.element} was not visible after 5 seconds!
在包装所有 selenium 方法以获得上面看到的所需输出之前,您可能需要尝试 https://github.com/seleniumbase/SeleniumBase ,它会为您完成所有这些工作,甚至更多。 (完全公开,这是我多年来为 Python 和 Selenium 构建的框架。)