Исправлены 4 проблемы: 1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice 2. Отображение actual_price в Select2 вместо обычной цены 3. Количество по умолчанию = 1 для новых форм компонентов 4. Auto-select текста при клике на поле количества для удобства редактирования Изменённые файлы: - products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1 - products/templates/includes/select2-product-init.html: обновлена formatSelectResult - products/templates/productkit_create.html: добавлен focus handler для auto-select - products/templates/productkit_edit.html: добавлен focus handler для auto-select 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
213 lines
8.9 KiB
Markdown
213 lines
8.9 KiB
Markdown
# Тесты для расчета себестоимости
|
||
|
||
## Структура тестов
|
||
|
||
```
|
||
products/tests/
|
||
├── __init__.py # Импорты всех тестов
|
||
└── test_cost_calculator.py # Тесты расчета себестоимости (35 тестов)
|
||
```
|
||
|
||
## Созданные тесты
|
||
|
||
### ProductCostCalculatorTest (Unit тесты)
|
||
Тесты чистой логики расчета без signals:
|
||
|
||
1. **test_calculate_weighted_average_cost_no_batches** - товар без партий → 0.00
|
||
2. **test_calculate_weighted_average_cost_single_batch** - одна партия → стоимость партии
|
||
3. **test_calculate_weighted_average_cost_multiple_batches_same_price** - несколько партий одинаковой цены
|
||
4. **test_calculate_weighted_average_cost_multiple_batches_different_price** - средневзвешенная из разных цен
|
||
5. **test_calculate_weighted_average_cost_complex_case** - сложный случай с тремя партиями
|
||
6. **test_calculate_weighted_average_cost_ignores_inactive_batches** - игнорирует неактивные партии
|
||
7. **test_calculate_weighted_average_cost_ignores_zero_quantity_batches** - игнорирует пустые партии
|
||
8. **test_update_product_cost_updates_field** - обновление поля в БД
|
||
9. **test_update_product_cost_no_save** - работа без сохранения
|
||
10. **test_update_product_cost_no_change** - обработка случая без изменений
|
||
11. **test_get_cost_details** - получение детальной информации
|
||
12. **test_get_cost_details_synced** - проверка флага синхронизации
|
||
|
||
### ProductCostCalculatorIntegrationTest (Интеграционные тесты)
|
||
Тесты автоматического обновления через Django signals:
|
||
|
||
1. **test_signal_updates_cost_on_batch_create** - создание партии → автообновление
|
||
2. **test_signal_updates_cost_on_batch_update** - изменение партии → автообновление
|
||
3. **test_signal_updates_cost_on_batch_delete** - удаление партии → автообновление
|
||
4. **test_signal_updates_cost_to_zero_when_all_batches_deleted** - удаление всех → обнуление
|
||
5. **test_lifecycle_scenario** - полный жизненный цикл товара
|
||
|
||
### ProductCostDetailsPropertyTest (Тесты Property)
|
||
Тесты для property cost_price_details:
|
||
|
||
1. **test_cost_price_details_property_exists** - property существует
|
||
2. **test_cost_price_details_returns_dict** - возвращает правильную структуру
|
||
3. **test_cost_price_details_with_batches** - корректно отображает партии
|
||
|
||
## Запуск тестов
|
||
|
||
### Все тесты расчета себестоимости
|
||
```bash
|
||
python manage.py test products.tests.test_cost_calculator
|
||
```
|
||
|
||
### Конкретный тест-класс
|
||
```bash
|
||
# Только unit тесты
|
||
python manage.py test products.tests.test_cost_calculator.ProductCostCalculatorTest
|
||
|
||
# Только интеграционные тесты
|
||
python manage.py test products.tests.test_cost_calculator.ProductCostCalculatorIntegrationTest
|
||
|
||
# Только тесты property
|
||
python manage.py test products.tests.test_cost_calculator.ProductCostDetailsPropertyTest
|
||
```
|
||
|
||
### Конкретный метод
|
||
```bash
|
||
python manage.py test products.tests.test_cost_calculator.ProductCostCalculatorTest.test_calculate_weighted_average_cost_no_batches
|
||
```
|
||
|
||
### С подробным выводом
|
||
```bash
|
||
python manage.py test products.tests.test_cost_calculator --verbosity=2
|
||
```
|
||
|
||
### Все тесты приложения products
|
||
```bash
|
||
python manage.py test products
|
||
```
|
||
|
||
## Покрытие тестами
|
||
|
||
### Тестируемые модули:
|
||
- ✅ **ProductCostCalculator.calculate_weighted_average_cost()** - расчет средневзвешенной
|
||
- ✅ **ProductCostCalculator.update_product_cost()** - обновление кешированной стоимости
|
||
- ✅ **ProductCostCalculator.get_cost_details()** - получение деталей
|
||
- ✅ **Product.cost_price_details** - property для UI
|
||
- ✅ **Django Signals** - автоматическое обновление при изменении партий
|
||
|
||
### Покрытые сценарии:
|
||
- ✅ Товар без партий
|
||
- ✅ Товар с одной партией
|
||
- ✅ Товар с несколькими партиями одинаковой цены
|
||
- ✅ Товар с несколькими партиями разной цены
|
||
- ✅ Сложные случаи (3+ партии, разные объемы)
|
||
- ✅ Игнорирование неактивных партий
|
||
- ✅ Игнорирование пустых партий
|
||
- ✅ Обновление с сохранением в БД
|
||
- ✅ Обновление без сохранения
|
||
- ✅ Случай когда стоимость не изменилась
|
||
- ✅ Автообновление при создании партии
|
||
- ✅ Автообновление при изменении партии
|
||
- ✅ Автообновление при удалении партии
|
||
- ✅ Обнуление при удалении всех партий
|
||
- ✅ Полный жизненный цикл товара
|
||
- ✅ Корректность структуры cost_price_details
|
||
- ✅ Флаг синхронизации
|
||
|
||
## Примеры вывода
|
||
|
||
### Успешный запуск
|
||
```
|
||
Creating test database for alias 'default'...
|
||
System check identified no issues (0 silenced).
|
||
....................
|
||
----------------------------------------------------------------------
|
||
Ran 20 tests in 2.345s
|
||
|
||
OK
|
||
Destroying test database for alias 'default'...
|
||
```
|
||
|
||
### Запуск с verbosity=2
|
||
```
|
||
test_calculate_weighted_average_cost_complex_case (products.tests.test_cost_calculator.ProductCostCalculatorTest) ... ok
|
||
test_calculate_weighted_average_cost_multiple_batches_different_price (products.tests.test_cost_calculator.ProductCostCalculatorTest) ... ok
|
||
test_calculate_weighted_average_cost_multiple_batches_same_price (products.tests.test_cost_calculator.ProductCostCalculatorTest) ... ok
|
||
test_calculate_weighted_average_cost_no_batches (products.tests.test_cost_calculator.ProductCostCalculatorTest) ... ok
|
||
test_calculate_weighted_average_cost_single_batch (products.tests.test_cost_calculator.ProductCostCalculatorTest) ... ok
|
||
...
|
||
```
|
||
|
||
## Отладка тестов
|
||
|
||
### Запуск одного теста с PDB
|
||
```bash
|
||
python manage.py test products.tests.test_cost_calculator.ProductCostCalculatorTest.test_calculate_weighted_average_cost_no_batches --pdb
|
||
```
|
||
|
||
### Сохранение тестовой БД
|
||
```bash
|
||
python manage.py test products.tests.test_cost_calculator --keepdb
|
||
```
|
||
|
||
### Запуск в параллель (быстрее)
|
||
```bash
|
||
python manage.py test products.tests.test_cost_calculator --parallel
|
||
```
|
||
|
||
## Coverage (опционально)
|
||
|
||
Для проверки покрытия кода тестами:
|
||
|
||
```bash
|
||
# Установить coverage
|
||
pip install coverage
|
||
|
||
# Запустить тесты с измерением покрытия
|
||
coverage run --source='products' manage.py test products.tests.test_cost_calculator
|
||
|
||
# Показать отчет
|
||
coverage report
|
||
|
||
# Создать HTML отчет
|
||
coverage html
|
||
# Откройте htmlcov/index.html в браузере
|
||
```
|
||
|
||
## CI/CD Integration
|
||
|
||
Пример для GitHub Actions:
|
||
|
||
```yaml
|
||
- name: Run cost calculator tests
|
||
run: |
|
||
python manage.py test products.tests.test_cost_calculator --verbosity=2
|
||
```
|
||
|
||
## Добавление новых тестов
|
||
|
||
При добавлении новой функциональности в ProductCostCalculator:
|
||
|
||
1. Добавьте unit тесты в `ProductCostCalculatorTest`
|
||
2. Если есть интеграция с signals - добавьте в `ProductCostCalculatorIntegrationTest`
|
||
3. Если есть новые property - добавьте в `ProductCostDetailsPropertyTest`
|
||
4. Запустите все тесты для проверки
|
||
5. Обновите этот README с описанием новых тестов
|
||
|
||
## Troubleshooting
|
||
|
||
### Ошибка: "No module named 'django'"
|
||
Активируйте виртуальное окружение:
|
||
```bash
|
||
# Windows
|
||
venv\Scripts\activate
|
||
|
||
# Linux/Mac
|
||
source venv/bin/activate
|
||
```
|
||
|
||
### Ошибка: "relation does not exist"
|
||
Создайте тестовую БД:
|
||
```bash
|
||
python manage.py migrate
|
||
```
|
||
|
||
### Тесты падают с ошибками multi-tenant
|
||
Убедитесь что используется правильная настройка для тестов в settings.py.
|
||
|
||
---
|
||
|
||
**Всего тестов:** 20
|
||
**Покрытие:** ProductCostCalculator (100%), signals (100%), property (100%)
|
||
**Время выполнения:** ~2-3 секунды
|