通过self而不是方法参数的类的Pytest fixture

Don*_*Mee 7 python unit-testing pytest

通常我会编写一个在每种方法中都使用pytest fixture的测试类.这是一个例子.我希望能够避免在每个方法的签名中编写夹具名称.这不是干的.如何才能做到这一点?

我希望能够通过将fixture作为测试类的属性来访问fixture.在这个例子中,我想将google fixture视为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"
Run Code Online (Sandbox Code Playgroud)

hoe*_*ing 13

当然,只需使用autouse夹具.这是pytestdocs中的相关位置.在您的示例中,更改将引入一个额外的fixture(我将其命名_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"
Run Code Online (Sandbox Code Playgroud)

您甚至可以完全放下google夹具并将代码移动到_request_google_page:

@pytest.fixture(autouse=True)
def _request_google_page(self):
    self._response = requests.get("https://www.google.com")
Run Code Online (Sandbox Code Playgroud)

请注意,_request_google_page默认情况下,每个测试将调用一次,因此每个测试都会得到一个新的响应.如果你想应对初始化一次和再利用遍布在所有测试TestGoogle类,调整固定范围(scope='class'用于_request_google_page和scope='module'或scope='session'对google).

  • @PrashantPathak这是测试收集和准备的一部分。当在测试集合上评估 `_request_google_page` 夹具时,`request.cls` 将是 `TestGoogle`,因此在收集 `TestGoogle` 后,`TestGoogle._response` 将被初始化;之后,执行 `TestGoogle().test_alive()` 并且 `self._response` 可用。实际上,它是一个类变量。 (2认同)

mak*_*asy 11

我不得不解决一个类似的问题,并且接受的解决方案对我来说不适用于类范围的装置。

我想为每个测试类调用一次夹具,并使用以下方法重新使用测试方法中的值 self. 这实际上也是 OP 打算做的。

您可以使用request夹具访问使用它的类 ( request.cls) 并在类属性中分配夹具值。然后您可以从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"
Run Code Online (Sandbox Code Playgroud)

希望能帮助其他人来回答这个问题。

  • @JorritSmit 在一个测试中设置一个值用于其他测试听起来很奇怪。测试不应为其他测试生成值。 (2认同)