Ответ
Для интеграционного тестирования API в Django, особенно с использованием Django REST Framework, основным инструментом является APITestCase из rest_framework.test.
Он наследуется от django.test.TestCase, но предоставляет APIClient, который упрощает отправку HTTP-запросов (GET, POST и др.) и работу с JSON.
Основной процесс тестирования:
- Создание тестового клиента:
APITestCaseавтоматически предоставляетself.client. - Отправка запроса: Используйте методы клиента (
self.client.post(),self.client.get()) для обращения к эндпоинту по его URL, который удобно получать черезreverse(). - Проверка ответа (Assertions): Проверяется HTTP-статус ответа (например,
status.HTTP_201_CREATED) и содержимое тела ответа (response.data).
Пример теста для эндпоинта создания пользователя:
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status
from django.contrib.auth.models import User
class UserAPITests(APITestCase):
def test_create_user(self):
"""Убедимся, что мы можем создать нового пользователя."""
url = reverse('user-list') # Предполагается, что URL-имя 'user-list'
data = {'username': 'testuser', 'password': 'password123'}
response = self.client.post(url, data, format='json')
# 1. Проверяем успешный статус-код
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
# 2. Проверяем, что пользователь действительно создан в БД
self.assertEqual(User.objects.count(), 1)
# 3. Проверяем данные в ответе
self.assertEqual(User.objects.get().username, 'testuser')
Best practices:
- Изоляция тестов: Каждый тест выполняется в изолированной транзакции, которая откатывается после его завершения.
APITestCaseделает это по умолчанию. - Подготовка данных: Используйте
setUpилиsetUpTestDataдля создания необходимых объектов в базе данных перед тестом. - Проверка состояния: Убедитесь, что после выполнения запроса состояние системы (например, количество объектов в БД) изменилось ожидаемым образом.
Ответ 18+ 🔞
А, ну вот, смотри, смотри, блядь! Опять эти ваши тесты, API, Django... Ну ладно, разберёмся, как не остаться с носом, а точнее — с неработающим бэкендом.
Так вот, слушай сюда, сука. Есть у них в этом вашем Django REST Framework такая штука — APITestCase. Это типа как обычный TestCase, но с прикрученным ебучком для API. Он тебе сразу клиента подсовывает, self.client, который умеет в JSON и всякие POST-запросы слать, не как какой-нибудь тупорылый браузер.
Как это, блядь, работает, внатуре:
- Клиента достал. Он уже есть,
self.client. Не надо его искать, он тут как тут, готовый впендюрить запрос куда надо. - Запрос отправил. Берёшь этого клиента и говоришь: «Пошёл нахуй, сделай POST вот на этот URL (который через
reverse()получишь, чтобы не как обезьяна строки вбивать) с вот такими данными». - Ответ проверил. А вот тут, сука, самое интересное. Получил ответ и начинаешь его ёбать проверками. Статус-код правильный?
201 Created, а не500 I'm a teapot? Данные в ответе те, что ожидал? И, что самое главное, блядь, в базе-то данных что-то изменилось? Создался ли пользователь, или это всё было как сон?
Вот, смотри, пример, чтобы не быть пиздаболом:
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status
from django.contrib.auth.models import User
class UserAPITests(APITestCase):
def test_create_user(self):
"""Тест на то, что мы можем создать нового юзера, а не просто так пиздеть."""
# 1. Говорим, куда стучаться
url = reverse('user-list') # Имя урла, а не адресная строка, ёпта!
# 2. Готовим данные, которые будем впихивать
data = {'username': 'testuser', 'password': 'password123'}
# 3. БАЦ! Отправляем запрос через нашего подставного клиента
response = self.client.post(url, data, format='json')
# 4. А теперь начинается проверка, блядь!
# Во-первых, статус. Должен быть 201, а не 404 или 500.
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
# Во-вторых, в базе данных должен появиться один пользователь. Раньше их было ноль.
self.assertEqual(User.objects.count(), 1)
# В-третьих, и этот пользователь должен быть именно тем, кого мы создали.
self.assertEqual(User.objects.get().username, 'testuser')
А теперь, блядь, главные правила, чтобы не облажаться:
- Тесты не должны друг другу мешать.
APITestCase— молодец, он каждый тест запускает в своей песочнице (транзакции), а потом всё откатывает. Как будто ничего и не было. Никаких грязных следов. - Готовь данные заранее. Не надо в каждом тесте создавать одни и те же объекты. Используй
setUpилиsetUpTestData. Это как подготовить инструменты перед ремонтом, а не бегать за каждой отвёрткой в магазин. - Проверяй не только ответ, но и последствия. Мало получить красивый JSON. Надо убедиться, что в системе что-то произошло. Объект создался? Удалился? Обновился? Вот это и есть суть, а не просто «запрос прошёл».
Вот и вся магия, ёпта. Ничего сложного, главное — не тупить и проверять всё, а не надеяться на авось.