Selenium 在 Jenkins 中构建不稳定,但在本地很好

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

下面发布的解决方案 - TLDR;这愚蠢地使用 presence_of_element_ located 与错误的用例,然后不考虑浏览器和驱动程序不同步。

问题:测试在本地通过但通过 Jenkins 失败的问题。


本地总是通过(windows VM)

Local

Jenkins 有时会通过(Windows VM)

Jenkins


本地测试和 Jenkins 测试都在同一虚拟机(Windows 代理)上运行。我遵循了这些人的建议,添加了以下参数,但没有改变/成功:

options = Options()
options.add_experimental_option('excludeSwitches', ['enable-logging'])  #Fixes the problem with console outputing warning "Bluetooth: bluetooth_adapter_winrt.cc:1074 Getting Default Adapter failed."
options.add_argument('--no-sandbox')
options.add_argument("enable-automation")
#options.add_argument("--headless") #CAUSES TIMEOUT ERROR
options.add_argument("--window-size=1920,1080")
options.add_argument("--disable-extensions")
options.add_argument("--dns-prefetch-disable")
options.add_argument("--disable-gpu")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-browser-side-navigation")
options.add_argument("--force-device-scale-factor=1")
prefs = {"download.default_directory" : r"C:\Users\MyUser\Path\Directory\\"} 
options.add_experimental_option("prefs", prefs)
s = Service('chromeDriverPath/chromedriver.exe')
context.driver = webdriver.Chrome(service=s, options=options,desired_capabilities=capa)

--headless
选项会产生错误:

Timed out receiving message from renderer: 10.000

所以我已经评论了。


问题: 为什么我的本地总是通过,但我的 Jenkins 不稳定,即使它们在同一个虚拟机上运行测试。我该如何解决这个问题?


背景

我看过this类似的问题,但没有解决方案。不幸的是我花了很多时间试图解决这个问题。

  • 不是代码 - 我确信它不是代码,因为我自己完成了所有代码(Python + 行为)。只是意味着我在其创建过程中对其进行了广泛的测试,并且每次在本地开发中它都会通过。
  • 驱动程序和浏览器同步 - 我正在研究“Selenium 驱动程序和浏览器之间的同步是问题”,如@ekostadinov所述

已安装的软件包版本 (PIP)

Package Version --------------------- --------- allure-behave 2.9.45 allure-python-commons 2.9.45 async-generator 1.10 attrs 21.4.0 behave 1.2.6 cairocffi 1.3.0 CairoSVG 2.5.2 certifi 2022.6.15 cffi 1.15.1 charset-normalizer 2.1.0 chromedriver 2.24.1 click 8.1.3 colorama 0.4.5 cryptography 37.0.4 cssselect2 0.6.0 defusedxml 0.7.1 et-xmlfile 1.1.0 h11 0.13.0 idna 3.3 lxml 4.9.1 multipledispatch 0.6.0 numpy 1.23.1 openpyxl 3.0.10 outcome 1.2.0 pandas 1.4.3 parse 1.19.0 parse-type 0.6.0 Pillow 9.2.0 pip 22.0.4 pluggy 1.0.0 pycparser 2.21 pygal 3.0.0 pyOpenSSL 22.0.0 pypiwin32 223 pyshadow 0.0.4 PySocks 1.7.1 python-dateutil 2.8.2 python-docx 0.8.11 python-dotenv 0.20.0 pytz 2022.1 pywin32 304 requests 2.28.1 selenium 4.3.0 setuptools 58.1.0 six 1.16.0 sniffio 1.2.0 sortedcontainers 2.4.0 tinycss2 1.1.1 trio 0.21.0 trio-websocket 0.9.2 urllib3 1.26.10 webdriver-manager 3.8.1 webencodings 0.5.1 wsproto 1.1.0


更新 08/02/2022 4:11pm

添加更多隐式和显式等待时间修复了许多不稳定的测试

    有些地方需要 time.sleep(x) 等待下载完成,然后才能提取 csv/xlsx 超时时间在 WebDriverWait(context.driver,
  • timeOutTimeInSeconds).until(EC.presence_of_element_ located((By.CSS_SELECTOR, ' {$路径}')))
仍然面临一些仅通过 Jenkins 进行的不稳定测试,涉及 WebDriverWait(context.driver, 180).until(EC.presence_of_element_ located((By.CSS_SELECTOR, '{$path}')))


更新 08/03/2022 8:20am 解决方案

    正如
  1. @undected Selenium 所指出的,在此用例中使用 presence_of_element_ located 可能是不正确的。这似乎是片状测试的来源。可以通过文档找到替代实现。这更多地解释了为什么在某些情况下这是不好的做法:
    “如果您的用例是验证任何元素是否存在,则需要诱导 WebDriverWait 将预期条件设置为 Presence_of_element_ located(),这是检查元素是否存在于页面 DOM 上的期望。
  • 这并不一定意味着该元素是可见的”(@未检测到的硒)。 (来源
一个问题是我需要等到元素变得可见,而不仅仅是在 DOM 中。我必须将一些presente_of_element_ located()更改为visibility_of_element_ located():

    “如果您的用例是提取任何元素的任何属性,您需要诱导 WebDriverWait 将预期条件设置为visibility_of_element_ located(定位器),这是检查元素是否存在于页面的 DOM 上并且可见的期望。可见性意味着元素不仅会显示,而且高度和宽度都大于 0。” (
  • @未检测到的硒)。 (来源
    在显式等待时间中添加额外的时间修复了由于浏览器和驱动程序之间的
  1. 不同步而导致的许多不稳定的测试。

示例

之前

WebDriverWait(context.driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '{$path}')))

之后

WebDriverWait(context.driver, 60).until(EC.visibility_of_element_located((By.CSS_SELECTOR, '{$path}')))

总结

使用正确的预期条件很重要。我什至不得不将我的其中一个更改为

element_to_be_clickable 以使其不不稳定。这是一个涉及等待可点击元素弹出的测试。确保阅读文档并使用最适合的预期条件以避免错误。另外,如果出现异步错误,请考虑延长隐式或显式等待时间。失败时的屏幕截图可以帮助您调试此问题。

selenium google-chrome jenkins selenium-chromedriver renderer
2个回答
1
投票
您需要解决以下几个问题:

  • 假设您使用的是

    windows

    options.add_argument("--disable-gpu")
    作为论点

    --disable-gpu

    仅对非Windows环境有效,不再相关。
    

  • 有些论点不再相关,所以你可以删除它们:

    options.add_argument("enable-automation") options.add_argument("--disable-extensions")
    
    
  • 理想情况下,

    jenkins非root/非管理员用户身份执行,因此您可能不需要参数:

    options.add_argument('--no-sandbox') options.add_argument("--disable-dev-shm-usage")
    
    
  • 可能您也不需要以下任一参数:

    options.add_argument("--dns-prefetch-disable") options.add_argument("--disable-browser-side-navigation") options.add_argument("--force-device-scale-factor=1")
    
    
  • 您可能想将其他参数调整为:

    prefs = {"download.default_directory" : r'C:\Users\MyUser\Path\Directory\'} options.add_experimental_option("prefs", prefs)
    
    
  • 最后,您没有使用任何

    capabilities

    ,因此您可以从构造函数中删除参数:

    desired_capabilities=capa
    
    

解决方案

您的有效代码块可以是:

options = Options() options.add_argument("--headless") options.add_argument("--window-size=1920,1080") options.add_experimental_option('excludeSwitches', ['enable-logging']) options.add_experimental_option("excludeSwitches", ["enable-automation"]) prefs = {"download.default_directory" : r'C:\Users\MyUser\Path\Directory\'} options.add_experimental_option("prefs", prefs) s = Service('chromeDriverPath/chromedriver.exe') context.driver = webdriver.Chrome(service=s, options=options)
    

0
投票
尝试更改您的 AWS ec2instance 类型,因为 jenkins 测试随机失败和 chromeheadless 连接失败通常是由于缺乏资源造成的

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