如何从范围=会话的pytest夹具返回多个值

Posted

技术标签:

【中文标题】如何从范围=会话的pytest夹具返回多个值【英文标题】:How to return multiple value from a pytest fixture with scope = session 【发布时间】:2022-01-21 22:48:47 【问题描述】:

我在 conftest.py 中创建了 pytest 夹具,用于创建用户和自动登录

@pytest.fixture(scope="session")
def api_client():
   from rest_framework.test import APIClient
   return APIClient()

@pytest.fixture(scope="session")
@pytest.mark.django_db
def create_user():
    def make_user(**kwargs):
        # employee = e_ge_employee.objects.create()
        kwargs['password'] = 'strong-test-pass'
        if 'username' not in kwargs:
            kwargs['username'] = 'test-user'
        # if 'employee' not in kwargs:
        #     kwargs['employee'] = employee
        return e_ge_user.objects.create_user(**kwargs)
    return make_user

@pytest.fixture(scope="session")
@pytest.mark.django_db
def auto_login_user(api_client, create_user):
    def make_auto_login():
        print("_+==--=-=-=-===--=-=-==----=-=-=-=")
        user = create_user()
        api_client.login(username=user.username, password='strong-test-pass')
        return api_client, user
    return make_auto_login

现在如何使用 API 客户端调用 get、post 方法以及如何在 test_views.p 中编写的多个测试用例中访问用户

@pytest.mark.django_db
class TestViews:

    def test_generate_token_views_post(self,auto_login_user):
        **"To be Answered"**
        assert True == True

    def test_generate_token_views_post2(self,auto_login_user):
        **"To be Answered"**
        assert True == True

【问题讨论】:

【参考方案1】:

您可以在fixture 中调用make_auto_login(),这将执行函数并返回api_clientuser。之后在测试中auto_login_user 将是一个包含值的元组

conftest.py:

@pytest.fixture(scope="session")
@pytest.mark.django_db
def auto_login_user(api_client, create_user):
    def make_auto_login():
        print("_+==--=-=-=-===--=-=-==----=-=-=-=")
        user = create_user()
        api_client.login(username=user.username, password='strong-test-pass')
        return api_client, user
    return make_auto_login()

test_views.py

class TestViews:

    def test_generate_token_views_post(self, auto_login_user):
        api_client, user = auto_login_user
        assert True

    def test_generate_token_views_post2(self, auto_login_user):
        api_client, user = auto_login_user
        assert True

【讨论】:

这个解决方案正在运行,但这个解决方案的问题是每次它调用 auto_login_user 固定装置并且每次都在创建新用户,你能提出一些建议吗? @KritikAlawat 这不会发生在我身上,我无法复制。在当前结构中auto_login_user 应该运行一次。 根据您的解决方案,如果我使用此 api_client, user = auto_login_user 我收到错误 TypeError: 'function' object is not iterable。如果我使用 api_client, user = auto_login_user() 这个 auto_login_user 将永远运行。你能看看这个吗? @KritikAlawat 你可能没有改变auto_login_user 返回return make_auto_login() 对不起,我错过了,但在将其更改为 make_auto_login() 后,它给了我一个 RuntimeError 错误:不允许数据库访问,使用“django_db”标记,或“db”或“transactional_db”固定装置来启用它。我没有改变其他任何东西。你能解释一下为什么会这样吗?

以上是关于如何从范围=会话的pytest夹具返回多个值的主要内容,如果未能解决你的问题,请参考以下文章

Pytest 在一个函数中使用相同的夹具两次

如何参数化 Pytest 夹具

如何在pytest中将几个参数化的夹具连接成一个新的夹具?

如何使用外部夹具跳过 pytest?

谷歌分析会话范围的字段返回多个值

如何绕过 pytest 夹具装饰器?