Flask应用程序在测试时随机拒绝连接

时间:2017-02-27 21:20:41

标签: python unit-testing flask python-requests nose

我有一个用Flask编写的API,我正在使用nosetests测试端点,使用请求向API发送请求。在测试期间,我随机收到错误

ConnectionError: HTTPConnectionPool(host='localhost', port=5555): Max retries exceeded with url: /api (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7fe4e794fd50>: Failed to establish a new connection: [Errno 111] Connection refused',))

此错误似乎仅在运行测试时发生,并随机影响无测试和所有测试之间的任何位置。我的所有测试都是从unittests.TestCase的一个子类运行的:

class WebServerTests(unittest.TestCase):
    # Args to run web server with
    server_args = {'port': WEB_SERVER_PORT, 'debug': True}

    # Process to run web server
    server_process = multiprocessing.Process(
        target=les.web_server.run_server, kwargs=server_args)

    @classmethod
    def setup_class(cls):
        """
        Set up testing
        """
        # Start server
        cls.server_process.start()

    @classmethod
    def teardown_class(cls):
        """
        Clean up after testing
        """
        # Kill server
        cls.server_process.terminate()
        cls.server_process.join()

    def test_api_info(self):
        """
        Tests /api route that gives information about API
        """
        # Test to make sure the web service returns the expected output, which at
        # the moment is just the version of the API
        url = get_endpoint_url('api')
        response = requests.get(url)
        assert response.status_code == 200, 'Status Code: {:d}'.format(
            response.status_code)
        assert response.json() == {
            'version': module.__version__}, 'Response: {:s}'.format(response.json())

在localhost上发生了一切,服务器正在侦听127.0.0.1。我的猜测是,有太多的请求被发送到服务器而有些被拒绝了,但我在调试日志中没有看到类似的内容。我还认为,在发出请求之前服务器进程没有启动可能是一个问题,但是在启动服务器进程后问题仍然存在。另一种尝试是让请求尝试通过设置requests.adapters.DEFAULT_RETRIES来重试连接。这也不起作用。

我已尝试在正常和停靠器容器中的两台计算机上运行测试,但无论运行它们的平台如何,问题似乎都会发生。

任何可能导致此问题以及可以采取哪些措施来解决问题的想法?

1 个答案:

答案 0 :(得分:1)

事实证明,我的问题确实是服务器没有足够时间启动的问题,因此测试将在它可以响应测试之前运行。我以为我试图通过睡眠来解决这个问题,但是在创建过程后而不是在启动过程之后意外地放置了它。最后,改变

cls.server_process.start()

cls.server_process.start()
time.sleep(1)

解决了这个问题。