测试Flask路线确实存在和不存在

Tim*_*per 8 python testing unit-testing flask

我正在使用正则表达式创建大量Flask路由.我想要进行单元测试,检查是否存在正确的路由以及错误的路由404.

这样做的一种方法是启动本地服务器并使用urllib2.urlopen等.但是,我希望能够在Travis上运行这个测试,我假设这不是一个选择.

我还有另一种方法可以在我的应用程序上测试路线吗?

Mar*_*ers 13

在您的单元测试中使用该Flask.test_client()对象.该方法返回一个FlaskClient实例(werkzeug.test.TestClient子类),使得测试路由变得微不足道.

调用的结果TestClient是一个Response对象,看它是200还是404响应测试Response.status_code属性:

with app.test_client() as c:
    response = c.get('/some/path/that/exists')
    self.assertEquals(response.status_code, 200)
Run Code Online (Sandbox Code Playgroud)

要么

with app.test_client() as c:
    response = c.get('/some/path/that/doesnt/exist')
    self.assertEquals(response.status_code, 404)
Run Code Online (Sandbox Code Playgroud)

请参阅Flask文档的" 测试Flask应用程序"一章.


Ray*_*nda 5

Martjin 的回答肯定会解决您的问题,但有时您没有时间(或不会)模拟您在要测试是否存在的路由中调用的所有组件。

为什么你需要嘲笑? 好吧,调用get('some_route') 将首先检查此路由是否存在,然后……它将被执行!

如果视图是一个复杂的视图,并且您需要有夹具、环境变量和任何其他准备来测试路由是否存在,那么您需要重新考虑您的测试设计。

如何避免这种情况:

您可以列出应用程序中的所有路线。检查您正在测试的那个在列表中。

在以下示例中,您可以通过站点地图的实现在实践中看到这一点。

from flask import Flask, url_for

app = Flask(__name__)

def has_no_empty_params(rule):
    defaults = rule.defaults if rule.defaults is not None else ()
    arguments = rule.arguments if rule.arguments is not None else ()
    return len(defaults) >= len(arguments)


@app.route("/site-map")
def site_map():
    links = []
    for rule in app.url_map.iter_rules():
        # Filter out rules we can't navigate to in a browser
        # and rules that require parameters
        if "GET" in rule.methods and has_no_empty_params(rule):
            url = url_for(rule.endpoint, **(rule.defaults or {}))
            links.append((url, rule.endpoint))
    # links is now a list of url, endpoint tuples
Run Code Online (Sandbox Code Playgroud)

参考:

获取应用程序中定义的所有路线的列表

列出路线的助手(如 Rail 的 rake 路线)