Flask单元测试 - 如何为每个测试重置app.url_map?

时间:2016-12-15 18:45:35

标签: python unit-testing flask pytest

我正在为Flask应用程序编写一系列单元测试。每项测试的设置如下:

  • 以测试模式(app.testing = True)创建Flask应用。
  • 在测试应用程序中的蓝图上安装测试端点(路径)。
  • (然后,在端点上进行一些测试......)

问题是我的测试中使用的应用实例累积了从之前测试中添加的路径,而不是从干净的平板开始。就好像app.url_map永远不会重置,即使我每次都创建一个新的应用程序......

这是我的设置功能的代码,它在每次测试之前运行(我使用的是pytest):

def setup(flask_app):
    app = flask_app

    # Mount a test endpoint on the API blueprint.
    bp = app.blueprints["api"]
    bp.add_url_rule('/foo', view_func=test_view, methods=['GET', ])

    print(app.url_map)

flask_app是一个pytest工具,可以创建一个新的测试应用程序,如下所示:

@pytest.fixture()
def flask_app():
    from my_app import create_app
    app = create_app('testing')
    # Configure a bunch of things on app...
    return app

如果我写了三个测试,我的setup函数会被调用三次,并为app.url_map记录以下内容:

# 1st test — My new '/api/foo' rule doesn't even show yet...
# For that, I'd need to re-register the blueprint after adding the URL to it.

Map([<Rule '/' (HEAD, OPTIONS, GET) -> main.index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>])


# 2nd test — Rule '/api/foo' added once

Map([<Rule '/' (HEAD, OPTIONS, GET) -> main.index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/api/foo' (HEAD, OPTIONS, GET) -> api.test_view>])


# 3rd test — Rule '/api/foo' added twice

Map([<Rule '/' (HEAD, OPTIONS, GET) -> main.index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/api/foo' (HEAD, OPTIONS, GET) -> api.test_view>],
<Rule '/api/foo' (HEAD, OPTIONS, GET) -> api.test_view>]

在我的实际代码中(有点复杂),我收到以下错误:

AssertionError: View function mapping is overwriting an existing endpoint function:
lib/flask/app.py:1068: AssertionError

这是有道理的,因为我试图多次添加相同的视图...为什么每次运行新测试时都不会获得新的应用实例?

我甚至不确定这是Flask问题还是pytest问题...... :(

1 个答案:

答案 0 :(得分:0)

我可以通过将实例化的所有东西移动到设置中(甚至导入您正在使用的库)来解决类似的问题。当然,可以像在整个烧瓶应用程序中一样使用create_app()方法,以一种更为优雅的方式完成此操作。这里要注意的重要一点是,将使状态(此处是端点)不在全局范围内的实例,然后将其移入create_app()方法。

如果需要更多信息,请告诉我。