Skip to content

Instantly share code, notes, and snippets.

@Miron-Anosov
Created February 2, 2025 10:36
Show Gist options
  • Save Miron-Anosov/ca35b0f34413ff5e1dfb18d4228e54e2 to your computer and use it in GitHub Desktop.
Save Miron-Anosov/ca35b0f34413ff5e1dfb18d4228e54e2 to your computer and use it in GitHub Desktop.

Руководство по тестированию Django приложений

Содержание

Теория тестирования

Тестирование программного обеспечения - это процесс проверки соответствия фактического поведения программы ожидаемому поведению на конечном наборе тестов.

Основные принципы тестирования:

  1. Раннее тестирование
  2. Независимость тестирования
  3. Исчерпывающее тестирование невозможно
  4. Тестирование показывает наличие дефектов
  5. Кластеризация дефектов
  6. Парадокс пестицида
  7. Зависимость от контекста

Виды тестирования

1. Модульное тестирование (Unit Testing)

  • Тестирование отдельных компонентов приложения
  • Проверка конкретных функций и методов
  • Изоляция от внешних зависимостей

2. Интеграционное тестирование

  • Проверка взаимодействия между компонентами
  • Тестирование групп взаимосвязанных модулей
  • Проверка интеграции с базой данных

3. Функциональное тестирование

  • Тестирование полного функционала
  • Проверка бизнес-логики
  • End-to-end тестирование

4. Нагрузочное тестирование

  • Проверка производительности
  • Тестирование при высоких нагрузках
  • Стресс-тестирование

Примитивы тестирования

1. Test Case (Тестовый случай)

def test_user_creation(self):
    """
    Тестовый случай для проверки создания пользователя
    """
    user = User.objects.create_user(
        username='testuser',
        email='[email protected]',
        password='testpass123'
    )
    self.assertEqual(user.username, 'testuser')

2. Test Suite (Набор тестов)

class UserTestSuite(TestCase):
    """
    Набор тестов для пользовательской функциональности
    """
    def setUp(self):
        # Подготовка данных перед каждым тестом
        self.user = User.objects.create_user(
            username='testuser',
            password='12345'
        )

3. Fixtures (Фикстуры)

class ArticleTest(TestCase):
    """
    Использование фикстур для загрузки тестовых данных
    """
    fixtures = ['test_data.json']

Django Testing Framework

1. TestCase - основной класс для тестирования

from django.test import TestCase

class MyTests(TestCase):
    def setUp(self):
        """
        Метод выполняется перед каждым тестом
        """
        self.user = User.objects.create_user(...)

    def tearDown(self):
        """
        Метод выполняется после каждого теста
        """
        self.user.delete()

2. Тестирование Views

from django.test import Client

class ViewTests(TestCase):
    def test_home_page(self):
        """
        Тестирование домашней страницы
        """
        client = Client()
        response = client.get('/')
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'home.html')

3. Тестирование Models

class ModelTests(TestCase):
    def test_article_creation(self):
        """
        Тестирование создания статьи
        """
        article = Article.objects.create(
            title='Test Article',
            content='Test Content'
        )
        self.assertTrue(isinstance(article, Article))
        self.assertEqual(article.title, 'Test Article')

4. Тестирование Forms

class FormTests(TestCase):
    def test_valid_form(self):
        """
        Тестирование валидной формы
        """
        data = {'title': 'Test', 'content': 'Test Content'}
        form = ArticleForm(data=data)
        self.assertTrue(form.is_valid())

5. Тестирование URLs

from django.urls import reverse

class URLTests(TestCase):
    def test_article_detail_url(self):
        """
        Тестирование URL для детальной страницы статьи
        """
        url = reverse('article-detail', args=[1])
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

6. Тестирование API

from rest_framework.test import APITestCase

class APITests(APITestCase):
    def test_api_response(self):
        """
        Тестирование API endpoint
        """
        url = reverse('api-endpoint')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 2)

Лучшие практики

1. Организация тестов

  • Группируйте тесты по функциональности
  • Используйте понятные имена тестов
  • Следуйте принципу "один тест - одна проверка"

2. Изоляция тестов

from unittest.mock import patch

class IsolatedTests(TestCase):
    @patch('module.ExternalService')
    def test_external_service(self, mock_service):
        """
        Изолированный тест с использованием mock
        """
        mock_service.return_value.get_data.return_value = {'key': 'value'}
        # Тестовый код

3. Асинхронное тестирование

from django.test import AsyncTestCase

class AsyncTests(AsyncTestCase):
    async def test_async_view(self):
        """
        Тестирование асинхронного представления
        """
        response = await self.async_client.get('/async-view/')
        self.assertEqual(response.status_code, 200)

4. Покрытие кода тестами

# Запуск тестов с отчетом о покрытии
coverage run manage.py test
coverage report
coverage html  # Генерация HTML отчета

Важные моменты

  1. Factory Boy - использование фабрик для создания тестовых данных:
import factory

class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = User
    
    username = factory.Sequence(lambda n: f'user_{n}')
    email = factory.LazyAttribute(lambda obj: f'{obj.username}@example.com')
  1. Параметризация тестов:
from parameterized import parameterized

class ParameterizedTests(TestCase):
    @parameterized.expand([
        ("test1", 1, True),
        ("test2", 2, False),
    ])
    def test_parameters(self, name, value, expected):
        """
        Параметризованный тест
        """
        result = some_function(value)
        self.assertEqual(result, expected)
  1. Тестирование Middleware:
class MiddlewareTests(TestCase):
    def test_middleware(self):
        """
        Тестирование middleware
        """
        with self.modify_settings(MIDDLEWARE={
            'append': 'path.to.TestMiddleware',
        }):
            response = self.client.get('/')
            self.assertEqual(response.status_code, 200)
  1. Тестирование сигналов:
from django.db.models.signals import post_save
from django.test.utils import disconnect_signals

class SignalTests(TestCase):
    def setUp(self):
        """
        Отключение сигналов перед тестами
        """
        disconnect_signals(post_save)

    def test_signal(self):
        """
        Тестирование работы сигнала
        """
        # Тестовый код
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment