uchill/backend/apps/homework/tests/test_performance.py

304 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Тесты производительности для API домашних заданий.
Измеряют время ответа и количество SQL запросов.
"""
import time
import pytest
from django.test.utils import override_settings
from django.db import connection, reset_queries
from django.contrib.auth import get_user_model
User = get_user_model()
@pytest.mark.django_db
@pytest.mark.performance
class TestHomeworkPerformance:
"""Тесты производительности API домашних заданий."""
@pytest.fixture
def setup_data(self, mentor_user, client_user):
"""Создает тестовые данные для проверки производительности."""
from apps.schedule.models import Lesson
from apps.homework.models import Homework, HomeworkSubmission
# Создаем несколько студентов
students = []
for i in range(10):
student = User.objects.create_user(
email=f'student{i}@test.com',
password='TestPass123!',
first_name=f'Студент{i}',
last_name=f'Тестовый{i}',
role='client',
is_email_verified=True,
is_active=True
)
students.append(student)
# Создаем занятие
lesson = Lesson.objects.create(
mentor=mentor_user,
title='Тестовое занятие',
status='scheduled'
)
# Создаем домашние задания
homeworks = []
for i in range(5):
homework = Homework.objects.create(
title=f'ДЗ {i+1}',
description=f'Описание ДЗ {i+1}',
mentor=mentor_user,
lesson=lesson,
status='published',
max_score=100
)
# Назначаем студентов
homework.assigned_to.set(students)
# Создаем решения для некоторых студентов
for j, student in enumerate(students[:5]): # 5 студентов сдали
HomeworkSubmission.objects.create(
homework=homework,
student=student,
content=f'Решение от студента {j}',
status='graded' if j % 2 == 0 else 'pending',
score=80 + j if j % 2 == 0 else None
)
homeworks.append(homework)
return {
'mentor_user': mentor_user,
'students': students,
'homeworks': homeworks
}
def test_homework_list_performance_mentor(self, authenticated_client):
"""Тест производительности списка ДЗ для ментора."""
reset_queries()
start_time = time.time()
response = authenticated_client.get('/api/homework/homeworks/')
end_time = time.time()
elapsed_time = end_time - start_time
query_count = len(connection.queries)
assert response.status_code == 200
assert elapsed_time < 0.5, f"Время ответа слишком долгое: {elapsed_time:.3f}с"
assert query_count < 20, f"Слишком много SQL запросов: {query_count}"
print(f"\n📊 Список ДЗ (ментор):")
print(f" Время: {elapsed_time:.3f}с")
print(f" SQL запросов: {query_count}")
print(f" ДЗ в ответе: {len(response.json().get('results', response.json()))}")
def test_homework_list_performance_student(self, authenticated_client_user):
"""Тест производительности списка ДЗ для студента."""
reset_queries()
start_time = time.time()
response = authenticated_client_user.get('/api/homework/homeworks/')
end_time = time.time()
elapsed_time = end_time - start_time
query_count = len(connection.queries)
assert response.status_code == 200
assert elapsed_time < 0.3, f"Время ответа слишком долгое: {elapsed_time:.3f}с"
assert query_count < 15, f"Слишком много SQL запросов: {query_count}"
print(f"\n📊 Список ДЗ (студент):")
print(f" Время: {elapsed_time:.3f}с")
print(f" SQL запросов: {query_count}")
def test_homework_statistics_performance(self, authenticated_client, setup_data):
"""Тест производительности статистики ДЗ."""
homework = setup_data['homeworks'][0]
reset_queries()
start_time = time.time()
response = authenticated_client.get(f'/api/homework/homeworks/{homework.id}/statistics/')
end_time = time.time()
elapsed_time = end_time - start_time
query_count = len(connection.queries)
assert response.status_code == 200
assert elapsed_time < 0.2, f"Время ответа слишком долгое: {elapsed_time:.3f}с"
assert query_count < 5, f"Слишком много SQL запросов: {query_count}"
print(f"\n📊 Статистика ДЗ:")
print(f" Время: {elapsed_time:.3f}с")
print(f" SQL запросов: {query_count}")
print(f" Данные: {response.json()}")
def test_homework_submissions_list_performance(self, authenticated_client, setup_data):
"""Тест производительности списка решений ДЗ."""
homework = setup_data['homeworks'][0]
reset_queries()
start_time = time.time()
response = authenticated_client.get(
f'/api/homework/submissions/?homework_id={homework.id}'
)
end_time = time.time()
elapsed_time = end_time - start_time
query_count = len(connection.queries)
assert response.status_code == 200
assert elapsed_time < 0.3, f"Время ответа слишком долгое: {elapsed_time:.3f}с"
assert query_count < 10, f"Слишком много SQL запросов: {query_count}"
print(f"\n📊 Список решений ДЗ:")
print(f" Время: {elapsed_time:.3f}с")
print(f" SQL запросов: {query_count}")
print(f" Решений в ответе: {len(response.json().get('results', response.json()))}")
@pytest.mark.django_db
@pytest.mark.performance
class TestChatPerformance:
"""Тесты производительности API чата."""
@pytest.fixture
def setup_chat_data(self, mentor_user, client_user):
"""Создает тестовые данные для чата."""
from apps.chat.models import Chat, ChatParticipant, Message, MessageRead
# Создаем несколько пользователей
users = [mentor_user, client_user]
for i in range(5):
user = User.objects.create_user(
email=f'user{i}@test.com',
password='TestPass123!',
first_name=f'Пользователь{i}',
last_name=f'Тестовый{i}',
role='client',
is_email_verified=True,
is_active=True
)
users.append(user)
# Создаем чаты с участниками и сообщениями
chats = []
for i in range(3):
chat = Chat.objects.create(
chat_type='group',
name=f'Чат {i+1}',
created_by=mentor_user
)
# Добавляем участников
for user in users[:3]:
ChatParticipant.objects.create(
chat=chat,
user=user,
role='member'
)
# Создаем сообщения
for j in range(10):
message = Message.objects.create(
chat=chat,
sender=users[j % len(users)],
content=f'Сообщение {j+1} в чате {i+1}'
)
# Помечаем некоторые сообщения как прочитанные
if j % 2 == 0:
MessageRead.objects.create(
message=message,
user=mentor_user
)
chats.append(chat)
return {
'mentor_user': mentor_user,
'chats': chats
}
def test_chat_list_performance(self, authenticated_client):
"""Тест производительности списка чатов."""
reset_queries()
start_time = time.time()
response = authenticated_client.get('/api/chat/chats/')
end_time = time.time()
elapsed_time = end_time - start_time
query_count = len(connection.queries)
assert response.status_code == 200
assert elapsed_time < 0.4, f"Время ответа слишком долгое: {elapsed_time:.3f}с"
assert query_count < 15, f"Слишком много SQL запросов: {query_count}"
print(f"\n📊 Список чатов:")
print(f" Время: {elapsed_time:.3f}с")
print(f" SQL запросов: {query_count}")
print(f" Чатов в ответе: {len(response.json().get('results', response.json()))}")
def test_chat_messages_performance(self, authenticated_client, setup_chat_data):
"""Тест производительности сообщений чата."""
chat = setup_chat_data['chats'][0]
reset_queries()
start_time = time.time()
response = authenticated_client.get(f'/api/chat/chats/{chat.uuid}/messages/')
end_time = time.time()
elapsed_time = end_time - start_time
query_count = len(connection.queries)
assert response.status_code == 200
assert elapsed_time < 0.3, f"Время ответа слишком долгое: {elapsed_time:.3f}с"
assert query_count < 10, f"Слишком много SQL запросов: {query_count}"
print(f"\n📊 Сообщения чата:")
print(f" Время: {elapsed_time:.3f}с")
print(f" SQL запросов: {query_count}")
messages_data = response.json().get('results', response.json())
print(f" Сообщений в ответе: {len(messages_data)}")
@pytest.mark.django_db
@pytest.mark.performance
class TestGeneralPerformance:
"""Общие тесты производительности."""
def test_multiple_requests_performance(self, authenticated_client):
"""Тест производительности при множественных запросах."""
times = []
query_counts = []
for i in range(5):
reset_queries()
start_time = time.time()
response = authenticated_client.get('/api/homework/homeworks/')
end_time = time.time()
times.append(end_time - start_time)
query_counts.append(len(connection.queries))
assert response.status_code == 200
avg_time = sum(times) / len(times)
avg_queries = sum(query_counts) / len(query_counts)
max_time = max(times)
max_queries = max(query_counts)
print(f"\n📊 Множественные запросы (5 раз):")
print(f" Среднее время: {avg_time:.3f}с")
print(f" Максимальное время: {max_time:.3f}с")
print(f" Среднее SQL запросов: {avg_queries:.1f}")
print(f" Максимум SQL запросов: {max_queries}")
assert avg_time < 0.5, f"Среднее время слишком долгое: {avg_time:.3f}с"
assert avg_queries < 20, f"Среднее количество запросов слишком большое: {avg_queries:.1f}"