[Fixed]-How to use pytest fixtures with django TestCase


I find it easier to use the "usefixtures" approach. It doesn’t show a magical 2nd argument to the function and it explicitly marks the class for having fixtures.

class CategoryTest(TestCase):
    def test1(self):
        assert Category.objects.count() == 1


I opted to rewrite django’s fixture logic using a "pytest fixture" that is applied at the session scope. All you need is a single fixture in a conftest.py file at the root of your test directory:

import pytest

from django.core.management import call_command

def django_db_setup(django_db_setup, django_db_blocker):
    fixtures = [

    with django_db_blocker.unblock():
        call_command('loaddata', *fixtures)

This allowed me to throw out the class-based tests altogether, and just use function-based tests.



Why do you need TestCase? I usually use Python class and create tests there.


import pytest
from django.urls import reverse
from rest_framework import status

from store.models import Book
from store.serializers import BooksSerializer

def test_data():
    """Поднимает временные данные."""
    Book.objects.create(name='Book1', price=4000)

def api_client():
    """Возвращает APIClient для создания запросов."""
    from rest_framework.test import APIClient
    return APIClient()

class TestBooks:
    def test_get_books_list(self, api_client):
        """GET запрос к списку книг."""
        url = reverse('book-list')
        excepted_data = BooksSerializer(Book.objects.all(), many=True).data
        response = api_client.get(url)
        assert response.status_code == status.HTTP_200_OK
        assert response.data == excepted_data
        assert response.data[0]['name'] == Book.objects.first().name

Leave a comment