如何在 django TestCase 中使用 pytest 固定装置

Rei*_*ica 7 python django pytest django-tests pytest-django

如何在TestCase方法中使用 pytest 固定装置?类似问题的几个答案似乎暗示我的例子应该有效:

import pytest

from django.test import TestCase
from myapp.models import Category
  
pytestmark = pytest.mark.django_db

@pytest.fixture
def category():
    return Category.objects.create()
  
class MyappTests(TestCase):
    def test1(self, category):
        assert isinstance(category, Category)
Run Code Online (Sandbox Code Playgroud)

但这总是会导致错误:

TypeError: test1() missing 1 required positional argument: 'category'
Run Code Online (Sandbox Code Playgroud)

我意识到我可以将这个简单的例子转换成一个函数,它会起作用。我更喜欢使用 django,TestCase因为它支持导入传统的“django fixture”文件,这是我的几个测试所需要的。将我的测试转换为函数需要重新实现这个逻辑,因为没有记录的方式使用 pytest(或 pytest-django)导入“django 固定装置”

包版本

Django==3.1.2
pytest==6.1.1
pytest-django==4.1.0
Run Code Online (Sandbox Code Playgroud)

小智 8

我发现使用“usefixtures”方法更容易。它没有显示该函数神奇的第二个参数,并且它明确标记该类具有固定装置。

@pytest.mark.usefixtures("category")
class CategoryTest(TestCase):
    def test1(self):
        assert Category.objects.count() == 1
Run Code Online (Sandbox Code Playgroud)


Rei*_*ica 5

我选择使用在范围内应用的“pytest 固定装置”session来重写 django 的固定装置逻辑。您所需要的只是conftest.py测试目录根目录下的文件中的单个固定装置:

import pytest

from django.core.management import call_command

@pytest.fixture(scope='session')
def django_db_setup(django_db_setup, django_db_blocker):
    fixtures = [
        'myapp/channel',
        'myapp/country',
        ...
    ]

    with django_db_blocker.unblock():
        call_command('loaddata', *fixtures)
Run Code Online (Sandbox Code Playgroud)

这使我能够完全抛弃基于类的测试,而只使用基于函数的测试。

文档