创建多个类似的PyTest固定装置



我有一系列pytest固定装置,它们在性质上非常相似。fixture被传递给测试,以验证某些CSS选择器是否正常工作。每个夹具中的代码几乎相同;唯一的区别是为每个fixture向CCD_ 2函数传递不同的URL。

每个固定装置看起来都是这样的:

import pytest

@pytest.fixture(scope="module")
def goto_pagename():
with sync_playwright() as play:
browser = play.chromium.launch()
page = browser.new_page()
page.goto(TestScrapeWebsite.address)
yield page
browser.close()

我尝试使用一个装饰器,它覆盖了除page.goto()yield page之外的所有代码,如下所示:

from playwright.sync_api import sync_playwright

def get_page(func):
def wrapper(*args, **kwargs):
with sync_playwright() as play:
browser = play.chromium.launch(*args, **kwargs)
page = browser.new_page()
func(page)
browser.close()
return wrapper

然后,固定装置和测试看起来像这样:

import pytest

@pytest.fixture(scope="module")
@get_page
def google_page(page):
page.goto(TestScrapeGoogle.address)
yield page

@pytest.fixture(scope="module")
@get_page
def stackoverflow_page(page):
page.goto(TestScrapeStackOverflow.address)
yield page

@pytest.fixture(scope="module")
@get_page
def github_page(page):
page.goto(TestScrapeGitHub.address)
yield page

class TestScrapeGoogle:
address = "https://google.com/"
def test_selectors(self, google_page):
assert google_page.url == self.address

class TestScrapeStackOverflow:
address = "https://stackoverflow.com/"
def test_selectors(self, stackoverflow_page):
assert stackoverflow_page.url == self.address

class TestScrapeGitHub:
address = "https://github.com/"
def test_selectors(self, github_page):
assert github_page.url == self.address

然而,在运行pytest测试运行程序时,出现了与固定装置有关的异常:

$ pytest test_script.py
...
============================================================================================ short test summary info ============================================================================================= 
FAILED test_script.py::TestScrapeGoogle::test_selectors - AttributeError: 'NoneType' object has no attribute 'url'
FAILED test_script.py::TestScrapeStackOverflow::test_selectors - AttributeError: 'NoneType' object has no attribute 'url'
FAILED test_script.py::TestScrapeGitHub::test_selectors - AttributeError: 'NoneType' object has no attribute 'url'                                                                                                 

有没有办法修改我所采取的方法来简化每个固定装置?或者,我所要求的是pytest的功能,我是否只需要完整地写出每个固定装置?


类似问题

下面我添加了一些Stack Overflow问题,这些问题在搜索问题标题时会出现。我还列出了为什么这个问题的答案不是我问题的理想解决方案的原因。

  • pytest fixture的多个副本:pytestfixture的所有副本都用于相同的测试。在我的情况下,我希望每个测试都有一个单独的固定装置
  • 使用两个不同的pytest夹具运行测试:虽然多个夹具,但每个测试(可能(只有一个夹具装饰测试

编辑:我自己无法运行此代码,因为我的chromeium设置此时似乎已崩溃我会选择使用pytest的参数化功能来实现您的期望。首先,我会创建我的固定装置

@pytest.fixture(scope='module')
def browser():
with sync_playwright() as play:
browser = play.chromium.launch(*args, **kwargs)
try:
yield browser
finally:
# Ensure the browser is gracefully closed at end of test
browser.close() 

@pytest.fixture
def page(browser, url):
# Provide the page
page = browser.new_page()
page.goto(url)
return page

请注意,url夹具尚未定义。

接下来,我创建一个带有url(和预期url(参数化的测试

@pytest.mark.parametrize('url, expected_url', [
('https://google.com/', 'https://google.com/'),
('https://stackoverflow.com/', 'https://stackoverflow.com/'),
('https://github.com/', 'https://github.com/'),
])
def test_selectors(page, expected_url):
assert page.url == expected_url

或者,如果网站的测试略有不同,可以有三个单独的测试,每个测试都有一个参数化的条目。

@pytest.mark.parametrize('url, expected_url', [
('https://google.com/', 'https://google.com/'),
])
def test_google_selector(page, expected_url):
assert page.url == expected_url

@pytest.mark.parametrize('url, expected_url', [
('https://stackoverflow.com/', 'https://stackoverflow.com/'),
])
def test_stackoverflow_selector(page, expected_url):
assert page.url == expected_url

最新更新