首页 > 解决方案 > 用于测试的后台 Flask toyserver

问题描述

我需要一个多线程模式的烧瓶服务器进行测试,因为某些测试路由本身会调用同一服务器上的其他路由(因此,在单线程中test_client它们会挂起)。我认为最简单的解决方案是在后台线程中手动启动服务器 - 但是使用此设置(如下所示),测试用例会因 ConnectionError 而失败 - 大概是因为它们没有等待服务器完成设置。

使用 Flask 设置多线程测试的最佳实践是什么?我是否应该继续使用这种方法并添加额外的处理以等待来自服务器的信号准备好?在 TestCase 端添加超时轮询?

main_test.py

import sys
import unittest
from threading import Thread
from main import app

def _run_test_server():
    app.run(host='localhost', port=3000, debug=True, threaded=True)

Thread(target=_run_test_server).start()
loader = unittest.TestLoader()
tests = loader.discover('.')
runner = unittest.runner.TextTestRunner()
status = runner.run(tests).wasSuccessful()
sys.exit(not status)

主文件

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == "__main__":
    app.run(host='localhost', port=3000, debug=True, threaded=True)

my_test_case.py

class MyTestCase(unittest.TestCase):
    """
    Baseclass for testcases
    """
    def fetch_response(self, path):
        return json.loads(
            requests.get(urllib.parse.urljoin(os.environ["ORIGIN_URI"], path)).data
        )

标签: pythonmultithreadingflasktesting

解决方案


我决定用 bash 来解决这个问题;使用以下_run_test_server功能,不再需要功能。该脚本可以在任何目录中调用并返回测试的退出代码,因此可以例如作为构建目标调用。

#!/usr/bin/env bash
set -o errexit
set -o pipefail
set -o nounset

# set up
curr_dir=$(pwd)
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "${script_dir}"
source .venv/bin/activate

# main tests depend on a development server being run in background.
# since we need a server in multithreaded mode, this was the easiest way to ensure
# that this server is available.
python main.py &
server_pid=$!
while ! nc -z localhost 3000; do   
  sleep 0.1
done
python main_tests.py && :
rc=$?

# clean up
kill ${server_pid}
cd "${curr_dir}"

exit $rc

推荐阅读