You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对数据库连接函数编写测试用例?Flask场景问题解析

Flask数据库连接函数的测试方案与上下文问题解决

一、测试思路验证

你的思路完全正确:单元测试通过Mock隔离外部数据库依赖,仅验证函数逻辑;集成测试则搭建真实测试数据库,验证完整连接与交互流程。

二、单元测试示例(Mock pymssql.connect)

使用unittest.mock模拟数据库连接,重点验证环境变量读取、连接参数传递、自动提交设置及连接关闭逻辑:

import unittest
from unittest.mock import patch, MagicMock
import os
from your_module import db_connection  # 替换为实际模块路径

class TestDbConnection(unittest.TestCase):
    def setUp(self):
        # 预置测试环境变量
        os.environ['TEST_SERVER'] = 'test-server'
        os.environ['TEST_DATABASE'] = 'test-db'
        os.environ['TEST_USERNAME'] = 'test-user'
        os.environ['TEST_PASSWORD'] = 'test-pass'

    def tearDown(self):
        # 清理环境变量
        for key in ['TEST_SERVER', 'TEST_DATABASE', 'TEST_USERNAME', 'TEST_PASSWORD']:
            if key in os.environ:
                del os.environ[key]

    @patch('pymssql.connect')
    def test_db_connection_flow(self, mock_connect):
        # 模拟数据库连接对象
        mock_conn = MagicMock()
        mock_connect.return_value = mock_conn

        # 执行上下文管理器
        with db_connection('TEST') as conn:
            self.assertEqual(conn, mock_conn)
            # 验证自动提交配置
            mock_conn.autocommit.assert_called_once_with(True)
            # 验证连接参数是否正确传递(注意:原函数中timeout变量未定义,需确保实际代码已声明)
            mock_connect.assert_called_once_with(
                server='test-server',
                database='test-db',
                user='test-user',
                password='test-pass',
                timeout=timeout
            )

        # 验证连接最终被关闭
        mock_conn.close.assert_called_once()

三、集成测试示例(用Fixture搭建测试数据库)

借助pytest的fixture创建临时测试数据库(建议用Docker快速搭建SQL Server测试环境):

import pytest
import os
import pymssql
from your_module import db_connection

# 测试数据库基础配置
TEST_DB_CONFIG = {
    'server': 'localhost',
    'database': 'test_temp_db',
    'username': 'sa',
    'password': 'your-test-password'
}

@pytest.fixture(scope='module')
def test_db():
    # 1. 创建测试数据库(若不存在)
    conn = pymssql.connect(
        server=TEST_DB_CONFIG['server'],
        database='master',
        user=TEST_DB_CONFIG['username'],
        password=TEST_DB_CONFIG['password']
    )
    cursor = conn.cursor()
    cursor.execute(f"IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = '{TEST_DB_CONFIG['database']}') CREATE DATABASE {TEST_DB_CONFIG['database']}")
    conn.commit()
    conn.close()

    # 2. 设置环境变量
    os.environ['TEST_SERVER'] = TEST_DB_CONFIG['server']
    os.environ['TEST_DATABASE'] = TEST_DB_CONFIG['database']
    os.environ['TEST_USERNAME'] = TEST_DB_CONFIG['username']
    os.environ['TEST_PASSWORD'] = TEST_DB_CONFIG['password']

    yield

    # 3. 清理测试数据库
    conn = pymssql.connect(
        server=TEST_DB_CONFIG['server'],
        database='master',
        user=TEST_DB_CONFIG['username'],
        password=TEST_DB_CONFIG['password']
    )
    cursor = conn.cursor()
    cursor.execute(f"ALTER DATABASE {TEST_DB_CONFIG['database']} SET SINGLE_USER WITH ROLLBACK IMMEDIATE")
    cursor.execute(f"DROP DATABASE {TEST_DB_CONFIG['database']}")
    conn.commit()
    conn.close()

    # 清理环境变量
    for key in ['TEST_SERVER', 'TEST_DATABASE', 'TEST_USERNAME', 'TEST_PASSWORD']:
        del os.environ[key]

def test_integration_db_connection(test_db):
    # 验证真实连接与查询功能
    with db_connection('TEST') as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT 1")
        result = cursor.fetchone()
        assert result[0] == 1

四、日志应用上下文问题解决

当函数中使用app.logger.info时,测试需显式激活Flask应用上下文,两种常用方案:

方法1:直接使用app.app_context()上下文管理器

from your_flask_app import app

@patch('pymssql.connect')
def test_db_connection_with_log(mock_connect):
    mock_conn = MagicMock()
    mock_connect.return_value = mock_conn

    # 激活应用上下文
    with app.app_context():
        with db_connection('TEST') as conn:
            # 执行测试逻辑
            pass

方法2:用pytest-flask的fixture简化配置

先安装依赖:

pip install pytest-flask

测试代码中使用内置fixture自动激活上下文:

import pytest
from your_flask_app import app

@pytest.fixture
def app_context():
    with app.app_context():
        yield

def test_db_connection_with_log(app_context, mock_connect):
    mock_conn = MagicMock()
    mock_connect.return_value = mock_conn
    
    with db_connection('TEST') as conn:
        # 执行测试逻辑
        pass

内容的提问来源于stack exchange,提问作者FrankZhu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:34:51