【问题标题】:How to use pytest with Django?如何在 Django 中使用 pytest?
【发布时间】:2021-02-24 20:46:46
【问题描述】:

当我在 Django 中使用 pytest 时,没有创建 test_

最小可重现示例:

在 Django 项目中:

./manage.py startapp testing_pytest

在models.py中

class Snippet(models.Model):

    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    external_id = models.CharField(max_length=100, default='0')

    class Meta:
        ordering = ['created']

然后在 Postgres 中创建一个名为 loc_db 的数据库,

./manage.py makemigrations
./manage.py migrate 

在 serializers.py 中

class BulkUpdateOrCreateListSerializer(serializers.ListSerializer):
    def create(self, validated_data):
        result = [self.child.create(attrs) for attrs in validated_data]
        try:
            res = self.child.Meta.model.objects.bulk_create(result)
        except IntegrityError as e:
            raise ValidationError(e)
        return res

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ['id','title', 'code', 'linenos']
        read_only_fields = ['id']
        list_serializer_class = BulkUpdateOrCreateListSerializer

    def create(self, validated_data):
        instance = Snippet(**validated_data)
        if isinstance(self._kwargs["data"], dict):
            instance.save()
        return instance

在views.py中

class SnippetGetView(generics.ListAPIView):
    serializer_class = SnippetSerializer
    queryset = Snippet.objects.all()

class SnippetUpdateView(generics.ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    def get_serializer(self, *args, **kwargs):
        if isinstance(kwargs.get("data", {}), list):
            kwargs["many"] = True
        return super(SnippetUpdateView, self).get_serializer(*args, **kwargs)

在tests.py中

@pytest.fixture(scope='session',autouse=True)
def my_faker():
    return Faker()

@pytest.fixture(scope='session',autouse=True)
def factory():
    return APIRequestFactory()

@pytest.fixture(scope='session',autouse=True)
def snippets():
    snippets = []
    for i in range(TEST_SIZE):
        snippets.append({'title':'snippet'+str(i),'code':'print(True)','linenos':False,'external_id':'1'})
    return snippets

@pytest.mark.django_db
def test_update_snippet(factory,snippets):
    request = factory.post('/add-snippets/',snippets)
    view = SnippetUpdateView.as_view()
    response = view(request)
    response.render()
    assert status.is_success(response.status_code)

/settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'loc_db',
        'USER': '<some name>',
        'PASSWORD': '<some pass>',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

在 pytest.ini 中

[pytest]
DJANGO_SETTINGS_MODULE = <project_dir>.settings
python_files = tests.py test_*.py *_tests.py

我希望在执行这些测试时运行 pytest 会创建 test_loc_db,然后保存该 sn-ps 数组以进行批量创建。但是没有创建 test_db。相反,它只是通过了该测试。但我不确定为什么。那些 sn-ps 保存在哪里?

【问题讨论】:

    标签: python django pytest


    【解决方案1】:

    我认为pytest 没有这样的功能,将数据库事务输出到文件。我还检查了文档,似乎不存在该功能。

    它通常(和你的行为一样)只是输出测试是否通过。最后一行看起来像这样

    ============================== <N Tests> passed in 0.27s ==============================
    

    测试控制台上还会报告失败的测试。以下是最接近任何类型的数据库保存的提及

    这些数据将可用于标有 pytest.mark.django_db() 标记的测试,或使用 db 固定装置的测试。测试数据将保存在数据库中,不会被重置。

    您可以从here 看到这一点。您也可以查看 Django's test framework 以查看它是否支持。

    【讨论】:

    • 我不明白。问题是 pytest 是否像 Django 测试框架那样创建该 test_ 数据库并将记录保存到其中。这是您所说的pytest缺乏的功能吗?这是否确认数据库测试只能使用 Django 的测试模块而不是 pytest?
    • @BigBoy1337 是的,没错。我不认为 pytest 支持它。
    猜你喜欢
    • 2021-02-08
    • 1970-01-01
    • 2018-12-23
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多