-
Notifications
You must be signed in to change notification settings - Fork 0
Testing Guide
garotm edited this page Nov 29, 2024
·
1 revision
This guide outlines the testing practices and standards for the fleXRP project. We use pytest as our primary testing framework and aim for comprehensive test coverage across all components.
tests/
├── unit/
│ ├── api/
│ ├── core/
│ └── services/
├── integration/
│ ├── api/
│ └── services/
├── e2e/
├── fixtures/
└── conftest.py
Test individual components in isolation.
# tests/unit/services/test_payment.py
import pytest
from src.services.payment import PaymentService
def test_payment_creation():
"""Test creating a new payment."""
service = PaymentService()
payment = service.create_payment(amount=100.00)
assert payment.amount == 100.00
assert payment.status == "pending"
def test_payment_validation():
"""Test payment validation."""
service = PaymentService()
with pytest.raises(ValueError):
service.create_payment(amount=-100.00)Test component interactions.
# tests/integration/test_payment_flow.py
import pytest
from src.services import PaymentService
from src.services import WalletService
@pytest.mark.integration
def test_payment_processing():
"""Test complete payment processing flow."""
payment_service = PaymentService()
wallet_service = WalletService()
payment = payment_service.create_payment(amount=100.00)
result = wallet_service.process_payment(payment)
assert result.status == "completed"
assert wallet_service.get_balance() == 900.00Test complete user scenarios.
# tests/e2e/test_payment_api.py
import pytest
from src.app import create_app
@pytest.mark.e2e
def test_payment_api_flow():
"""Test complete payment API flow."""
app = create_app('testing')
client = app.test_client()
# Create payment
response = client.post('/api/payments', json={
'amount': 100.00,
'currency': 'XRP'
})
assert response.status_code == 201
payment_id = response.json['id']
# Check status
response = client.get(f'/api/payments/{payment_id}')
assert response.status_code == 200
assert response.json['status'] == "pending"# tests/conftest.py
import pytest
from src.app import create_app
from src.db import db
@pytest.fixture
def app():
"""Create test app."""
app = create_app('testing')
return app
@pytest.fixture
def client(app):
"""Create test client."""
return app.test_client()
@pytest.fixture
def db_session():
"""Provide test database session."""
db.create_all()
yield db.session
db.session.remove()
db.drop_all()# tests/fixtures/mocks.py
import pytest
from unittest.mock import Mock
@pytest.fixture
def mock_xrpl_client():
"""Mock XRPL client."""
client = Mock()
client.get_balance.return_value = 1000.00
return client
@pytest.fixture
def mock_payment_response():
"""Mock payment response."""
return {
'id': 'test_payment_id',
'status': 'completed',
'amount': 100.00
}# Run all tests
pytest
# Run specific test file
pytest tests/unit/test_payment.py
# Run specific test
pytest tests/unit/test_payment.py::test_payment_creation
# Run marked tests
pytest -m integration# Run tests with coverage
pytest --cov=src tests/
# Generate HTML coverage report
pytest --cov=src --cov-report=html tests/# pytest.ini
[pytest]
markers =
unit: Unit tests
integration: Integration tests
e2e: End-to-end tests
slow: Slow running tests
# Using markers in tests
@pytest.mark.slow
def test_long_running_process():
"""Test that takes longer to execute."""
pass
@pytest.mark.integration
def test_database_integration():
"""Test database operations."""
passfrom unittest.mock import Mock, patch
def test_payment_processing():
"""Test payment processing with mocked dependencies."""
with patch('src.services.xrpl_client') as mock_client:
mock_client.send_payment.return_value = {
'status': 'success',
'tx_hash': 'abc123'
}
service = PaymentService(client=mock_client)
result = service.process_payment(amount=100.00)
assert result.status == 'completed'
mock_client.send_payment.assert_called_once()import pytest
import asyncio
@pytest.mark.asyncio
async def test_async_payment():
"""Test async payment processing."""
service = AsyncPaymentService()
result = await service.process_payment(amount=100.00)
assert result.status == 'completed'
@pytest.fixture
async def async_client():
"""Async client fixture."""
client = AsyncClient()
await client.connect()
yield client
await client.disconnect()# tests/fixtures/data.py
import json
import pytest
@pytest.fixture
def sample_payment_data():
"""Load sample payment data."""
with open('tests/fixtures/payment_data.json') as f:
return json.load(f)
def test_payment_creation(sample_payment_data):
"""Test payment creation with sample data."""
service = PaymentService()
payment = service.create_payment(**sample_payment_data)
assert payment.amount == sample_payment_data['amount']import pytest
from locust import HttpUser, task, between
class PaymentUser(HttpUser):
wait_time = between(1, 3)
@task
def create_payment(self):
"""Test payment creation under load."""
self.client.post("/api/payments", json={
"amount": 100.00,
"currency": "XRP"
})# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run tests
run: |
pytest --cov=src tests/- Write tests before code (TDD)
- Keep tests simple and focused
- Use meaningful test names
- Don't test implementation details
- Maintain test independence
- Clean up test data
- Use appropriate assertions
- Document complex test scenarios
def test_should_succeed():
"""Test successful scenario."""
# Arrange
service = PaymentService()
# Act
result = service.process_payment(100.00)
# Assert
assert result.status == "completed"
def test_should_fail():
"""Test failure scenario."""
# Arrange
service = PaymentService()
# Act & Assert
with pytest.raises(ValueError):
service.process_payment(-100.00)This documentation is maintained by the fleXRP team.