当 Selenium 测试失败时停止 ChromeDriver 回溯日志

问题描述 投票:0回答:1

我对

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
python python-3.x selenium-webdriver selenium-chromedriver stack-trace
1个回答
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 构建的框架。)

© www.soinside.com 2019 - 2024. All rights reserved.