287 lines
7.5 KiB
Python
287 lines
7.5 KiB
Python
"""
|
||
Pytest配置文件
|
||
提供共享的测试fixtures和配置
|
||
"""
|
||
import pytest
|
||
from unittest.mock import Mock
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from app.models.risk_detection import DetectionRule, RiskLevel
|
||
from app.services.risk_detection.engine.rule_engine import RuleEngine
|
||
from app.services.risk_detection.engine.dependency_resolver import DependencyResolver
|
||
from app.services.risk_detection.engine.execution_plan import ExecutionPlanner
|
||
from app.services.risk_detection.engine.result_processor import ResultProcessor
|
||
|
||
|
||
@pytest.fixture
|
||
def mock_db_session():
|
||
"""模拟数据库会话"""
|
||
session = Mock(spec=AsyncSession)
|
||
return session
|
||
|
||
|
||
@pytest.fixture
|
||
def sample_detection_rules():
|
||
"""模拟检测规则列表"""
|
||
rules = []
|
||
|
||
# 规则1:收入完整性检测
|
||
rule1 = Mock(spec=DetectionRule)
|
||
rule1.rule_id = "rule_revenue_integrity"
|
||
rule1.algorithm_code = "REVENUE_INTEGRITY_CHECK"
|
||
rule1.rule_name = "收入完整性检测"
|
||
rule1.parameters = {
|
||
"comparison_type": "monthly",
|
||
"dependencies": []
|
||
}
|
||
rule1.is_enabled = True
|
||
rules.append(rule1)
|
||
|
||
# 规则2:私户收款检测
|
||
rule2 = Mock(spec=DetectionRule)
|
||
rule2.rule_id = "rule_private_account"
|
||
rule2.algorithm_code = "PRIVATE_ACCOUNT_DETECTION"
|
||
rule2.rule_name = "私户收款检测"
|
||
rule2.parameters = {
|
||
"threshold_amount": 10000,
|
||
"dependencies": ["rule_revenue_integrity"]
|
||
}
|
||
rule2.is_enabled = True
|
||
rules.append(rule2)
|
||
|
||
# 规则3:发票虚开检测
|
||
rule3 = Mock(spec=DetectionRule)
|
||
rule3.rule_id = "rule_invoice_fraud"
|
||
rule3.algorithm_code = "INVOICE_FRAUD_DETECTION"
|
||
rule3.rule_name = "发票虚开检测"
|
||
rule3.parameters = {
|
||
"suspicious_rate_threshold": 0.3,
|
||
"dependencies": ["rule_revenue_integrity"]
|
||
}
|
||
rule3.is_enabled = True
|
||
rules.append(rule3)
|
||
|
||
# 规则4:费用异常检测
|
||
rule4 = Mock(spec=DetectionRule)
|
||
rule4.rule_id = "rule_expense_anomaly"
|
||
rule4.algorithm_code = "EXPENSE_ANOMALY_DETECTION"
|
||
rule4.rule_name = "费用异常检测"
|
||
rule4.parameters = {
|
||
"anomaly_threshold": 2.0,
|
||
"dependencies": []
|
||
}
|
||
rule4.is_enabled = True
|
||
rules.append(rule4)
|
||
|
||
# 规则5:税率错误检测
|
||
rule5 = Mock(spec=DetectionRule)
|
||
rule5.rule_id = "rule_tax_rate"
|
||
rule5.algorithm_code = "TAX_RATE_CHECK"
|
||
rule5.rule_name = "税率错误检测"
|
||
rule5.parameters = {
|
||
"dependencies": []
|
||
}
|
||
rule5.is_enabled = True
|
||
rules.append(rule5)
|
||
|
||
# 规则6:综合风险评估
|
||
rule6 = Mock(spec=DetectionRule)
|
||
rule6.rule_id = "rule_tax_risk_assessment"
|
||
rule6.algorithm_code = "TAX_RISK_ASSESSMENT"
|
||
rule6.rule_name = "综合风险评估"
|
||
rule6.parameters = {
|
||
"dependencies": [
|
||
"rule_revenue_integrity",
|
||
"rule_private_account",
|
||
"rule_invoice_fraud",
|
||
"rule_expense_anomaly",
|
||
"rule_tax_rate"
|
||
]
|
||
}
|
||
rule6.is_enabled = True
|
||
rules.append(rule6)
|
||
|
||
return rules
|
||
|
||
|
||
@pytest.fixture
|
||
def rule_engine(mock_db_session):
|
||
"""规则引擎实例"""
|
||
engine = RuleEngine(db_session=mock_db_session)
|
||
return engine
|
||
|
||
|
||
@pytest.fixture
|
||
def dependency_resolver():
|
||
"""依赖解析器实例"""
|
||
return DependencyResolver()
|
||
|
||
|
||
@pytest.fixture
|
||
def execution_planner():
|
||
"""执行计划器实例"""
|
||
return ExecutionPlanner()
|
||
|
||
|
||
@pytest.fixture
|
||
def result_processor():
|
||
"""结果处理器实例"""
|
||
return ResultProcessor()
|
||
|
||
|
||
@pytest.fixture
|
||
def mock_detection_results():
|
||
"""模拟检测结果列表"""
|
||
from app.services.risk_detection.engine.result_processor import DetectionResult
|
||
|
||
results = []
|
||
|
||
# 结果1:低风险
|
||
result1 = DetectionResult(
|
||
task_id="task_1",
|
||
rule_id="rule_1",
|
||
entity_id="entity_1",
|
||
entity_type="streamer",
|
||
risk_level=RiskLevel.LOW,
|
||
risk_score=25.0,
|
||
description="检测到轻微风险",
|
||
suggestion="继续保持合规状态"
|
||
)
|
||
results.append(result1)
|
||
|
||
# 结果2:中风险
|
||
result2 = DetectionResult(
|
||
task_id="task_1",
|
||
rule_id="rule_2",
|
||
entity_id="entity_1",
|
||
entity_type="streamer",
|
||
risk_level=RiskLevel.MEDIUM,
|
||
risk_score=55.0,
|
||
description="检测到中等风险",
|
||
suggestion="需要关注并及时处理"
|
||
)
|
||
results.append(result2)
|
||
|
||
# 结果3:高风险
|
||
result3 = DetectionResult(
|
||
task_id="task_1",
|
||
rule_id="rule_3",
|
||
entity_id="entity_1",
|
||
entity_type="streamer",
|
||
risk_level=RiskLevel.HIGH,
|
||
risk_score=80.0,
|
||
description="检测到高风险",
|
||
suggestion="建议立即采取整改措施"
|
||
)
|
||
results.append(result3)
|
||
|
||
return results
|
||
|
||
|
||
@pytest.fixture
|
||
def sample_entity_info():
|
||
"""模拟实体信息"""
|
||
return {
|
||
"entity_id": "streamer_001",
|
||
"entity_type": "streamer",
|
||
"entity_name": "测试主播",
|
||
"period": "2024-01",
|
||
"taxpayer_id": "12345678901234567890",
|
||
"unified_social_credit_code": "91310000MA1KXXXXXX",
|
||
"id_card_no": "110101199001011234"
|
||
}
|
||
|
||
|
||
@pytest.fixture
|
||
def sample_recharge_data():
|
||
"""模拟充值数据"""
|
||
return {
|
||
"total": 100000.00,
|
||
"count": 50,
|
||
"top_records": [
|
||
{
|
||
"recharge_id": "R001",
|
||
"user_name": "用户A",
|
||
"amount": 5000.0,
|
||
"time": "2024-01-15 10:30:00",
|
||
"payment_method": "支付宝"
|
||
},
|
||
{
|
||
"recharge_id": "R002",
|
||
"user_name": "用户B",
|
||
"amount": 3000.0,
|
||
"time": "2024-01-16 14:20:00",
|
||
"payment_method": "微信"
|
||
}
|
||
]
|
||
}
|
||
|
||
|
||
@pytest.fixture
|
||
def sample_declaration_data():
|
||
"""模拟申报数据"""
|
||
return {
|
||
"total": 80000.00,
|
||
"count": 3,
|
||
"records": [
|
||
{
|
||
"declaration_id": "D001",
|
||
"taxpayer_name": "测试主播",
|
||
"tax_period": "2024-01",
|
||
"sales_revenue": 50000.0,
|
||
"declaration_date": "2024-02-15"
|
||
},
|
||
{
|
||
"declaration_id": "D002",
|
||
"taxpayer_name": "测试主播",
|
||
"tax_period": "2024-01",
|
||
"sales_revenue": 30000.0,
|
||
"declaration_date": "2024-02-15"
|
||
}
|
||
]
|
||
}
|
||
|
||
|
||
@pytest.fixture
|
||
def sample_contract_data():
|
||
"""模拟合同数据"""
|
||
return {
|
||
"streamer_ratio": 70.0,
|
||
"platform_ratio": 30.0,
|
||
"contract_start_date": "2024-01-01",
|
||
"contract_end_date": "2024-12-31",
|
||
"contract_status": "active"
|
||
}
|
||
|
||
|
||
@pytest.fixture
|
||
def sample_risk_thresholds():
|
||
"""模拟风险阈值配置"""
|
||
return {
|
||
"critical_rate_threshold": 50.0,
|
||
"critical_amount_threshold": 100000.0,
|
||
"high_rate_threshold": 30.0,
|
||
"high_amount_threshold": 50000.0,
|
||
"medium_rate_threshold": 10.0,
|
||
"medium_amount_threshold": 10000.0,
|
||
"low_rate_threshold": 5.0,
|
||
"low_amount_threshold": 5000.0,
|
||
}
|
||
|
||
|
||
# 配置pytest-asyncio
|
||
def pytest_configure(config):
|
||
"""配置pytest"""
|
||
config.addinivalue_line(
|
||
"markers", "asyncio: mark test as async"
|
||
)
|
||
|
||
|
||
# 自定义标记
|
||
def pytest_collection_modifyitems(config, items):
|
||
"""修改收集的测试项目"""
|
||
for item in items:
|
||
# 为所有异步测试添加asyncio标记
|
||
if asyncio.iscoroutinefunction(getattr(item.function, "__code__", None)):
|
||
item.add_marker(pytest.mark.asyncio)
|