烧瓶单元测试-如何为每个测试重置app.url_map? [英] Flask unit testing - How to reset app.url_map for each test?

查看:61
本文介绍了烧瓶单元测试-如何为每个测试重置app.url_map?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a series of unit tests for a Flask app. The setup for each test is as follows:

  • 在测试模式下创建Flask应用( app.testing = True ).
  • 在测试应用内的蓝图上安装测试端点(路由).
  • (然后,在端点上进行一些测试...)

问题在于,我的测试中使用的应用实例会累积从以前的测试中添加的路由,而不是从干净的表盘开始.好像 app.url_map 从未被重置,即使我每次都创建一个新应用...

The problem is that the app instance used in my tests accumulates the routes added from the previous tests instead of starting from a clean slate. It's as if app.url_map is never reset even though I create a new app each time...

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

Here's the code of my setup function, which runs before each test (I am using 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固定装置,可创建一个新的测试应用,如下所示:

flask_app is a pytest fixture that creates a new test app, something like this:

@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 记录以下内容:

If I write three tests, my setup function is called three times and logs the following for 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>]

在我的实际代码(稍微复杂一些)中,出现以下错误:

In my actual code (a bit more complicated), I get the following error:

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

这是有道理的,因为我试图多次添加相同的视图...为什么每次运行新测试时都没有得到一个新的应用程序实例?

Which makes sense, since I'm trying to add the same view multiple times... Why don't I get a fresh app instance every time I run a new test?

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

I'm not even sure if this is Flask issue or a pytest issue... :(

推荐答案

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

I could solve a similar problem by moving all stuff you instantiate for the setup into the setup (even the import of the libraries you are using there). Of course, this can be done in a more elegant way by having a create_app() method like you do for your whole flask application. The important point to take away here is to take the instance that keeps the state (here the endpoints) out of the global scope and move it into the create_app() method.

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

Tell me if you need more information on this.

这篇关于烧瓶单元测试-如何为每个测试重置app.url_map?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆