Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing Flask test_客户端未在unittest.TestCase的setUp()处重新启动_Unit Testing_Flask_Nose - Fatal编程技术网

Unit testing Flask test_客户端未在unittest.TestCase的setUp()处重新启动

Unit testing Flask test_客户端未在unittest.TestCase的setUp()处重新启动,unit-testing,flask,nose,Unit Testing,Flask,Nose,我正在编写一个小型的REST服务,其中包括: 从烧瓶导入烧瓶 app=烧瓶(名称) app.config['count']=0 @应用程序路径(“/count”) def get_count(): app.config['count']+=1 返回str(app.config['count']-1) @应用程序路径(“/重置”) def reset(): app.config['count']=0 返回str(app.config['count']) 如果名称=“\uuuuu main\uuuu

我正在编写一个小型的REST服务,其中包括:

从烧瓶导入烧瓶
app=烧瓶(名称)
app.config['count']=0
@应用程序路径(“/count”)
def get_count():
app.config['count']+=1
返回str(app.config['count']-1)
@应用程序路径(“/重置”)
def reset():
app.config['count']=0
返回str(app.config['count'])
如果名称=“\uuuuu main\uuuuuuuu”:
app.run(debug=True)
/count
的顺序调用应返回
0、1、2、…
。调用
/reset
应重置计数器

为了测试它,我遵循以下步骤:

#/usr/bin/python
将服务器导入为服务器
导入单元测试
从nose.tools导入断言_等于
类TestUnitBase(unittest.TestCase):
def设置(自):
打印“设置!”
server.app.testing=True
self.app=server.app.test_client()
def测试计数在新服务器(自身)中为零:
“”“/count应为新服务器返回0”“”
response=self.app.get(“/count”)
数据,状态=response.data,response.status
断言_等于(int(数据),0)
打印数据、状态
def test_count_在新服务器中再次为零(self):
“”“断言正常运行时间响应包含“启动”和“测试”元素。”“”
response=self.app.get(“/count”)
数据,状态=response.data,response.status
断言_等于(int(数据),0)
打印数据、状态
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
进口鼻
run(argv=[\uuuuu文件\uuuuuu'--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()
都会启动一个新服务器,并且
counter=0

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

不幸的是,这是一个非同寻常的变化。官方文档中解释了基本知识:

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

app = Flask(__name__)
在全局范围中,您将有一个
create_app()
函数返回此
app
对象。每个测试都可以自己做。您向全新的
应用程序
对象发送的任何请求都将是第一个请求

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

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

self.app = server.app.test_client()
这很令人困惑。现在你有两个
app
东西。我更喜欢称之为客户机,因为它是:

self.client = server.app.test_client()

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

是否
TestUnit
子类
unittest.TestCase
?@dim Yes。安装程序为每个测试运行一次。您在示例中提到的计数器是保存在测试客户端还是服务器中的?我认为使用计数器的示例测试可能有助于更好地理解问题。@Miguel用完整的服务器和测试代码更新了我的答案。非常感谢您的回答!另一方面,您如何为REST服务存储全局计数器?@AdamMatan:我不确定您需要计数器的用例是什么,但我不会给客户端直接增加计数器的能力,我只会根据客户端的操作间接计算服务器中需要计数的事件。例如,如果我想计算请求,我只需在请求之前添加一个递增内部计数器的
处理程序。如果我需要公开计数器,我将有一个
stats
资源作为返回当前值的
/stats
路由公开。对于单元测试,我将首先读取计数器,运行测试,然后确保计数器增加了正确的次数。测试不应关注计数器是否从0开始。