- Added all real order statuses: new, confirmed, in_assembly, in_delivery, return - Test #2: expanded to test cancellation from 4 different statuses (new, confirmed, in_assembly, in_delivery) - Test #3: updated to use new → cancelled → in_assembly flow - Test #4: updated to use in_delivery status instead of packing - All 5 tests passing successfully
🧪 Критические тесты переходов между статусами заказов
📋 Описание
Набор из 5 критических тестов, проверяющих корректность работы системы резервирования и списания товаров при переходах между статусами заказов.
🎯 Тестируемые сценарии
1️⃣ Тест "Танцы туда-сюда" (test_01_draft_to_completed_to_cancelled_to_completed)
Проверяет множественные переходы между статусами:
draft→completed→cancelled→completed(снова)- Цель: Убедиться что Sale не дублируется при повторном переходе в
completed
2️⃣ Тест отмены из черновика (test_02_draft_to_cancelled_releases_reservations)
Проверяет освобождение резервов при отмене:
draft→cancelled- Цель: Резервы должны корректно освобождаться
3️⃣ Тест возврата из отмены (test_03_cancelled_to_pending_reserves_stock)
Проверяет резервирование при возврате:
draft→cancelled→pending- Цель: Резервы должны восстанавливаться при возврате из отмены
4️⃣ Тест промежуточного статуса (test_04_create_order_with_intermediate_status)
Проверяет создание заказа с новым статусом:
- Создание заказа сразу со статусом "Упаковывается" (не positive, не negative)
- Цель: Система должна работать с любыми промежуточными статусами
5️⃣ Тест отката от выполненного (test_05_completed_to_draft_rollback_sale)
Проверяет откат Sale:
draft→completed→draft- Цель: Sale должен корректно откатываться, товар возвращаться на склад
🚀 Запуск тестов
Запуск всех тестов:
cd myproject
python manage.py test inventory.tests.test_order_status_transitions
Запуск конкретного теста:
python manage.py test inventory.tests.test_order_status_transitions.OrderStatusTransitionCriticalTest.test_01_draft_to_completed_to_cancelled_to_completed
Запуск с подробным выводом:
python manage.py test inventory.tests.test_order_status_transitions --verbosity=2
✅ Что проверяет каждый тест
Все тесты проверяют 3 критических аспекта:
1. Корректность Stock
quantity_available- доступное количествоquantity_reserved- зарезервированное количествоquantity_free- свободное количество (available - reserved)
2. Корректность Reservation
- Статус резерва (
reserved,converted_to_sale,released) - Переходы между статусами при изменении статуса заказа
3. Корректность Sale и StockBatch
- Sale не дублируется при повторных переходах
- StockBatch корректно уменьшается/восстанавливается
- SaleBatchAllocation создаётся только один раз
🔍 Пример вывода успешного теста
test_01_draft_to_completed_to_cancelled_to_completed ... ok
test_02_draft_to_cancelled_releases_reservations ... ok
test_03_cancelled_to_pending_reserves_stock ... ok
test_04_create_order_with_intermediate_status ... ok
test_05_completed_to_draft_rollback_sale ... ok
----------------------------------------------------------------------
Ran 5 tests in 2.341s
OK
⚠️ Важные особенности
- Тесты используют TransactionTestCase - каждый тест выполняется в отдельной транзакции
- Создаётся отдельная схема БД
test_order_statusдля изоляции - После каждого теста данные очищаются - тесты не влияют друг на друга
- Тесты работают с тенантами - используется
schema_context()
🐛 Если тесты падают
Проверьте сигналы:
inventory/signals.py- все сигналы должны быть подключеныinventory/apps.py- сигналы должны импортироваться вready()
Проверьте модели:
Reservation.status- должны быть варианты:reserved,converted_to_sale,releasedOrderStatus- должны быть флагиis_positive_end,is_negative_end
Проверьте БД:
python manage.py migrate
📝 Добавление новых тестов
Чтобы добавить новый тест:
- Создайте метод в классе
OrderStatusTransitionCriticalTest - Начните имя с
test_(обязательно!) - Используйте вспомогательные методы:
_create_order(status, quantity)- создать заказ_assert_stock_state(available, reserved, free)- проверить Stock_assert_reservation_status(order, expected_status)- проверить резерв_assert_sale_exists(order, should_exist)- проверить Sale
Пример:
def test_06_my_new_scenario(self):
"""Описание сценария"""
with schema_context('test_order_status'):
order = self._create_order(self.status_draft, quantity=Decimal('10.00'))
# Ваши проверки
self._assert_stock_state(
available=Decimal('100.00'),
reserved=Decimal('10.00'),
free=Decimal('90.00')
)
🎓 Дополнительная информация
- Документация Django Testing: https://docs.djangoproject.com/en/stable/topics/testing/
- Django Tenants Testing: https://django-tenants.readthedocs.io/en/latest/test.html