304 lines
13 KiB
Python
304 lines
13 KiB
Python
"""
|
||
Тесты производительности для 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}"
|
||
|