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

时间:2018-05-02 10:42:25

标签: 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"

2 个答案:

答案 0 :(得分:9)

当然,只需使用autouse灯具。 Here is the relevant spot in pytest docs。在您的示例中,更改将引入一个额外的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"

您甚至可以完全放弃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类的所有测试中重复使用,请调整夹具范围(scope='class'_request_google_pagescope='module' scope='session' } google)。

答案 1 :(得分:2)

我不得不解决一个类似的问题,而对于类范围的夹具,接受的解决方案对我不起作用。

我想每个测试类调用一个夹具,然后使用self在测试方法中重用该值。实际上,这也是OP打算做的。

您可以使用request灯具来访问使用它的类(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"

希望可以帮助其他人解决这个问题。