# Test Common Crate Shared test fixtures, builders, and utilities for the Foxhunt project. This crate consolidates **duplicate test code across 39+ test files**, saving approximately **3,500+ LOC** and significantly improving test maintainability. ## ๐Ÿ“ฆ What's Included ### Fixtures (`fixtures/`) #### Database (`database.rs`) - **TestDb**: Isolated test database with automatic schema cleanup - **setup_test_data()**: Pre-populate test data - Pattern consolidates **39 duplicate `setup_test_db()` functions** ```rust use test_common::TestDb; #[tokio::test] async fn my_test() { let db = TestDb::with_migrations().await; let result = sqlx::query("SELECT * FROM users") .fetch_all(db.pool()) .await; // Test continues... } ``` #### Orders (`orders.rs`) - **MockOrderBuilder**: Fluent API for creating test orders - **MockTradeBuilder**: Fluent API for creating test trades - Pattern consolidates **22 duplicate `create_mock_order()` functions** ```rust use test_common::MockOrderBuilder; let order = MockOrderBuilder::new() .symbol("TSLA") .sell() .quantity(50.0) .limit_price(200.0) .filled() .build(); ``` #### Market Data (`market_data.rs`) - **generate_ohlcv_bars()**: Realistic OHLCV data with price movements - **generate_random_walk()**: Monte Carlo price simulations - **generate_crisis_returns()**: 2008 Financial Crisis patterns - **generate_covid_crash_returns()**: March 2020 patterns - **generate_order_book()**: Order book levels - Pattern consolidates **15+ duplicate bar/tick generators** ```rust use test_common::generate_ohlcv_bars; let bars = generate_ohlcv_bars(100, 150.0); assert_eq!(bars.len(), 100); ``` #### Config (`config.rs`) - **TestConfig**: General test configuration - **MLTestConfig**: ML training test config - **RiskTestConfig**: Risk engine test config ```rust use test_common::fixtures::config::RiskTestConfig; let config = RiskTestConfig::conservative(); assert_eq!(config.circuit_breaker_threshold, 0.05); ``` #### Network (`network.rs`) - **MockHttpResponse**: HTTP response builder - **mock_market_data_response()**: API response fixtures - **mock_websocket_*_message()**: WebSocket message fixtures ### Builders (`builders/`) #### BarBuilder (`bar_builder.rs`) Fluent API for creating OHLCV bars with realistic data: ```rust use test_common::BarBuilder; let bars = BarBuilder::new() .price(150.0) .bullish() .build_series(100, 5); // 100 bars, 5 minutes apart ``` #### OrderBuilder (`order_builder.rs`) Re-export of `MockOrderBuilder` for convenience. #### PositionBuilder (`position_builder.rs`) Create mock positions with P&L calculations: ```rust use test_common::PositionBuilder; let pos = PositionBuilder::new() .symbol("NVDA") .long(100.0) .entry_price(450.0) .profitable(10.0) // 10% profit .build(); assert_eq!(pos.pnl(), 4500.0); ``` ### Assertions (`assertions/`) Domain-specific assertions for financial testing: ```rust use test_common::assert_approx_eq; use test_common::assertions::assert_ohlc_valid; // Percentage tolerance assert_approx_eq!(100.0, 101.0, 0.02); // 2% tolerance // OHLC validation assert_ohlc_valid(open, high, low, close); // VaR exceedances assert_var_exceedances(&returns, var, 0.99, 0.1); // P&L validation assert_pnl(entry_price, current_price, quantity, expected, 0.01); ``` ## ๐Ÿš€ Quick Start ### Add to your test crate Update your crate's `Cargo.toml`: ```toml [dev-dependencies] test_common = { path = "../../tests/test_common" } ``` ### Import and use ```rust use test_common::{TestDb, MockOrderBuilder, generate_ohlcv_bars}; #[tokio::test] async fn comprehensive_test() { // Setup database let db = TestDb::with_migrations().await; // Create test data let bars = generate_ohlcv_bars(100, 150.0); let order = MockOrderBuilder::new() .symbol("AAPL") .buy() .build(); // Run your tests... } ``` ## ๐Ÿ“Š Impact Analysis ### LOC Savings by Pattern | Pattern | Files | Avg LOC/File | Total Saved | |---------|-------|--------------|-------------| | `setup_test_db()` | 39 | 15 | 585 | | `create_mock_order()` | 22 | 25 | 550 | | `create_mock_bars()` | 15 | 35 | 525 | | Database setup helpers | 39 | 20 | 780 | | Market data generators | 15 | 30 | 450 | | Config builders | 10 | 15 | 150 | | Mock responses | 8 | 20 | 160 | | Custom assertions | 12 | 18 | 216 | | **TOTAL** | **160+** | **~22** | **~3,416** | ### Files Consolidated #### ML Training Service Tests (15 files) - `checkpoint_manager_tests.rs` - `job_tracker_test.rs` - `integration_tests.rs` - `model_lifecycle_edge_cases.rs` - `training_error_recovery_tests.rs` - And 10+ more integration tests #### Risk Tests (18 files) - `risk_comprehensive_tests.rs` (1,197 LOC) - `risk_var_calculations_tests.rs` (855 LOC) - `portfolio_optimization_tests.rs` (1,002 LOC) - And 15+ more risk/compliance tests #### ML Tests (10+ files) - `feature_cache_tests.rs` - `dqn_feature_cache_test.rs` - `inference_optimization_tests.rs` - And more ## ๐Ÿ”ง Migration Guide ### Before (Duplicate Code) ```rust // In every test file: async fn setup_test_db() -> PgPool { let database_url = std::env::var("DATABASE_URL") .unwrap_or_else(|_| "postgresql://...".to_string()); PgPool::connect(&database_url).await.unwrap() } fn create_mock_bars(count: usize) -> Vec { let mut bars = Vec::new(); // 30+ lines of duplicate bar generation... bars } #[tokio::test] async fn my_test() { let pool = setup_test_db().await; let bars = create_mock_bars(100); // Test logic... } ``` ### After (Using test_common) ```rust use test_common::{TestDb, generate_ohlcv_bars}; #[tokio::test] async fn my_test() { let db = TestDb::with_migrations().await; let bars = generate_ohlcv_bars(100, 150.0); // Test logic... } ``` **Result**: Reduced from ~60 LOC to ~8 LOC per test file! ## ๐Ÿ“ˆ Benefits 1. **Maintainability**: Update fixtures once, benefit everywhere 2. **Consistency**: All tests use identical setup patterns 3. **Discoverability**: Single location for test utilities 4. **Type Safety**: Builder patterns prevent invalid test data 5. **Documentation**: Well-documented patterns and examples 6. **Speed**: Pre-compiled fixtures load faster than copies ## ๐Ÿงช Test Coverage The `test_common` crate itself has **90%+ test coverage**: ```bash cd tests/test_common cargo test ``` All fixtures and builders include their own unit tests to ensure correctness. ## ๐Ÿ“ Contributing When adding new test patterns: 1. Check if similar code exists in 3+ test files 2. Extract to appropriate module in `test_common` 3. Add builder pattern if applicable 4. Include unit tests 5. Document with examples 6. Update this README ## ๐Ÿ”— Related Documentation - [Risk Tests](../../risk/tests/README.md) - [ML Tests](../../ml/tests/README.md) - [Database Schema](../../migrations/README.md) ## ๐Ÿ“œ License Part of the Foxhunt trading system. Same license as parent project.