73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
"""
|
||
pytest 全局配置
|
||
=============================================================
|
||
|
||
P1 阶段:
|
||
- flask_app fixture:最小 Flask 应用(供 jsonify 等需应用上下文的功能测试)
|
||
- 项目根目录加入 sys.path
|
||
|
||
P8 阶段补充(测试完善):
|
||
- app fixture:create_app() + 测试库 DATABASE_URL 覆盖
|
||
- db fixture:事务内建表/清库
|
||
- client fixture:Flask test_client
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
|
||
import pytest
|
||
from flask import Flask
|
||
|
||
# 项目根目录加入 sys.path(tests/ 已有 __init__.py 时 pytest 通常自动处理,
|
||
# 此处显式补充,兼容从任意目录启动 pytest 的场景)
|
||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
if ROOT not in sys.path:
|
||
sys.path.insert(0, ROOT)
|
||
|
||
|
||
@pytest.fixture
|
||
def flask_app():
|
||
"""
|
||
最小 Flask 应用实例(无数据库/中间件,仅提供应用上下文)。
|
||
|
||
配置项说明:
|
||
- SECRET_KEY: FlaskForm CSRF 校验需要
|
||
- WTF_CSRF_ENABLED=False: 单元测试关闭 CSRF
|
||
"""
|
||
app = Flask(__name__)
|
||
app.config['SECRET_KEY'] = 'test-secret-key'
|
||
app.config['WTF_CSRF_ENABLED'] = False
|
||
return app
|
||
|
||
|
||
@pytest.fixture
|
||
def app():
|
||
"""
|
||
sqlite 内存库应用实例:供 Repository 单测使用。
|
||
|
||
- StaticPool 保证所有连接共享同一内存库(多线程/多次 init 下数据一致)
|
||
- 每测试独立建表/drop(query.update / bulk_insert 与 identity map 冲突,
|
||
不宜采用事务回滚隔离)
|
||
- 测试内数据构造需显式 db.session.commit()
|
||
"""
|
||
from sqlalchemy.pool import StaticPool
|
||
|
||
from src.core.database import db
|
||
import src.models_registry # noqa: F401 (注册全部表)
|
||
|
||
flask_app = Flask(__name__)
|
||
flask_app.config.update(
|
||
TESTING=True,
|
||
SECRET_KEY='test-secret-key',
|
||
WTF_CSRF_ENABLED=False,
|
||
SQLALCHEMY_DATABASE_URI='sqlite://',
|
||
SQLALCHEMY_TRACK_MODIFICATIONS=False,
|
||
SQLALCHEMY_ENGINE_OPTIONS={'poolclass': StaticPool},
|
||
)
|
||
db.init_app(flask_app)
|
||
with flask_app.app_context():
|
||
db.create_all()
|
||
yield flask_app
|
||
db.session.remove()
|
||
db.drop_all()
|