You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python+Selenium:如何为@pytest.mark.parametrize传入函数并解决报错

问题分析

你遇到的AttributeError: 'function' object has no attribute 'execute_script'错误,根源在于测试收集阶段的执行时机问题:

  • @pytest.mark.parametrize是在pytest收集测试用例时就执行的,此时你的driver fixture还没有被实例化为WebDriver对象,传入get_images_list的driver只是一个fixture函数本身,自然没有execute_script方法。
  • 另外,即使能获取到元素对象,它也是绑定到特定driver实例的,跨测试用例复用会触发StaleElementReferenceException,所以直接参数化元素对象本身不可行。
解决方案

方案一:用pytest_generate_tests动态参数化图片src

通过pytest的钩子函数,在测试运行前临时初始化driver获取所有图片的src,再将src作为参数传入测试用例,每个用例中重新定位图片并检查加载状态:

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def pytest_generate_tests(metafunc):
    # 仅当测试用例包含image_src参数时才执行参数化
    if "image_src" in metafunc.fixturenames:
        # 临时初始化driver获取图片src列表
        temp_driver = webdriver.Chrome()
        temp_driver.get("https://openweathermap.org/")
        # 提取所有图片的src并去重
        image_srcs = temp_driver.execute_script(
            "return Array.from(document.querySelectorAll('img')).map(img => img.src)"
        )
        unique_srcs = list(set(image_srcs))
        temp_driver.quit()
        # 动态生成测试参数
        metafunc.parametrize("image_src", unique_srcs)

@pytest.fixture(scope="module")
def driver():
    # 正式测试用的driver实例
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_image_load(driver, image_src):
    driver.get("https://openweathermap.org/")
    try:
        # 根据src定位图片元素
        image = driver.find_element(By.CSS_SELECTOR, f"img[src='{image_src}']")
        # 检查图片是否加载完成(更可靠的判断方式)
        is_loaded = driver.execute_script(
            "return arguments[0].complete && arguments[0].naturalWidth > 0",
            image
        )
        assert is_loaded, f"图片 {image_src} 未正常显示"
    except:
        pytest.fail(f"图片 {image_src} 不存在或加载失败")

方案二:通过fixture参数化图片src

利用fixture的params属性,结合全局fixture获取图片src列表,实现参数化:

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

@pytest.fixture(scope="module")
def driver():
    driver = webdriver.Chrome()
    driver.get("https://openweathermap.org/")
    yield driver
    driver.quit()

@pytest.fixture(scope="module")
def all_image_srcs(driver):
    # 获取所有图片的src并去重
    srcs = driver.execute_script(
        "return Array.from(document.querySelectorAll('img')).map(img => img.src)"
    )
    return list(set(srcs))

@pytest.fixture(scope="function", params=[])
def image_src(request, all_image_srcs):
    # 将src列表作为参数传递给每个测试用例
    request.param = all_image_srcs
    return request.param

def test_image_load(driver, image_src):
    image = driver.find_element(By.CSS_SELECTOR, f"img[src='{image_src}']")
    is_loaded = driver.execute_script(
        "return arguments[0].complete && arguments[0].naturalWidth > 0",
        image
    )
    assert is_loaded, f"图片 {image_src} 未正常显示"
关键注意点
  • 不要参数化WebElement对象:元素实例与特定driver实例绑定,跨用例复用必然触发过期元素异常。
  • 图片加载判断用complete+naturalWidth:比单纯判断width/height更可靠,能区分图片是否真的加载完成(而非占位宽高)。

内容的提问来源于stack exchange,提问作者zaelcovsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:17:46