在 Pytest 中参数化静态 webdriver 夹具和生成器?

Parametrizing a static webdriver fixture and a generator in Pytest?

我正在构建一个自动化测试以查找 WP 插件中任何可能的死 links。为此,我有两个辅助函数。

第一个启动 Selenium 网络驱动程序:

@pytest.fixture(scope='session')
def setup():
    d = webdriver.Firefox()
    site = os.getenv('TestSite')
    d.get(site)
    login = d.find_element_by_id('user_login')
    d.implicitly_wait(5)
    user, pw = os.getenv('TestUser'), os.getenv('TestPw')
    d.find_element(By.ID, 'user_login').send_keys(user)
    d.find_element(By.ID, 'user_pass').send_keys(pw)
    d.find_element(By.ID, 'wp-submit').click()
    yield d, site
    d.quit()

第二个读取 JSON 文件,挑选出文件中的每一页,然后将其交给第三个函数:

def page_generator() -> Iterator[Dict[str, Any]]:
    try:
        json_path = '../linkList.json'
        doc = open(json_path)
        body = json.loads(doc.read())
        doc.close()
    except FileNotFoundError:
        print(f'Did not find a file at {json_path}')
        exit(1)
    for page in body['pages']:
        yield page

第三个功能是测试的香饽饽,运行遍历页面,寻找每一个link。我的目标是参数化每个页面,我的函数头目前看起来像...

@pytest.mark.parametrize('spin_up, page', [(setup, p) for p in page_generator()])
def test_links(spin_up, page):
    driver, site = spin_up
    # Do all the things

不幸的是,运行 这导致 TypeError: cannot unpack non-iterable function object。是将 yield d, site 放入某种循环以将函数变成可迭代的唯一选择,还是有办法告诉 test_links 迭代地拉取与其 spin_up 相同的设置函数值?

有一种简单的方法可以做你想做的事,那就是直接将 setup 夹具指定为 test_links 的参数。请注意,pytest 足够聪明,可以弄清楚 setup 参数指的是夹具,而 page 参数指的是参数化:

@pytest.mark.parametrize('page', page_generator())
def test_links(setup, page):
    driver, site = setup

您也可以看看 parametrize_from_file。这是我编写的一个包,用于帮助从 JSON/YAML/TOML 文件加载测试用例。它基本上与您的 page_generator() 函数做同样的事情,但更简洁(更一般)。