5.2 KiB
5.2 KiB
Pricing Model Tests Documentation
This directory contains comprehensive tests for the Django pricing models in the Servala project. The tests ensure that price calculations work correctly and prevent regressions when making changes to the pricing logic.
Test Structure
test_pricing.py
Core tests for all pricing models including:
- ComputePlanTestCase: Tests for compute plan pricing and retrieval
- StoragePlanTestCase: Tests for storage plan pricing
- ProgressiveDiscountModelTestCase: Tests for discount calculations with multiple tiers
- VSHNAppCatPriceTestCase: Tests for AppCat service pricing with discounts
- VSHNAppCatAddonTestCase: Tests for addon pricing (base fees and unit rates)
test_pricing_edge_cases.py
Edge case and error condition tests including:
- Discount calculations with zero units or very large numbers
- Price calculations with inactive discount models
- Missing price data handling
- Decimal precision edge cases
- Unique constraint enforcement
- Addon ordering and filtering
test_pricing_integration.py
Integration tests that verify models work together:
- Complete pricing setup across all models
- Multi-currency pricing scenarios
- Complex AppCat services with all features
- External price comparisons
- Real-world comprehensive pricing scenarios
test_utils.py
Helper utilities and mixins for test setup:
PricingTestMixin
: Common setup methods for pricing tests- Helper functions for expected price calculations
Running the Tests
Individual Test Classes
# Run specific test class
uv run --extra dev manage.py test hub.services.tests.test_pricing.ComputePlanTestCase --verbosity=2
# Run specific test method
uv run --extra dev manage.py test hub.services.tests.test_pricing.VSHNAppCatPriceTestCase.test_calculate_final_price_simple --verbosity=2
All Pricing Tests
# Run all pricing tests
uv run --extra dev manage.py test hub.services.tests --verbosity=2
# Run with database reuse for faster execution
uv run --extra dev manage.py test hub.services.tests --verbosity=2 --keepdb
Test Script
Use the provided test runner script:
./run_pricing_tests.sh
Test Coverage
The test suite covers:
Basic Model Functionality
- Model creation and string representations
- Field validation and constraints
- Relationship handling
Price Calculations
- Simple price retrieval (
get_price
methods) - Progressive discount calculations
- Final price calculations with base fees, unit rates, and addons
- Multi-currency support
Edge Cases
- Zero or negative values
- Very large numbers
- Missing price data
- Inactive discount models
- Decimal precision issues
Business Logic
- Mandatory vs. optional addons
- Discount tier spanning
- Service level pricing differences
- External price comparisons
Integration Scenarios
- Complete service setups
- Real-world pricing scenarios
- Cross-model relationships
Key Test Scenarios
Progressive Discount Testing
The tests verify that progressive discounts work correctly:
# Example: 0-9 units (0%), 10-49 units (10%), 50+ units (20%)
# For 60 units:
# - First 10 units: full price
# - Next 40 units: 90% of price (10% discount)
# - Next 10 units: 80% of price (20% discount)
Addon Pricing Testing
Tests cover both addon types:
- Base Fee Addons: Fixed cost regardless of units
- Unit Rate Addons: Cost multiplied by number of units
Multi-Currency Testing
Ensures pricing works across CHF, EUR, and USD currencies.
Best Practices for Adding New Tests
- Use Descriptive Test Names: Test method names should clearly describe what is being tested
- Test Both Success and Failure Cases: Include tests for valid inputs and error conditions
- Use Decimal for Monetary Values: Always use
Decimal
for precise monetary calculations - Test Edge Cases: Include tests for boundary conditions and unusual inputs
- Verify Relationships: Test that model relationships work correctly
- Test Business Logic: Focus on the actual business rules, not just CRUD operations
Common Test Patterns
Setting Up Test Data
def setUp(self):
self.cloud_provider = CloudProvider.objects.create(
name="Test Provider",
slug="test-provider",
description="Test description",
website="https://test.com"
)
Testing Price Calculations
def test_price_calculation(self):
# Set up pricing data
# Call calculation method
result = price_config.calculate_final_price(currency, service_level, units)
# Verify expected result
self.assertEqual(result['total_price'], expected_amount)
Testing Error Conditions
def test_negative_units_error(self):
with self.assertRaises(ValueError):
price_config.calculate_final_price(currency, service_level, -1)
Maintenance
- Run tests after any changes to pricing models or calculations
- Update tests when adding new pricing features
- Add regression tests when fixing bugs
- Keep test data realistic but minimal
- Document complex test scenarios in comments
Dependencies
The tests require:
- Django test framework
- Test database (SQLite in-memory for speed)
- All pricing models and their dependencies
- Decimal library for precise calculations