penti/backend/tests/test_api_backtest.py

130 lines
4.1 KiB
Python

"""
Backtest API integration tests
"""
import pytest
from datetime import date
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
@pytest.mark.integration
class TestBacktestAPI:
"""Backtest API endpoint tests"""
def test_list_strategies(self, client: TestClient):
"""Test strategy list endpoint"""
response = client.get("/api/v1/backtest/strategies/list")
assert response.status_code == 200
data = response.json()
assert "strategies" in data
assert len(data["strategies"]) > 0
# Check strategy structure
strategy = data["strategies"][0]
assert "name" in strategy
assert "description" in strategy
def test_run_backtest_invalid_dates(self, client: TestClient):
"""Test backtest with invalid date range"""
config = {
"name": "Invalid Date Test",
"strategy_name": "multi_factor",
"start_date": "2023-12-31",
"end_date": "2023-01-01", # End before start
"initial_capital": 10000000,
"commission_rate": 0.0015,
"rebalance_frequency": "monthly",
"strategy_config": {"count": 20}
}
response = client.post("/api/v1/backtest/run", json=config)
# Should fail validation
assert response.status_code in [400, 422]
def test_run_backtest_invalid_strategy(self, client: TestClient):
"""Test backtest with non-existent strategy"""
config = {
"name": "Invalid Strategy Test",
"strategy_name": "nonexistent_strategy",
"start_date": "2023-01-01",
"end_date": "2023-12-31",
"initial_capital": 10000000,
"commission_rate": 0.0015,
"rebalance_frequency": "monthly",
"strategy_config": {"count": 20}
}
response = client.post("/api/v1/backtest/run", json=config)
# Should fail with 400 or 404
assert response.status_code in [400, 404]
def test_run_backtest_missing_fields(self, client: TestClient):
"""Test backtest with missing required fields"""
config = {
"name": "Incomplete Test",
"strategy_name": "multi_factor",
# Missing dates and other required fields
}
response = client.post("/api/v1/backtest/run", json=config)
assert response.status_code == 422 # Validation error
@pytest.mark.slow
def test_run_backtest_success(
self,
client: TestClient,
sample_assets,
sample_price_data
):
"""Test successful backtest execution"""
config = {
"name": "Integration Test Backtest",
"strategy_name": "multi_factor",
"start_date": "2023-01-01",
"end_date": "2023-01-31",
"initial_capital": 10000000,
"commission_rate": 0.0015,
"rebalance_frequency": "monthly",
"strategy_config": {"count": 3}
}
response = client.post("/api/v1/backtest/run", json=config)
# Note: May fail if insufficient data, that's expected
if response.status_code == 200:
data = response.json()
assert "id" in data
assert "name" in data
assert "status" in data
assert data["name"] == config["name"]
def test_get_backtest_not_found(self, client: TestClient):
"""Test getting non-existent backtest"""
import uuid
fake_id = str(uuid.uuid4())
response = client.get(f"/api/v1/backtest/{fake_id}")
assert response.status_code == 404
def test_list_backtests(self, client: TestClient):
"""Test listing backtests"""
response = client.get("/api/v1/backtest/?skip=0&limit=10")
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
def test_delete_backtest_not_found(self, client: TestClient):
"""Test deleting non-existent backtest"""
import uuid
fake_id = str(uuid.uuid4())
response = client.delete(f"/api/v1/backtest/{fake_id}")
assert response.status_code == 404