使用Python Unittest在Flask中测试重定向

Jas*_*oks 14 python unit-testing flask python-unittest

我目前正在尝试为Flask应用程序编写一些单元测试.在我的许多视图功能(例如我的登录)中,我重定向到新页面.例如:

@user.route('/login', methods=['GET', 'POST'])
def login():
    ....
    return redirect(url_for('splash.dashboard'))
Run Code Online (Sandbox Code Playgroud)

我正在尝试验证此重定向是否发生在我的单元测试中.现在,我有:

def test_register(self):
    rv = self.create_user('John','Smith','John.Smith@myschool.edu', 'helloworld')
    self.assertEquals(rv.status, "200 OK")
    # self.assert_redirects(rv, url_for('splash.dashboard'))
Run Code Online (Sandbox Code Playgroud)

此函数确保返回的响应为200,但最后一行显然不是有效的语法.我怎么能断言呢?我的create_user功能很简单:

def create_user(self, firstname, lastname, email, password):
        return self.app.post('/user/register', data=dict(
            firstname=firstname,
            lastname=lastname,
            email=email,
            password=password
        ), follow_redirects=True)
Run Code Online (Sandbox Code Playgroud)

谢谢!

Rac*_*ers 13

Flask有内置的测试钩子和测试客户端,非常适合这样的功能.

from flask import url_for
import yourapp

test_client = yourapp.app.test_client()
response = test_client.get(url_for('whatever.url'), follow_redirects=True)

# check that the path changed
assert response.request.path == url_for('redirected.url')
Run Code Online (Sandbox Code Playgroud)

文档提供了有关如何执行此操作的更多信息,尽管如果您看到"flaskr",这是测试类的名称而不是Flask中的任何内容,这在我第一次看到它时会让我感到困惑.

  • 我强烈建议人们使用这个解决方案来消除Flask-Testing依赖性(一般来说,我认为使用尽可能少的扩展是好事,或者只有"稳定"和"大"的扩展,如Flask-Principal,Flask - 安全等).但是,此解决方案引发了一个`RuntimeError:尝试在没有推送应用程序上下文的情况下生成URL.这必须在应用程序上下文可用时执行,因为`url_for`需要应用程序上下文.你所要做的就是将它放在`app.app_context():`中 (4认同)
  • “ response.request”-> AttributeError:“ Response”对象没有属性“ request” (3认同)

kar*_*eek 10

尝试烧瓶测试

对于assertRedirects有api 你可以使用它

assertRedirects(response, location)

Checks if response is an HTTP redirect to the given location.
Parameters: 

    response – Flask response
    location – relative URL (i.e. without http://localhost)
Run Code Online (Sandbox Code Playgroud)

测试脚本:

def test_register(self):
    rv = self.create_user('John','Smith','John.Smith@myschool.edu', 'helloworld')
    assertRedirects(rv, url of splash.dashboard)
Run Code Online (Sandbox Code Playgroud)


bro*_*oox 5

一种方法是不遵循重定向(follow_redirects从请求中删除或将其显式设置为False)。

然后,您可以简单地替换self.assertEquals(rv.status, "200 OK")为:

self.assertEqual(rv.status_code, 302)
self.assertEqual(rv.location, url_for('splash.dashboard', _external=True))
Run Code Online (Sandbox Code Playgroud)

如果您follow_redirects出于某种原因想要继续使用,则另一种方法(略微易碎)是检查某些预期的仪表板字符串,例如响应中的HTML元素ID rv.data。例如self.assertIn('dashboard-id', rv.data)