Flask test_client未在unittest.TestCase的setUp()处重新启动

时间:2014-01-20 12:30:55

标签: unit-testing flask nose

我正在使用flask编写一个小型REST服务:

from flask import Flask
app = Flask(__name__)

app.config['count']=0

@app.route("/count")
def get_count():
    app.config['count']+=1
    return str(app.config['count']-1)

@app.route("/reset")
def reset():
    app.config['count']=0
    return str(app.config['count'])

if __name__ == "__main__":
    app.run(debug = True)

/count的连续调用应返回0, 1, 2, ...。调用/reset应该重置计数器。

为了测试它,我遵循了flask and nose tutorial ::

#!/usr/bin/python

import flask_server as server
import unittest
from nose.tools import assert_equals

class TestUnitBase(unittest.TestCase):

    def setUp(self):
        print "Setting up!"
        server.app.testing=True
        self.app = server.app.test_client()

    def test_count_is_zero_in_new_server(self):
        """/count should return 0 for a new server"""
        response       = self.app.get("/count")
        data, status   = response.data, response.status
        assert_equals(int(data), 0)
        print data, status

    def test_count_is_zero_in_new_server_again(self):
        """Asserts that the uptime response contains "boot" and "test" elements."""
        response       = self.app.get("/count")
        data, status   = response.data, response.status
        assert_equals(int(data), 0)
        print data, status

if __name__ == '__main__':
    import nose
    nose.run(argv=[__file__, '--with-doctest', '-v', '-s'])

方法是相同的,我希望它们都能通过,但是:

 $ nosetests -vs location_update_server/server/test_flask_server.py
/count should return 0 for a new server ... Setting up!
0 200 OK
ok
Asserts that the uptime response contains "boot" and "test" elements. ... Setting up!
FAIL

======================================================================
FAIL: Asserts that the uptime response contains "boot" and "test" elements.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/adam/vioozer/servers/location_update_server/server/test_flask_server.py", line 28, in test_count_is_zero_in_new_server_again
    assert_equals(int(data), 0)
AssertionError: 1 != 0

----------------------------------------------------------------------
Ran 2 tests in 0.025s

FAILED (failures=1)

setUp方法确实被调用了两次,但服务器只创建了一次。如何设置测试,以便每次调用setUp()都会启动一个新服务器counter=0

1 个答案:

答案 0 :(得分:4)

您需要为每个测试创建一个新应用程序,以便每个测试开始向全新服务器发送请求。 “应用程序”是指类Flask的实例。

不幸的是,这是一个非平凡的变化。官方文档中解释了基础知识:Application Factories

按照引用页面中的说明操作后,您将不会调用

app = Flask(__name__)

在全局范围内,您将拥有一个返回此create_app()对象的app函数。每个测试都可以自己制作。您发送到全新app对象的任何请求都将是第一个。

关于切换到应用工厂的棘手部分是,一旦将app创建移动到某个功能中,就不能再使用app.route()来定义路由,因为app未定义在全球范围内了。解决方案是使用在运行时附加到应用程序的蓝图。

作为旁注,调用测试客户端self.app的标准做法是这样的:

self.app = server.app.test_client()

非常令人困惑。现在你有两个app个东西。我更喜欢称它为客户端,因为它就是这样:

self.client = server.app.test_client()

最后,请注意,由于依赖于调用顺序,您的REST API实际上并不是RESTful,这种不确定行为实际上会导致您的问题。您的/count路由并不真正代表资源,它代表一个操作。 GET个请求应该是只读的,通常应该使用PUT请求发出对资源的更改。