如何测试集成SQLAlchemy的Flask应用?
Flask测试:隔离数据库与Patch使用误区
一、完全可以隔离测试数据库
不管用unittest还是pytest,都能轻松实现测试时替换数据库,不碰生产库:
- unittest写法:
在setUp()方法里直接覆盖Flask应用的数据库配置,换成测试专用库(推荐SQLite内存库,无需手动清理文件),然后创建表;tearDown()里销毁表即可:from unittest import TestCase from myapp import create_app, db class TestDBFill(TestCase): def setUp(self): self.app = create_app({'TESTING': True, 'SQLALCHEMY_DATABASE_URI': 'sqlite:///:memory:'}) self.app_context = self.app.app_context() self.app_context.push() db.create_all() def tearDown(self): db.session.remove() db.drop_all() self.app_context.pop() - pytest fixture写法:
写一个函数级别的fixture,每次测试都生成全新的测试数据库,自动完成清理:
内存库import pytest from myapp import create_app, db @pytest.fixture(scope='function') def test_app(): # 加载测试专属配置 app = create_app({ 'TESTING': True, 'SQLALCHEMY_DATABASE_URI': 'sqlite:///:memory:' }) with app.app_context(): db.create_all() yield app # 测试执行时使用该应用实例 # 测试结束后自动清理 db.session.remove() db.drop_all()sqlite:///:memory:是最优选择,测试结束后自动销毁,无需手动删文件;如果必须用文件型数据库,测试后直接删除对应文件即可。
二、关于Patching的误解
你认为patching只能处理返回对象是错误的,它完全能覆盖数据接收场景,只是要选对使用场景:
- 如果你的数据库填充函数依赖外部服务(比如调用第三方API拉取数据),可以patch这个API调用函数,让它返回模拟数据,再验证填充到测试数据库的内容是否符合预期。
- 如果是直接操作数据库的填充逻辑,不建议用patching,反而应该用上面说的测试数据库实际跑一遍——毕竟你要测试的是填充逻辑本身,用真实的数据库操作才能验证正确性,patch反而会掩盖潜在问题。
- 你试过的flask_testing、pytest fixture都是正确的测试方式,之前出问题大概率是配置没覆盖到位,比如测试时不小心加载了生产环境的数据库配置,导致操作了真实库。
内容的提问来源于stack exchange,提问作者Kate
相关产品推荐
相关产品推荐

