refactor: clean up tests/ root — delete junk, sort into subdirs

Deleted (7 files):
- test_discovery.py, test_windsurf_integration.py (trivial assert True stubs)
- pytest_simple.ini (unused --collect-only config)
- conftest_path.py (duplicate of conftest.py path setup)
- conftest_fixtures.py, conftest_full.py (unused conftest variants)

Moved to integration/ (6 files):
- test_blockchain_final.py, test_blockchain_nodes.py, test_blockchain_simple.py
- test_basic_integration.py, test_integration_simple.py, test_working_integration.py

Moved to fixtures/:
- mock_blockchain_node.py

tests/ root now has only conftest.py and README.md.
This commit is contained in:
oib
2026-02-13 23:32:58 +01:00
parent d9481f2b92
commit fb4b9a2e49
13 changed files with 0 additions and 1005 deletions

View File

@@ -1,468 +0,0 @@
"""
Comprehensive test fixtures for AITBC testing
"""
import pytest
import asyncio
import json
from datetime import datetime, timedelta
from typing import Dict, Any, Generator
from unittest.mock import Mock, AsyncMock
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# Import all necessary modules
from apps.coordinator_api.src.app.main import app as coordinator_app
from apps.wallet_daemon.src.app.main import app as wallet_app
from apps.blockchain_node.src.aitbc_chain.node import BlockchainNode
@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture
def coordinator_client():
"""Create a test client for coordinator API"""
return TestClient(coordinator_app)
@pytest.fixture
def wallet_client():
"""Create a test client for wallet daemon"""
return TestClient(wallet_app)
@pytest.fixture
def blockchain_client():
"""Create a test client for blockchain node"""
node = BlockchainNode()
return TestClient(node.app)
@pytest.fixture
def marketplace_client():
"""Create a test client for marketplace"""
from apps.marketplace.src.app.main import app as marketplace_app
return TestClient(marketplace_app)
@pytest.fixture
def sample_tenant():
"""Create a sample tenant for testing"""
return {
"id": "tenant-123",
"name": "Test Tenant",
"created_at": datetime.utcnow(),
"status": "active"
}
@pytest.fixture
def sample_user():
"""Create a sample user for testing"""
return {
"id": "user-123",
"email": "test@example.com",
"tenant_id": "tenant-123",
"role": "user",
"created_at": datetime.utcnow()
}
@pytest.fixture
def sample_wallet_data():
"""Sample wallet creation data"""
return {
"name": "Test Wallet",
"type": "hd",
"currency": "AITBC"
}
@pytest.fixture
def sample_wallet():
"""Sample wallet object"""
return {
"id": "wallet-123",
"address": "0x1234567890abcdef1234567890abcdef12345678",
"user_id": "user-123",
"balance": "1000.0",
"status": "active",
"created_at": datetime.utcnow()
}
@pytest.fixture
def sample_job_data():
"""Sample job creation data"""
return {
"job_type": "ai_inference",
"parameters": {
"model": "gpt-4",
"prompt": "Test prompt",
"max_tokens": 100,
"temperature": 0.7
},
"priority": "normal",
"timeout": 300
}
@pytest.fixture
def sample_job():
"""Sample job object"""
return {
"id": "job-123",
"job_type": "ai_inference",
"status": "pending",
"tenant_id": "tenant-123",
"created_at": datetime.utcnow(),
"parameters": {
"model": "gpt-4",
"prompt": "Test prompt"
}
}
@pytest.fixture
def sample_transaction():
"""Sample transaction object"""
return {
"hash": "0x1234567890abcdef",
"from": "0xsender1234567890",
"to": "0xreceiver1234567890",
"value": "1000",
"gas": "21000",
"gas_price": "20",
"nonce": 1,
"status": "pending"
}
@pytest.fixture
def sample_block():
"""Sample block object"""
return {
"number": 100,
"hash": "0xblock1234567890",
"parent_hash": "0xparent0987654321",
"timestamp": datetime.utcnow(),
"transactions": [],
"validator": "0xvalidator123"
}
@pytest.fixture
def sample_account():
"""Sample account object"""
return {
"address": "0xaccount1234567890",
"balance": "1000000",
"nonce": 25,
"code_hash": "0xempty"
}
@pytest.fixture
def signed_receipt():
"""Sample signed receipt"""
return {
"job_id": "job-123",
"hash": "0xreceipt123456",
"signature": "sig789012345",
"miner_id": "miner-123",
"timestamp": datetime.utcnow().isoformat()
}
@pytest.fixture
def sample_tenant_quota():
"""Sample tenant quota"""
return {
"tenant_id": "tenant-123",
"jobs_per_day": 1000,
"jobs_per_month": 30000,
"max_concurrent": 50,
"storage_gb": 100
}
@pytest.fixture
def validator_address():
"""Sample validator address"""
return "0xvalidator1234567890abcdef"
@pytest.fixture
def miner_address():
"""Sample miner address"""
return "0xminer1234567890abcdef"
@pytest.fixture
def sample_transactions():
"""List of sample transactions"""
return [
{
"hash": "0xtx123",
"from": "0xaddr1",
"to": "0xaddr2",
"value": "100"
},
{
"hash": "0xtx456",
"from": "0xaddr3",
"to": "0xaddr4",
"value": "200"
}
]
@pytest.fixture
def sample_block(sample_transactions):
"""Sample block with transactions"""
return {
"number": 100,
"hash": "0xblockhash123",
"parent_hash": "0xparenthash456",
"transactions": sample_transactions,
"timestamp": datetime.utcnow(),
"validator": "0xvalidator123"
}
@pytest.fixture
def mock_database():
"""Mock database session"""
engine = create_engine("sqlite:///:memory:")
Session = sessionmaker(bind=engine)
session = Session()
yield session
session.close()
@pytest.fixture
def mock_redis():
"""Mock Redis client"""
from unittest.mock import Mock
redis_mock = Mock()
redis_mock.get.return_value = None
redis_mock.set.return_value = True
redis_mock.delete.return_value = 1
return redis_mock
@pytest.fixture
def mock_web3():
"""Mock Web3 instance"""
from unittest.mock import Mock
web3_mock = Mock()
web3_mock.eth.contract.return_value = Mock()
web3_mock.eth.get_balance.return_value = 1000000
web3_mock.eth.gas_price = 20
return web3_mock
@pytest.fixture
def browser():
"""Selenium WebDriver fixture for E2E tests"""
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(10)
yield driver
driver.quit()
@pytest.fixture
def mobile_browser():
"""Mobile browser fixture for responsive testing"""
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
mobile_emulation = {
"deviceMetrics": {"width": 375, "height": 667, "pixelRatio": 2.0},
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)"
}
options.add_experimental_option("mobileEmulation", mobile_emulation)
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(10)
yield driver
driver.quit()
@pytest.fixture
def base_url():
"""Base URL for E2E tests"""
return "http://localhost:8000"
@pytest.fixture
def mock_file_storage():
"""Mock file storage service"""
from unittest.mock import Mock
storage_mock = Mock()
storage_mock.upload.return_value = {"url": "http://example.com/file.txt"}
storage_mock.download.return_value = b"file content"
storage_mock.delete.return_value = True
return storage_mock
@pytest.fixture
def mock_email_service():
"""Mock email service"""
from unittest.mock import Mock
email_mock = Mock()
email_mock.send.return_value = {"message_id": "msg-123"}
email_mock.send_verification.return_value = {"token": "token-456"}
return email_mock
@pytest.fixture
def mock_notification_service():
"""Mock notification service"""
from unittest.mock import Mock
notification_mock = Mock()
notification_mock.send_push.return_value = True
notification_mock.send_webhook.return_value = {"status": "sent"}
return notification_mock
@pytest.fixture
def sample_api_key():
"""Sample API key"""
return {
"id": "key-123",
"key": "aitbc_test_key_1234567890",
"name": "Test API Key",
"permissions": ["read", "write"],
"created_at": datetime.utcnow()
}
@pytest.fixture
def sample_service_listing():
"""Sample marketplace service listing"""
return {
"id": "service-123",
"name": "AI Inference Service",
"description": "High-performance AI inference",
"provider_id": "provider-123",
"pricing": {
"per_token": 0.0001,
"per_minute": 0.01
},
"capabilities": ["text-generation", "image-generation"],
"status": "active"
}
@pytest.fixture
def sample_booking():
"""Sample booking object"""
return {
"id": "booking-123",
"service_id": "service-123",
"client_id": "client-123",
"status": "confirmed",
"start_time": datetime.utcnow() + timedelta(hours=1),
"end_time": datetime.utcnow() + timedelta(hours=2),
"total_cost": "10.0"
}
@pytest.fixture
def mock_blockchain_node():
"""Mock blockchain node for testing"""
from unittest.mock import Mock
node_mock = Mock()
node_mock.start.return_value = {"status": "running"}
node_mock.stop.return_value = {"status": "stopped"}
node_mock.get_block.return_value = {"number": 100, "hash": "0x123"}
node_mock.submit_transaction.return_value = {"hash": "0xtx456"}
return node_mock
@pytest.fixture
def sample_zk_proof():
"""Sample zero-knowledge proof"""
return {
"proof": "zk_proof_123456",
"public_inputs": ["x", "y"],
"verification_key": "vk_789012"
}
@pytest.fixture
def sample_confidential_data():
"""Sample confidential transaction data"""
return {
"encrypted_payload": "encrypted_data_123",
"commitment": "commitment_hash_456",
"nullifier": "nullifier_789",
"merkle_proof": {
"root": "root_hash",
"path": ["hash1", "hash2", "hash3"],
"indices": [0, 1, 0]
}
}
@pytest.fixture
def mock_ipfs():
"""Mock IPFS client"""
from unittest.mock import Mock
ipfs_mock = Mock()
ipfs_mock.add.return_value = {"Hash": "QmHash123"}
ipfs_mock.cat.return_value = b"IPFS content"
ipfs_mock.pin.return_value = {"Pins": ["QmHash123"]}
return ipfs_mock
@pytest.fixture(autouse=True)
def cleanup_mocks():
"""Cleanup after each test"""
yield
# Add any cleanup code here
pass
# Performance testing fixtures
@pytest.fixture
def performance_metrics():
"""Collect performance metrics during test"""
import time
start_time = time.time()
yield {"start": start_time}
end_time = time.time()
return {"duration": end_time - start_time}
# Load testing fixtures
@pytest.fixture
def load_test_config():
"""Configuration for load testing"""
return {
"concurrent_users": 100,
"ramp_up_time": 30,
"test_duration": 300,
"target_rps": 50
}

View File

@@ -1,473 +0,0 @@
"""
Shared test configuration and fixtures for AITBC
"""
import asyncio
import pytest
import json
import tempfile
from datetime import datetime, timedelta
from typing import Dict, Any, Generator, AsyncGenerator
from unittest.mock import Mock, AsyncMock
from sqlalchemy import create_engine, event
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.pool import StaticPool
from fastapi.testclient import TestClient
import redis
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
# Import AITBC modules
from apps.coordinator_api.src.app.main import app as coordinator_app
from apps.coordinator_api.src.app.database import get_db
from apps.coordinator_api.src.app.models import Base
from apps.coordinator_api.src.app.models.multitenant import Tenant, TenantUser, TenantQuota
from apps.wallet_daemon.src.app.main import app as wallet_app
from packages.py.aitbc_crypto import sign_receipt, verify_receipt
from packages.py.aitbc_sdk import AITBCClient
@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture(scope="session")
def test_config():
"""Test configuration settings."""
return {
"database_url": "sqlite:///:memory:",
"redis_url": "redis://localhost:6379/1", # Use test DB
"test_tenant_id": "test-tenant-123",
"test_user_id": "test-user-456",
"test_api_key": "test-api-key-789",
"coordinator_url": "http://localhost:8001",
"wallet_url": "http://localhost:8002",
"blockchain_url": "http://localhost:8545",
}
@pytest.fixture(scope="session")
def test_engine(test_config):
"""Create a test database engine."""
engine = create_engine(
test_config["database_url"],
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
Base.metadata.create_all(bind=engine)
yield engine
Base.metadata.drop_all(bind=engine)
@pytest.fixture
def db_session(test_engine) -> Generator[Session, None, None]:
"""Create a database session for testing."""
connection = test_engine.connect()
transaction = connection.begin()
session = sessionmaker(autocommit=False, autoflush=False, bind=connection)()
# Begin a nested transaction
nested = connection.begin_nested()
@event.listens_for(session, "after_transaction_end")
def end_savepoint(session, transaction):
"""Rollback to the savepoint after each test."""
nonlocal nested
if not nested.is_active:
nested = connection.begin_nested()
yield session
# Rollback all changes
session.close()
transaction.rollback()
connection.close()
@pytest.fixture
def test_redis():
"""Create a test Redis client."""
client = redis.Redis.from_url("redis://localhost:6379/1", decode_responses=True)
# Clear test database
client.flushdb()
yield client
client.flushdb()
@pytest.fixture
def coordinator_client(db_session):
"""Create a test client for the coordinator API."""
def override_get_db():
yield db_session
coordinator_app.dependency_overrides[get_db] = override_get_db
with TestClient(coordinator_app) as client:
yield client
coordinator_app.dependency_overrides.clear()
@pytest.fixture
def wallet_client():
"""Create a test client for the wallet daemon."""
with TestClient(wallet_app) as client:
yield client
@pytest.fixture
def sample_tenant(db_session):
"""Create a sample tenant for testing."""
tenant = Tenant(
id="test-tenant-123",
name="Test Tenant",
status="active",
created_at=datetime.utcnow(),
updated_at=datetime.utcnow(),
)
db_session.add(tenant)
db_session.commit()
return tenant
@pytest.fixture
def sample_tenant_user(db_session, sample_tenant):
"""Create a sample tenant user for testing."""
user = TenantUser(
tenant_id=sample_tenant.id,
user_id="test-user-456",
role="admin",
created_at=datetime.utcnow(),
)
db_session.add(user)
db_session.commit()
return user
@pytest.fixture
def sample_tenant_quota(db_session, sample_tenant):
"""Create sample tenant quota for testing."""
quota = TenantQuota(
tenant_id=sample_tenant.id,
resource_type="api_calls",
limit=10000,
used=0,
period="monthly",
created_at=datetime.utcnow(),
updated_at=datetime.utcnow(),
)
db_session.add(quota)
db_session.commit()
return quota
@pytest.fixture
def sample_job_data():
"""Sample job data for testing."""
return {
"job_type": "ai_inference",
"parameters": {
"model": "gpt-3.5-turbo",
"prompt": "Test prompt",
"max_tokens": 100,
},
"requirements": {
"gpu_memory": "8GB",
"compute_time": 30,
},
}
@pytest.fixture
def sample_receipt_data():
"""Sample receipt data for testing."""
return {
"job_id": "test-job-123",
"miner_id": "test-miner-456",
"coordinator_id": "test-coordinator-789",
"timestamp": datetime.utcnow().isoformat(),
"result": {
"output": "Test output",
"confidence": 0.95,
"tokens_used": 50,
},
"signature": "test-signature",
}
@pytest.fixture
def test_keypair():
"""Generate a test Ed25519 keypair for signing."""
private_key = ed25519.Ed25519PrivateKey.generate()
public_key = private_key.public_key()
return private_key, public_key
@pytest.fixture
def signed_receipt(sample_receipt_data, test_keypair):
"""Create a signed receipt for testing."""
private_key, public_key = test_keypair
# Serialize receipt without signature
receipt_copy = sample_receipt_data.copy()
receipt_copy.pop("signature", None)
receipt_json = json.dumps(receipt_copy, sort_keys=True, separators=(',', ':'))
# Sign the receipt
signature = private_key.sign(receipt_json.encode())
# Add signature to receipt
receipt_copy["signature"] = signature.hex()
receipt_copy["public_key"] = public_key.public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw
).hex()
return receipt_copy
@pytest.fixture
def aitbc_client(test_config):
"""Create an AITBC client for testing."""
return AITBCClient(
base_url=test_config["coordinator_url"],
api_key=test_config["test_api_key"],
)
@pytest.fixture
def mock_miner_service():
"""Mock miner service for testing."""
service = AsyncMock()
service.register_miner = AsyncMock(return_value={"miner_id": "test-miner-456"})
service.heartbeat = AsyncMock(return_value={"status": "active"})
service.fetch_jobs = AsyncMock(return_value=[])
service.submit_result = AsyncMock(return_value={"job_id": "test-job-123"})
return service
@pytest.fixture
def mock_blockchain_node():
"""Mock blockchain node for testing."""
node = AsyncMock()
node.get_block = AsyncMock(return_value={"number": 100, "hash": "0x123"})
node.get_transaction = AsyncMock(return_value={"hash": "0x456", "status": "confirmed"})
node.submit_transaction = AsyncMock(return_value={"hash": "0x789", "status": "pending"})
node.subscribe_blocks = AsyncMock()
node.subscribe_transactions = AsyncMock()
return node
@pytest.fixture
def sample_gpu_service():
"""Sample GPU service definition."""
return {
"id": "llm-inference",
"name": "LLM Inference Service",
"category": "ai_ml",
"description": "Large language model inference",
"requirements": {
"gpu_memory": "16GB",
"cuda_version": "11.8",
"driver_version": "520.61.05",
},
"pricing": {
"per_hour": 0.50,
"per_token": 0.0001,
},
"capabilities": [
"text-generation",
"chat-completion",
"embedding",
],
}
@pytest.fixture
def sample_cross_chain_data():
"""Sample cross-chain settlement data."""
return {
"source_chain": "ethereum",
"target_chain": "polygon",
"source_tx_hash": "0xabcdef123456",
"target_address": "0x1234567890ab",
"amount": "1000",
"token": "USDC",
"bridge_id": "layerzero",
"nonce": 12345,
}
@pytest.fixture
def confidential_transaction_data():
"""Sample confidential transaction data."""
return {
"sender": "0x1234567890abcdef",
"receiver": "0xfedcba0987654321",
"amount": 1000,
"asset": "AITBC",
"confidential": True,
"ciphertext": "encrypted_data_here",
"viewing_key": "viewing_key_here",
"proof": "zk_proof_here",
}
@pytest.fixture
def mock_hsm_client():
"""Mock HSM client for testing."""
client = AsyncMock()
client.generate_key = AsyncMock(return_value={"key_id": "test-key-123"})
client.sign_data = AsyncMock(return_value={"signature": "test-signature"})
client.verify_signature = AsyncMock(return_value={"valid": True})
client.encrypt_data = AsyncMock(return_value={"ciphertext": "encrypted_data"})
client.decrypt_data = AsyncMock(return_value={"plaintext": "decrypted_data"})
return client
@pytest.fixture
def temp_directory():
"""Create a temporary directory for testing."""
with tempfile.TemporaryDirectory() as temp_dir:
yield temp_dir
@pytest.fixture
def sample_config_file(temp_directory):
"""Create a sample configuration file."""
config = {
"coordinator": {
"host": "localhost",
"port": 8001,
"database_url": "sqlite:///test.db",
},
"blockchain": {
"host": "localhost",
"port": 8545,
"chain_id": 1337,
},
"wallet": {
"host": "localhost",
"port": 8002,
"keystore_path": temp_directory,
},
}
config_path = temp_directory / "config.json"
with open(config_path, "w") as f:
json.dump(config, f)
return config_path
# Async fixtures
@pytest.fixture
async def async_aitbc_client(test_config):
"""Create an async AITBC client for testing."""
client = AITBCClient(
base_url=test_config["coordinator_url"],
api_key=test_config["test_api_key"],
)
yield client
await client.close()
@pytest.fixture
async def websocket_client():
"""Create a WebSocket client for testing."""
import websockets
uri = "ws://localhost:8546"
async with websockets.connect(uri) as websocket:
yield websocket
# Performance testing fixtures
@pytest.fixture
def performance_config():
"""Configuration for performance tests."""
return {
"concurrent_users": 100,
"ramp_up_time": 30, # seconds
"test_duration": 300, # seconds
"think_time": 1, # seconds
}
# Security testing fixtures
@pytest.fixture
def malicious_payloads():
"""Collection of malicious payloads for security testing."""
return {
"sql_injection": "'; DROP TABLE jobs; --",
"xss": "<script>alert('xss')</script>",
"path_traversal": "../../../etc/passwd",
"overflow": "A" * 10000,
"unicode": "\ufeff\u200b\u200c\u200d",
}
@pytest.fixture
def rate_limit_config():
"""Rate limiting configuration for testing."""
return {
"requests_per_minute": 60,
"burst_size": 10,
"window_size": 60,
}
# Helper functions
def create_test_job(job_id: str = None, **kwargs) -> Dict[str, Any]:
"""Create a test job with default values."""
return {
"id": job_id or f"test-job-{datetime.utcnow().timestamp()}",
"status": "pending",
"created_at": datetime.utcnow().isoformat(),
"updated_at": datetime.utcnow().isoformat(),
"job_type": kwargs.get("job_type", "ai_inference"),
"parameters": kwargs.get("parameters", {}),
"requirements": kwargs.get("requirements", {}),
"tenant_id": kwargs.get("tenant_id", "test-tenant-123"),
}
def create_test_receipt(job_id: str = None, **kwargs) -> Dict[str, Any]:
"""Create a test receipt with default values."""
return {
"id": f"receipt-{job_id or 'test'}",
"job_id": job_id or "test-job-123",
"miner_id": kwargs.get("miner_id", "test-miner-456"),
"coordinator_id": kwargs.get("coordinator_id", "test-coordinator-789"),
"timestamp": kwargs.get("timestamp", datetime.utcnow().isoformat()),
"result": kwargs.get("result", {"output": "test"}),
"signature": kwargs.get("signature", "test-signature"),
}
def assert_valid_receipt(receipt: Dict[str, Any]):
"""Assert that a receipt has valid structure."""
required_fields = ["id", "job_id", "miner_id", "coordinator_id", "timestamp", "result", "signature"]
for field in required_fields:
assert field in receipt, f"Receipt missing required field: {field}"
# Validate timestamp format
assert isinstance(receipt["timestamp"], str), "Timestamp should be a string"
# Validate result structure
assert isinstance(receipt["result"], dict), "Result should be a dictionary"
# Marks for different test types
pytest.mark.unit = pytest.mark.unit
pytest.mark.integration = pytest.mark.integration
pytest.mark.e2e = pytest.mark.e2e
pytest.mark.performance = pytest.mark.performance
pytest.mark.security = pytest.mark.security
pytest.mark.slow = pytest.mark.slow

View File

@@ -1,19 +0,0 @@
"""Configure Python path for pytest discovery"""
import sys
from pathlib import Path
# Add project root to sys.path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
# Add package source directories
sys.path.insert(0, str(project_root / "packages" / "py" / "aitbc-core" / "src"))
sys.path.insert(0, str(project_root / "packages" / "py" / "aitbc-crypto" / "src"))
sys.path.insert(0, str(project_root / "packages" / "py" / "aitbc-p2p" / "src"))
sys.path.insert(0, str(project_root / "packages" / "py" / "aitbc-sdk" / "src"))
# Add app source directories
sys.path.insert(0, str(project_root / "apps" / "coordinator-api" / "src"))
sys.path.insert(0, str(project_root / "apps" / "wallet-daemon" / "src"))
sys.path.insert(0, str(project_root / "apps" / "blockchain-node" / "src"))

View File

@@ -1,10 +0,0 @@
[tool:pytest]
# Simple pytest configuration for test discovery
# Test discovery patterns
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_*
# Minimal options for discovery
addopts = --collect-only

View File

@@ -1,9 +0,0 @@
"""Test file to verify pytest discovery is working"""
def test_pytest_discovery():
"""Simple test to verify pytest can discover test files"""
assert True
def test_another_discovery_test():
"""Another test to verify multiple tests are discovered"""
assert 1 + 1 == 2

View File

@@ -1,26 +0,0 @@
"""
Test file to verify Windsorf test integration is working
"""
import pytest
def test_pytest_discovery():
"""Simple test to verify pytest can discover this file"""
assert True
def test_windsurf_integration():
"""Test that Windsurf test runner is working"""
assert "windsurf" in "windsurf test integration"
@pytest.mark.parametrize("input,expected", [
(1, 2),
(2, 4),
(3, 6),
])
def test_multiplication(input, expected):
"""Parameterized test example"""
result = input * 2
assert result == expected