Flask单元测试和应用初始化

0 投票
1 回答
2724 浏览
提问于 2025-04-18 01:32

我有一个Flask应用程序,想对它进行一些单元测试。为此,我创建了一个新的Flask对象,初始化了一些蓝图、SQLA和其他几个包,然后执行测试用例。

不过,我发现测试用的Flask对象上有些接口缺失,这让我对Flask的初始化方式产生了疑问。

举个简单的例子,一个接口是这样创建的:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

如果我在测试用例的setUp方法中创建一个新的Flask对象,它肯定不会包含'/'这个路由,因为这个路由是从另一个Flask对象(上面文件中的那个)创建的。所以我的问题是:测试用例应该怎么写,初始化一般是怎么进行的?我在某个地方看到过,应该避免在导入时进行初始化(也就是在模块级别),但如果使用了注解,这似乎是不可能的。

1 个回答

2

在你的测试案例中,不需要新建一个 Flask 对象。你应该是直接 导入你已经存在的 app 对象

在很多项目中,你已经把所有的扩展功能都添加到了这个 app 对象里。在我的很多项目中,我有一个工厂方法,它会接收一个配置对象,然后返回一个完全初始化好的 app 对象;我用这个方法来创建一个基础的测试案例:

import unittest

import project


class Config(object):
    DEBUG = False
    TESTING = True
    CACHE_NO_NULL_WARNING = True  # silence Flask-Cache warning
    SECRET_KEY = 'SECRET_KEY'


class ProjectCoreViewCase(unittest.TestCase):
    """Base test case for the Project core app"""

    def setUp(self, **kwargs):
        config = Config()
        config.__dict__.update(kwargs)
        app = project.create_app(config)
        self.app = app.test_client()

这样,任何测试都可以使用 self.app 作为测试客户端来进行测试。

这是一个基础的测试案例,你可以从它那里继承;setUp() 方法允许你进行额外的配置,通过传递关键字参数给 super() 调用来实现:

class ConcreteTestCase(ProjectCoreViewCase):
    def setUp(self):
        super(ConcreteTestCase, self).setUp(
            SQLALCHEMY_DATABASE_URI='your_test_specific_connection_uri',
        )

撰写回答