class 的 Pytest fixture 通过 self 而不是方法参数
Pytest fixture for a class through self not as method argument
我通常会编写一个测试 class,在每个方法中使用 pytest fixture。这是一个例子。我希望能够避免必须在每个方法的签名中写下夹具名称。这不是干的。如何才能做到这一点?
我希望能够通过将夹具作为测试的属性来访问夹具 class。在此示例中,我希望将 google 夹具视为 TestGoogle 的一个属性。这可能吗?
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture()
def google():
return requests.get("https://www.google.com")
class TestGoogle:
def test_alive(self, google):
assert google.status_code == 200
def test_html_title(self, google):
soup = BeautifulSoup(google.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
当然可以,只需使用自动夹具即可。 Here is the relevant spot in pytest
docs。在您的示例中,更改将引入一个额外的固定装置(我将其命名为 _request_google_page
):
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture()
def google():
return requests.get("https://www.google.com")
class TestGoogle:
@pytest.fixture(autouse=True)
def _request_google_page(self, google):
self._response = google
def test_alive(self):
assert self._response.status_code == 200
def test_html_title(self):
soup = BeautifulSoup(self._response.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
您甚至可以完全删除 google
夹具并将代码移动到 _request_google_page
:
@pytest.fixture(autouse=True)
def _request_google_page(self):
self._response = requests.get("https://www.google.com")
请注意 _request_google_page
默认情况下每个测试都会调用一次,因此每个测试都会得到一个新的响应。如果您希望响应初始化一次并在 TestGoogle
class 中的所有测试中重复使用,请调整夹具范围(scope='class'
用于 _request_google_page
和 scope='module'
或scope='session'
对于 google
)。示例:
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture(scope='module')
def google():
return requests.get("https://www.google.com")
@pytest.fixture(autouse=True, scope='class')
def _request_google_page(request, google):
request.cls._response = google
class TestGoogle:
def test_alive(self):
assert self._response.status_code == 200
def test_html_title(self):
soup = BeautifulSoup(self._response.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
我不得不解决一个类似的问题,但公认的解决方案对 class-scoped fixture 不起作用。
我想在每个测试中调用一次夹具 class 并在使用 self
的测试方法中重新使用该值。这实际上也是 OP 打算做的。
您可以使用 request
夹具访问正在使用它的 class (request.cls
) 并在 class 属性中分配夹具值。然后您可以从 self
访问此属性。这是完整的片段:
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture(scope="class")
def google(request):
request.cls.google = requests.get("https://www.google.com")
@pytest.mark.usefixtures("google")
class TestGoogle:
def test_alive(self):
assert self.google.status_code == 200
def test_html_title(self):
soup = BeautifulSoup(self.google.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
希望能帮助其他人解决这个问题。
import pytest
from sqlalchemy import create_engine
@pytest.fixture(scope="class")
def test_connection():
engine = "abc"#create_engine()
return engine
@pytest.fixture(scope="class")
def test_patient_id():
engine = "123"#create_engine()
return engine
@pytest.mark.usefixtures("test_connection","test_patient_id")
class TestRuleEngine:
def test_table_setup(self, test_connection, test_patient_id):
assert 1
assert test_connection=="abc"
assert test_patient_id=="123"
def test_data_insert(self):
assert 1
def test_data_delete(self):
assert 1
def test_table_delete(self):
assert 1
我通常会编写一个测试 class,在每个方法中使用 pytest fixture。这是一个例子。我希望能够避免必须在每个方法的签名中写下夹具名称。这不是干的。如何才能做到这一点?
我希望能够通过将夹具作为测试的属性来访问夹具 class。在此示例中,我希望将 google 夹具视为 TestGoogle 的一个属性。这可能吗?
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture()
def google():
return requests.get("https://www.google.com")
class TestGoogle:
def test_alive(self, google):
assert google.status_code == 200
def test_html_title(self, google):
soup = BeautifulSoup(google.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
当然可以,只需使用自动夹具即可。 Here is the relevant spot in pytest
docs。在您的示例中,更改将引入一个额外的固定装置(我将其命名为 _request_google_page
):
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture()
def google():
return requests.get("https://www.google.com")
class TestGoogle:
@pytest.fixture(autouse=True)
def _request_google_page(self, google):
self._response = google
def test_alive(self):
assert self._response.status_code == 200
def test_html_title(self):
soup = BeautifulSoup(self._response.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
您甚至可以完全删除 google
夹具并将代码移动到 _request_google_page
:
@pytest.fixture(autouse=True)
def _request_google_page(self):
self._response = requests.get("https://www.google.com")
请注意 _request_google_page
默认情况下每个测试都会调用一次,因此每个测试都会得到一个新的响应。如果您希望响应初始化一次并在 TestGoogle
class 中的所有测试中重复使用,请调整夹具范围(scope='class'
用于 _request_google_page
和 scope='module'
或scope='session'
对于 google
)。示例:
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture(scope='module')
def google():
return requests.get("https://www.google.com")
@pytest.fixture(autouse=True, scope='class')
def _request_google_page(request, google):
request.cls._response = google
class TestGoogle:
def test_alive(self):
assert self._response.status_code == 200
def test_html_title(self):
soup = BeautifulSoup(self._response.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
我不得不解决一个类似的问题,但公认的解决方案对 class-scoped fixture 不起作用。
我想在每个测试中调用一次夹具 class 并在使用 self
的测试方法中重新使用该值。这实际上也是 OP 打算做的。
您可以使用 request
夹具访问正在使用它的 class (request.cls
) 并在 class 属性中分配夹具值。然后您可以从 self
访问此属性。这是完整的片段:
from bs4 import BeautifulSoup
import pytest
import requests
@pytest.fixture(scope="class")
def google(request):
request.cls.google = requests.get("https://www.google.com")
@pytest.mark.usefixtures("google")
class TestGoogle:
def test_alive(self):
assert self.google.status_code == 200
def test_html_title(self):
soup = BeautifulSoup(self.google.content, "html.parser")
assert soup.title.text.upper() == "GOOGLE"
希望能帮助其他人解决这个问题。
import pytest
from sqlalchemy import create_engine
@pytest.fixture(scope="class")
def test_connection():
engine = "abc"#create_engine()
return engine
@pytest.fixture(scope="class")
def test_patient_id():
engine = "123"#create_engine()
return engine
@pytest.mark.usefixtures("test_connection","test_patient_id")
class TestRuleEngine:
def test_table_setup(self, test_connection, test_patient_id):
assert 1
assert test_connection=="abc"
assert test_patient_id=="123"
def test_data_insert(self):
assert 1
def test_data_delete(self):
assert 1
def test_table_delete(self):
assert 1