Add pytest test files for microservices
- Created test files for GPU service (tests/test_main.py) - Created test files for Marketplace service (tests/test_main.py) - Created test files for Trading service (tests/test_main.py) - Created test files for Governance service (tests/test_main.py) - Created integration tests for API gateway (tests/test_gateway.py) - Added pytest dependencies to all service pyproject.toml files - Created TEST_COVERAGE_REQUIREMENTS.md documenting coverage targets and best practices This completes Phase 8: Create pytest test files for microservices
This commit is contained in:
@@ -13,6 +13,12 @@ dependencies = [
|
||||
"aitbc-core",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest>=7.4.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -21,3 +27,6 @@ build-backend = "poetry.core.masonry.api"
|
||||
packages = [
|
||||
{ include = "api_gateway", from = "src" }
|
||||
]
|
||||
|
||||
[tool.poetry.extras]
|
||||
test = ["pytest", "pytest-asyncio"]
|
||||
|
||||
3
apps/api-gateway/tests/__init__.py
Normal file
3
apps/api-gateway/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
API Gateway tests
|
||||
"""
|
||||
71
apps/api-gateway/tests/test_gateway.py
Normal file
71
apps/api-gateway/tests/test_gateway.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
Test API Gateway routing
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from api_gateway.main import app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
"""Create test client for API Gateway"""
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def test_gateway_health_check(client):
|
||||
"""Test gateway health check endpoint"""
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "healthy"
|
||||
assert data["service"] == "api-gateway"
|
||||
|
||||
|
||||
def test_service_registry(client):
|
||||
"""Test service registry endpoint"""
|
||||
response = client.get("/services")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "services" in data
|
||||
services = data["services"]
|
||||
assert isinstance(services, list)
|
||||
# Check that GPU service is registered
|
||||
gpu_service = next((s for s in services if s["name"] == "gpu"), None)
|
||||
assert gpu_service is not None
|
||||
assert gpu_service["url"] == "http://localhost:8101"
|
||||
assert "/gpu/*" in gpu_service["routes"]
|
||||
|
||||
|
||||
def test_gpu_route_proxy(client):
|
||||
"""Test that gateway proxies requests to GPU service"""
|
||||
# This test requires GPU service to be running
|
||||
# In CI, this would be mocked or services would be started
|
||||
response = client.get("/gpu/health")
|
||||
# May fail if service not running, but tests routing logic
|
||||
assert response.status_code in [200, 503] # 503 if service down
|
||||
|
||||
|
||||
def test_marketplace_route_proxy(client):
|
||||
"""Test that gateway proxies requests to Marketplace service"""
|
||||
response = client.get("/marketplace/health")
|
||||
assert response.status_code in [200, 503]
|
||||
|
||||
|
||||
def test_trading_route_proxy(client):
|
||||
"""Test that gateway proxies requests to Trading service"""
|
||||
response = client.get("/trading/health")
|
||||
assert response.status_code in [200, 503]
|
||||
|
||||
|
||||
def test_governance_route_proxy(client):
|
||||
"""Test that gateway proxies requests to Governance service"""
|
||||
response = client.get("/governance/health")
|
||||
assert response.status_code in [200, 503]
|
||||
|
||||
|
||||
def test_unknown_route(client):
|
||||
"""Test that unknown routes return 404"""
|
||||
response = client.get("/unknown/path")
|
||||
assert response.status_code == 404
|
||||
285
apps/docs/TEST_COVERAGE_REQUIREMENTS.md
Normal file
285
apps/docs/TEST_COVERAGE_REQUIREMENTS.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# AITBC Microservices Test Coverage Requirements
|
||||
|
||||
This document outlines the test coverage requirements for the AITBC microservices architecture.
|
||||
|
||||
## Overview
|
||||
|
||||
Each microservice should maintain adequate test coverage to ensure reliability and facilitate future development. Test coverage should be measured and tracked as part of the CI/CD pipeline.
|
||||
|
||||
## Test Coverage Targets
|
||||
|
||||
### Minimum Requirements
|
||||
|
||||
- **Unit Tests**: 70% line coverage minimum
|
||||
- **Integration Tests**: 50% line coverage minimum
|
||||
- **Overall Coverage**: 60% line coverage minimum per service
|
||||
|
||||
### Ideal Targets
|
||||
|
||||
- **Unit Tests**: 80% line coverage
|
||||
- **Integration Tests**: 70% line coverage
|
||||
- **Overall Coverage**: 75% line coverage per service
|
||||
|
||||
## Service-Specific Requirements
|
||||
|
||||
### GPU Service
|
||||
|
||||
**Unit Test Coverage Requirements:**
|
||||
- Domain models (GPUArchitecture, GPURegistry, ConsumerGPUProfile, EdgeGPUMetrics, GPUBooking, GPUReview): 80%
|
||||
- Service layer (EdgeGPUService): 75%
|
||||
- API endpoints: 70%
|
||||
|
||||
**Integration Test Coverage Requirements:**
|
||||
- Database operations: 70%
|
||||
- API endpoint integration: 60%
|
||||
- Service dependencies: 50%
|
||||
|
||||
**Critical Path Tests:**
|
||||
- Consumer GPU profile listing
|
||||
- Edge GPU metrics creation
|
||||
- GPU discovery (async)
|
||||
- Inference optimization (async)
|
||||
|
||||
### Marketplace Service
|
||||
|
||||
**Unit Test Coverage Requirements:**
|
||||
- Domain models (MarketplaceOffer, MarketplaceBid, GlobalMarketplaceOffer, GlobalMarketplaceTransaction, etc.): 75%
|
||||
- Service layer (MarketplaceService): 70%
|
||||
- API endpoints: 65%
|
||||
|
||||
**Integration Test Coverage Requirements:**
|
||||
- Database operations: 70%
|
||||
- API endpoint integration: 60%
|
||||
- Service dependencies: 50%
|
||||
|
||||
**Critical Path Tests:**
|
||||
- Offer creation and retrieval
|
||||
- Bid creation and retrieval
|
||||
- Marketplace analytics
|
||||
|
||||
### Trading Service
|
||||
|
||||
**Unit Test Coverage Requirements:**
|
||||
- Domain models (TradeRequest, TradeMatch, TradeNegotiation, TradeAgreement, TradeSettlement, TradeFeedback, TradingAnalytics): 75%
|
||||
- Service layer (TradingService): 70%
|
||||
- API endpoints: 65%
|
||||
|
||||
**Integration Test Coverage Requirements:**
|
||||
- Database operations: 70%
|
||||
- API endpoint integration: 60%
|
||||
- Service dependencies: 50%
|
||||
|
||||
**Critical Path Tests:**
|
||||
- Trade request creation
|
||||
- Trade matching logic
|
||||
- Agreement creation
|
||||
- Settlement processing
|
||||
|
||||
### Governance Service
|
||||
|
||||
**Unit Test Coverage Requirements:**
|
||||
- Domain models (GovernanceProfile, Proposal, Vote, DaoTreasury, TransparencyReport): 75%
|
||||
- Service layer (GovernanceService): 70%
|
||||
- API endpoints: 65%
|
||||
|
||||
**Integration Test Coverage Requirements:**
|
||||
- Database operations: 70%
|
||||
- API endpoint integration: 60%
|
||||
- Service dependencies: 50%
|
||||
|
||||
**Critical Path Tests:**
|
||||
- Proposal creation
|
||||
- Vote casting
|
||||
- Proposal execution
|
||||
- Treasury management
|
||||
|
||||
### API Gateway
|
||||
|
||||
**Unit Test Coverage Requirements:**
|
||||
- Routing logic: 80%
|
||||
- Service registry: 75%
|
||||
- Proxy functionality: 70%
|
||||
|
||||
**Integration Test Coverage Requirements:**
|
||||
- Gateway to service routing: 70%
|
||||
- Load balancing: 50%
|
||||
- Error handling: 60%
|
||||
|
||||
**Critical Path Tests:**
|
||||
- Health check routing
|
||||
- Service registry updates
|
||||
- Request proxying to each service
|
||||
- Unknown route handling
|
||||
|
||||
## Test Types
|
||||
|
||||
### Unit Tests
|
||||
|
||||
**Purpose**: Test individual functions and methods in isolation.
|
||||
|
||||
**Requirements**:
|
||||
- Mock external dependencies (database, external APIs)
|
||||
- Test edge cases and error conditions
|
||||
- Test validation logic
|
||||
- Test business logic
|
||||
|
||||
**Example Coverage Areas**:
|
||||
- Domain model validation
|
||||
- Service method logic
|
||||
- Utility functions
|
||||
- Helper methods
|
||||
|
||||
### Integration Tests
|
||||
|
||||
**Purpose**: Test interactions between components.
|
||||
|
||||
**Requirements**:
|
||||
- Use test databases
|
||||
- Test database operations
|
||||
- Test API endpoint integration
|
||||
- Test service-to-service communication
|
||||
|
||||
**Example Coverage Areas**:
|
||||
- Database CRUD operations
|
||||
- API request/response handling
|
||||
- Service dependency resolution
|
||||
- Transaction management
|
||||
|
||||
### End-to-End Tests
|
||||
|
||||
**Purpose**: Test complete workflows across services.
|
||||
|
||||
**Requirements**:
|
||||
- Test critical user journeys
|
||||
- Test gateway routing
|
||||
- Test service orchestration
|
||||
- Test error propagation
|
||||
|
||||
**Example Coverage Areas**:
|
||||
- Complete trade flow (request → match → negotiate → agree → settle)
|
||||
- Complete proposal flow (create → vote → execute)
|
||||
- Gateway routing to all services
|
||||
|
||||
## Test Execution
|
||||
|
||||
### Running Tests
|
||||
|
||||
**Run all tests for a service:**
|
||||
```bash
|
||||
cd apps/<service-name>
|
||||
pytest tests/
|
||||
```
|
||||
|
||||
**Run with coverage:**
|
||||
```bash
|
||||
pytest tests/ --cov=src --cov-report=html --cov-report=term
|
||||
```
|
||||
|
||||
**Run specific test file:**
|
||||
```bash
|
||||
pytest tests/test_main.py
|
||||
```
|
||||
|
||||
**Run specific test:**
|
||||
```bash
|
||||
pytest tests/test_main.py::test_health_check
|
||||
```
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
Tests should run automatically in CI/CD pipeline:
|
||||
|
||||
1. **On Pull Request**: Run all tests with coverage reporting
|
||||
2. **On Merge to Main**: Run all tests with coverage reporting and enforce minimum coverage
|
||||
3. **Nightly**: Run full test suite including end-to-end tests
|
||||
|
||||
### Coverage Enforcement
|
||||
|
||||
Minimum coverage thresholds should be enforced in CI:
|
||||
|
||||
```ini
|
||||
[tool.coverage.run]
|
||||
source = "src"
|
||||
|
||||
[tool.coverage.report]
|
||||
exclude_lines = [
|
||||
"pragma: no cover",
|
||||
"def __repr__",
|
||||
"raise AssertionError",
|
||||
"raise NotImplementedError",
|
||||
"if __name__ == .__main__.:",
|
||||
"if TYPE_CHECKING:",
|
||||
"@abstractmethod",
|
||||
]
|
||||
|
||||
[tool.coverage.fail_under]
|
||||
minimum = 60
|
||||
```
|
||||
|
||||
## Coverage Reporting
|
||||
|
||||
### Coverage Reports
|
||||
|
||||
Coverage reports should be generated in multiple formats:
|
||||
|
||||
- **HTML**: For detailed analysis (coverage/html/index.html)
|
||||
- **Terminal**: For quick summary
|
||||
- **XML**: For CI/CD integration
|
||||
|
||||
### Coverage Tracking
|
||||
|
||||
Coverage should be tracked over time to identify trends:
|
||||
|
||||
- Track coverage by service
|
||||
- Track coverage by module
|
||||
- Track coverage by test type
|
||||
- Identify declining coverage
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Test Organization
|
||||
|
||||
- Organize tests by module/functionality
|
||||
- Use descriptive test names
|
||||
- Keep tests independent
|
||||
- Use fixtures for common setup
|
||||
|
||||
### Test Data
|
||||
|
||||
- Use factories for test data creation
|
||||
- Use in-memory databases for unit tests
|
||||
- Use test database for integration tests
|
||||
- Clean up test data after each test
|
||||
|
||||
### Mocking
|
||||
|
||||
- Mock external dependencies
|
||||
- Use pytest-mock for mocking
|
||||
- Mock database calls in unit tests
|
||||
- Use real database in integration tests
|
||||
|
||||
### Async Testing
|
||||
|
||||
- Use pytest-asyncio for async tests
|
||||
- Mark async tests with @pytest.mark.asyncio
|
||||
- Test async service methods
|
||||
- Test async database operations
|
||||
|
||||
## Coverage Exclusions
|
||||
|
||||
The following can be excluded from coverage calculations:
|
||||
|
||||
- Type checking blocks (`if TYPE_CHECKING:`)
|
||||
- Abstract methods
|
||||
- Representation methods (`__repr__`)
|
||||
- Test files themselves
|
||||
- Configuration files
|
||||
- Migration scripts
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Add coverage reporting to CI/CD pipeline
|
||||
2. Set up coverage tracking dashboard
|
||||
3. Review coverage reports regularly
|
||||
4. Increase coverage targets as codebase matures
|
||||
5. Add end-to-end tests for critical workflows
|
||||
@@ -14,6 +14,13 @@ dependencies = [
|
||||
"aitbc-core",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest>=7.4.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"httpx>=0.25.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -22,3 +29,6 @@ build-backend = "poetry.core.masonry.api"
|
||||
packages = [
|
||||
{ include = "governance_service", from = "src" }
|
||||
]
|
||||
|
||||
[tool.poetry.extras]
|
||||
test = ["pytest", "pytest-asyncio", "httpx"]
|
||||
|
||||
3
apps/governance-service/tests/__init__.py
Normal file
3
apps/governance-service/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Governance service tests
|
||||
"""
|
||||
72
apps/governance-service/tests/test_main.py
Normal file
72
apps/governance-service/tests/test_main.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
Test Governance service main application
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from governance_service.main import app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
"""Create test client for Governance service"""
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def test_health_check(client):
|
||||
"""Test health check endpoint"""
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "healthy"
|
||||
assert data["service"] == "governance-service"
|
||||
|
||||
|
||||
def test_governance_status(client):
|
||||
"""Test governance status endpoint"""
|
||||
response = client.get("/governance/status")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "operational"
|
||||
assert data["service"] == "governance-service"
|
||||
|
||||
|
||||
def test_get_governance_profiles(client):
|
||||
"""Test get governance profiles endpoint"""
|
||||
response = client.get("/v1/governance/profiles")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_governance_proposals(client):
|
||||
"""Test get governance proposals endpoint"""
|
||||
response = client.get("/v1/governance/proposals")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_governance_votes(client):
|
||||
"""Test get governance votes endpoint"""
|
||||
response = client.get("/v1/governance/votes")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_governance_treasury(client):
|
||||
"""Test get governance treasury endpoint"""
|
||||
response = client.get("/v1/governance/treasury")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, dict)
|
||||
|
||||
|
||||
def test_get_governance_analytics(client):
|
||||
"""Test get governance analytics endpoint"""
|
||||
response = client.get("/v1/governance/analytics")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, dict)
|
||||
@@ -14,6 +14,13 @@ dependencies = [
|
||||
"aitbc-core",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest>=7.4.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"httpx>=0.25.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -22,3 +29,6 @@ build-backend = "poetry.core.masonry.api"
|
||||
packages = [
|
||||
{ include = "gpu_service", from = "src" }
|
||||
]
|
||||
|
||||
[tool.poetry.extras]
|
||||
test = ["pytest", "pytest-asyncio", "httpx"]
|
||||
|
||||
3
apps/gpu-service/tests/__init__.py
Normal file
3
apps/gpu-service/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
GPU service tests
|
||||
"""
|
||||
47
apps/gpu-service/tests/test_main.py
Normal file
47
apps/gpu-service/tests/test_main.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Test GPU service main application
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from gpu_service.main import app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
"""Create test client for GPU service"""
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def test_health_check(client):
|
||||
"""Test health check endpoint"""
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "healthy"
|
||||
assert data["service"] == "gpu-service"
|
||||
|
||||
|
||||
def test_gpu_status(client):
|
||||
"""Test GPU status endpoint"""
|
||||
response = client.get("/gpu/status")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "operational"
|
||||
assert data["service"] == "gpu-service"
|
||||
|
||||
|
||||
def test_get_consumer_gpu_profiles(client):
|
||||
"""Test get consumer GPU profiles endpoint"""
|
||||
response = client.get("/v1/marketplace/edge-gpu/profiles")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
# Check that at least one profile is returned
|
||||
assert len(data) > 0
|
||||
# Check that profile has required fields
|
||||
profile = data[0]
|
||||
assert "profile_id" in profile
|
||||
assert "name" in profile
|
||||
assert "architecture" in profile
|
||||
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "marketplace-service"
|
||||
version = "0.1.0"
|
||||
description = "AITBC Marketplace Service for GPU marketplace operations"
|
||||
description = "AITBC Marketplace Service for marketplace operations"
|
||||
authors = [
|
||||
{name = "AITBC Team", email = "team@aitbc.dev"}
|
||||
]
|
||||
@@ -14,6 +14,13 @@ dependencies = [
|
||||
"aitbc-core",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest>=7.4.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"httpx>=0.25.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -22,3 +29,6 @@ build-backend = "poetry.core.masonry.api"
|
||||
packages = [
|
||||
{ include = "marketplace_service", from = "src" }
|
||||
]
|
||||
|
||||
[tool.poetry.extras]
|
||||
test = ["pytest", "pytest-asyncio", "httpx"]
|
||||
|
||||
3
apps/marketplace-service/tests/__init__.py
Normal file
3
apps/marketplace-service/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Marketplace service tests
|
||||
"""
|
||||
56
apps/marketplace-service/tests/test_main.py
Normal file
56
apps/marketplace-service/tests/test_main.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
Test Marketplace service main application
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from marketplace_service.main import app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
"""Create test client for Marketplace service"""
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def test_health_check(client):
|
||||
"""Test health check endpoint"""
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "healthy"
|
||||
assert data["service"] == "marketplace-service"
|
||||
|
||||
|
||||
def test_marketplace_status(client):
|
||||
"""Test marketplace status endpoint"""
|
||||
response = client.get("/marketplace/status")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "operational"
|
||||
assert data["service"] == "marketplace-service"
|
||||
|
||||
|
||||
def test_get_marketplace_offers(client):
|
||||
"""Test get marketplace offers endpoint"""
|
||||
response = client.get("/v1/marketplace/offers")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_marketplace_bids(client):
|
||||
"""Test get marketplace bids endpoint"""
|
||||
response = client.get("/v1/marketplace/bids")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_marketplace_analytics(client):
|
||||
"""Test get marketplace analytics endpoint"""
|
||||
response = client.get("/v1/marketplace/analytics")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, dict)
|
||||
@@ -14,6 +14,13 @@ dependencies = [
|
||||
"aitbc-core",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest>=7.4.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"httpx>=0.25.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -22,3 +29,6 @@ build-backend = "poetry.core.masonry.api"
|
||||
packages = [
|
||||
{ include = "trading_service", from = "src" }
|
||||
]
|
||||
|
||||
[tool.poetry.extras]
|
||||
test = ["pytest", "pytest-asyncio", "httpx"]
|
||||
|
||||
3
apps/trading-service/tests/__init__.py
Normal file
3
apps/trading-service/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Trading service tests
|
||||
"""
|
||||
64
apps/trading-service/tests/test_main.py
Normal file
64
apps/trading-service/tests/test_main.py
Normal file
@@ -0,0 +1,64 @@
|
||||
"""
|
||||
Test Trading service main application
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from trading_service.main import app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
"""Create test client for Trading service"""
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def test_health_check(client):
|
||||
"""Test health check endpoint"""
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "healthy"
|
||||
assert data["service"] == "trading-service"
|
||||
|
||||
|
||||
def test_trading_status(client):
|
||||
"""Test trading status endpoint"""
|
||||
response = client.get("/trading/status")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "operational"
|
||||
assert data["service"] == "trading-service"
|
||||
|
||||
|
||||
def test_get_trade_requests(client):
|
||||
"""Test get trade requests endpoint"""
|
||||
response = client.get("/v1/trading/requests")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_trade_matches(client):
|
||||
"""Test get trade matches endpoint"""
|
||||
response = client.get("/v1/trading/matches")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_trade_agreements(client):
|
||||
"""Test get trade agreements endpoint"""
|
||||
response = client.get("/v1/trading/agreements")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_get_trading_analytics(client):
|
||||
"""Test get trading analytics endpoint"""
|
||||
response = client.get("/v1/trading/analytics")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, dict)
|
||||
Reference in New Issue
Block a user