我正在创建大量Flask路线using regular expressions。我想要进行单元测试,检查是否存在正确的路由以及错误的路由404.
这样做的一种方法是启动本地服务器并使用urllib2.urlopen
等。但是,我希望能够在Travis上运行这个测试,我假设这不是一个选择。
我可以通过另一种方式在我的应用程序上测试路线吗?
答案 0 :(得分:11)
在您的单元测试中使用Flask.test_client()
object。该方法返回FlaskClient
instance(a werkzeug.test.TestClient
subclass),使测试路线变得微不足道。
调用TestClient
的结果是Response
object,以查看它是否为200或404响应测试Response.status_code
attribute:
with app.test_client() as c:
response = c.get('/some/path/that/exists')
self.assertEquals(response.status_code, 200)
或
with app.test_client() as c:
response = c.get('/some/path/that/doesnt/exist')
self.assertEquals(response.status_code, 404)
请参阅Flask文档的Testing Flask Applications chapter。
答案 1 :(得分:2)
为什么你需要模拟?那么,调用get('some_route')
将首先检查此路由是否存在然后......它将被执行!
如果视图是一个复杂的视图,你需要有固定装置,envs变量和任何其他准备测试路线是否存在,那么你需要再考虑一下你的测试设计。
您可以列出应用中的所有路线。检查您正在测试的那个是否在列表中。
在下面的示例中,您可以通过实施站点地图来实现这一点。
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
参考:
答案 2 :(得分:1)
测试URL而不执行附加视图功能的另一种方法是使用match
中的方法MapAdapter
。
from flask import Flask
app = Flask(__name__)
@app.route('/users')
def list_users():
return ''
@app.route('/users/<int:id>')
def get_user(id):
return ''
# Get a new MapAdapter instance. For testing purpose, an empty string is fine
# for the server name.
adapter = app.url_map.bind('')
# This raise werkzeug.exceptions.NotFound.
adapter.match('/unknown')
# This raises werkzeug.exceptions.MethodNotAllowed,
# Although the route exists, the POST method was not defined.
adapter.match('/users', method='POST')
# No exception occurs when there is a match..
adapter.match('/users')
adapter.match('/users/1')
来自Werkzeug文档:
如果存在匹配项,您将得到一个元组(端点,参数)。
在某些测试方案中可能有用。