gpt4 book ai didi

python - 运行 Flask 服务器、nosetests 和覆盖率

转载 作者:行者123 更新时间:2023-11-30 23:10:11 25 4
gpt4 key购买 nike

我正在 Flask 中编写一个 api。我有几个返回 json 响应的 View ,并且我编写了一些单元测试来检查这些 View 是否正常工作并返回正确的数据。然后我打开了nosetests的覆盖率插件(在我的例子中nose-cov)。

这就是我的问题开始的地方,覆盖范围没有看到我的观点被测试执行。

首先一些基本代码可以让您全面了解:

我的看法:

def get_user(uid):
"""Retrieve user.

Args:
uid (url): valid uid value

Usage: ::

GET user/<uid>/

Returns:
obj:
::

{
'data': {
`response.User`,
},
'success': True,
'status': 'get'
}
"""
if not uid:
raise exception.ValueError("Uid is empty")

obj = db_layer.user.get_user(uid=value)

return {
'data': {
obj.to_dict(), # to_dict is helper method that converts part of orm into dict
},
'success': True,
'status': 'get'
}

我的测试:

class TestUserViews(base.TestViewsBase):
def test_get_user(self):
uid = 'some_uid_from_fixtures'
name = 'some_name_from_fixtures'

response = self.get(u'user/uid/{}/'.format(uid))
self.assertEqual(response.status_code, 200)

user_data = json.loads(response.text)['data']
self.assertEqual(name, user_data['username'])
self.assertEqual(uid, user_data['uid'])

def get(self, method, headers=None):
"""
Wrapper around requests.get, reassures that authentication is
sorted for us.
"""
kwargs = {
'headers': self._build_headers(headers),
}

return requests.get(self.get_url(method), **kwargs)

def get_url(self, method):
return '{}/{}/{}'.format(self.domain, self.version, method)

def _build_headers(self, headers=None):
if headers is None:
headers = {}

headers.update({
'X-Auth-Token': 'some-token',
'X-Auth-Token-Test-User-Id': 'some-uid',
})

return headers

为了运行测试套件,我有特殊的 shell 脚本,可以为我执行一些操作:

#!/usr/bin/env bash

HOST="0.0.0.0"
PORT="5001"

ENVS="PYTHONPATH=$PYTHONPATH:$PWD"

# start server
START_SERVER="$ENVS python $PWD/server.py --port=$PORT --host=$HOST"

eval "$START_SERVER&"

PID=$!

eval "$ENVS nosetests -s --nologcapture --cov-report html --with-cov"

kill -9 $PID

之后该 View 被报告为未执行。

最佳答案

好的,伙计们,12 小时后我找到了解决方案。我检查了flask、werkzeug、requests、subprocess 和thread lib。只是了解到问题在其他地方。事实上,解决方案很简单。必须修改的代码是 server.py 的执行。我们还需要覆盖它,然后合并 server.py 生成的结果和 notests 生成的结果。修改后的 test-runner.sh 如下所示:

#!/usr/bin/env bash

HOST="0.0.0.0"
PORT="5001"

ENVS="COVERAGE_PROCESS_START=$PWD/.apirc PYTHONPATH=$PYTHONPATH:$PWD"

START_SERVER="$ENVS coverage run --rcfile=.apirc $PWD/server.py --port=$PORT --host=$HOST"

eval "$START_SERVER&"

eval "$ENVS nosetests -s --nologcapture --cov-config=.apirc --cov-report html --with-cov"

# this is important bit, we have to stop flask server gracefully otherwise
# coverage won't get a chance to collect and save all results
eval "curl -X POST http://$HOST:$PORT/0.0/shutdown/"

# this will merge results from both coverage runs
coverage combine --rcfile=.apirc
coverage html --rcfile=.apirc

在我的例子中,.apirc 如下所示:

[run]
branch = True
parallel = True
source = files_to_cover/

[html]
directory = cover

我们需要做的最后一件事是在我们的 flask 中构建 View ,这将使我们能够正常关闭服务器。之前我用kill -9 粗暴地杀死了它,它不仅杀死了服务器,还杀死了覆盖范围。

按照以下代码段操作:http://flask.pocoo.org/snippets/67/

我的观点是这样的:

def shutdown():
if config.SHUTDOWN_ALLOWED:
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()

return 'Server shutting down...'

使用nose-cov而不是标准覆盖率插件很重要,因为它使用rcfile并允许配置更多。在我们的例子中,并行是关键,请注意 data_files 变量不适用于 Nose 覆盖,因此您无法在 .apirc 中覆盖它,并且必须使用默认值。

完成所有这些之后,您的覆盖范围将几乎闪烁着有效的值。

我希望它对那里的人有帮助。

关于python - 运行 Flask 服务器、nosetests 和覆盖率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30806553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com