python pytest单元测试

前言:py web开发使用,简单的记录下python pytest单元测试的使用

pytest.fixture

@pytest.fixture用于定义测试用例中可复用的资源或环境设置。

关于fixture作用范围

Scope 描述
function 默认值。每次调用测试函数时都会创建和销毁资源。适合需要独立环境的测试场景。
class 在整个测试类中共享资源。所有属于该类的测试函数将共享同一个资源实例。
module 在整个模块中共享资源。模块内的所有测试函数将共享同一个资源实例,指一个.py文件,通常以test_*.py*_test.py命名
session 在整个测试会话中共享资源。所有测试文件中的所有测试函数将共享同一个资源实例。

模块与测试类的主要区别

特性 模块 (Module) 测试类 (Test Class)
组织方式 组织在 .py 文件中 组织在类中
作用范围 整个文件 类内部
包含内容 测试函数、测试类、fixture 测试方法、类级别的 fixture
执行顺序 按文件中定义顺序 按类中定义顺序
资源管理 支持模块级别的 fixture 支持类级别的 fixture
适用场景 简单的测试场景 需要逻辑分组或共享资源的复杂场景

实际使用

在实际环境中,我们一般使用@pytest.fixture将可复用的资源进行修饰,比如数据库资源句柄,事件循环等

如下图所示,我们通过scope="module"将其设置作用域为module,那么之后在这个测试用例中相关的数据库句柄始终使用的都是该db,同样的事件循环event也是如此。

@pytest.fixture(scope="module")
def db():
    """模拟数据库会话"""
    db_user = os.getenv('POSTGRES_USER')
    db_pass = os.getenv('POSTGRES_PASSWORD')
    db_host = os.getenv('POSTGRES_HOST')
    db_port = os.getenv('POSTGRES_PORT')
    db_name = os.getenv('POSTGRES_DB')
    # 构建数据库连接字符串
    database_url = f'postgresql://{db_user}:{db_pass}@{db_host}:{db_port}/{db_name}'
    engine = create_engine(database_url, echo=False, pool_size=50, max_overflow=100)
    SessionLocal = sessionmaker(autoflush=True, bind=engine)
    session = SessionLocal()
    try:
        yield session
    finally:
        session.close()


@pytest.fixture(scope="class")
def event_loop():
    """Create an instance of the default event loop for each test case."""
    import asyncio
    loop = asyncio.get_event_loop_policy().new_event_loop()
    yield loop
    loop.close()


@pytest.mark.asyncio
async def test_ingress_data(db):
    # 查询ingress数据
    ingress = db.query(Ingress).filter(
        Ingress.tl_domain == 'gztyre.com',
        Ingress.protocol.in_(['http', 'https']),
    ).all()

    # 打印数据测试
    for info in ingress:
        print(info.url, info.nuclei)

posted @ 2025-02-18 15:25  zpchcbd  阅读(50)  评论(0)    收藏  举报