Django 的 LiveServerTestCase 总是因为地址冲突而失败......尽管地址看起来是免费的



我目前正在清理我的Django功能测试,以使用LiveServerTestCase,而不是从后台运行的开发环境实例中弹出基于硒的测试,我遇到了麻烦。每次我尝试运行LiveServerTestCase测试时,我都会得到以下错误:

======================================================================
ERROR: setUpClass (fun_tests.tests.backend.TestCmsLogin)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/user/Documents/env/local/lib/python2.7/site-packages/django/test/testcases.py", line 1187, in setUpClass
    raise cls.server_thread.error
error: [Errno 98] Address already in use

超级有趣,考虑到sudo netstat -netp | grep 8081不会产生任何结果。一些背景:我使用Django 1.6,我使用nose、Django-nose、nose-exclude,但我已经有效地将它们剔除,以帮助诊断问题。我使用的代码非常简单:

from django.test import LiveServerTestCase
class TestCmsLogin(LiveServerTestCase):
    def test_a_test_itself(self):
        self.assertTrue(True)

我找不到任何关于这个主题的现有技术,Djangproject的bug跟踪器是干净的。我错过了什么?

编辑:今天早上这个问题是不可复制的,任何将8081端口标记为打开的都不再引起问题。

第二版:在我的文章中,把8081错打成了8082,修复了(并检查了一下,以确保当时我打对了)。

您可以(在settings.py中)设置环境变量DJANGO_LIVE_TEST_SERVER_ADDRESS,以包括将要尝试的多个端口范围:

os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']="localhost:8000-8010,8080,9200-9300"

我自己也有同样的问题,也许这能帮助别人。

在上一个测试生成内部服务器错误后,我在运行后续测试时开始出现这种情况。在mac上,使用lsof查找使用端口的程序,并将其杀死。例如:

$ sudo lsof -i :8081
COMMAND    PID    USER   FD   TYPE            DEVICE SIZE/OFF NODE NAME
firefox-b 1097 username    3u  IPv4 0x94495559c6dea35      0t0  TCP localhost:sunproxyadmin (LISTEN)
$ kill -9 1097

值得一提的是,我遇到了一个类似的问题,但解决方法略有不同。我们的LiveServerTestCase在虚拟化环境中与其他几台机器一起运行,需要保持相同的端口,以便Nginx(在不同的机器上)能够正确重定向流量。

有问题的线路https://github.com/django/django/blob/1.11.15/django/test/testcases.py#L1296特别是allow_reuse_address=False

allow_reuse_address默认为True,在这里被覆盖,期望服务器线程将绑定到端口0,并保证有一个可用端口。不过,如果在后续运行之间重用该端口,那么当下一次测试启动时,操作系统还没有超时上一次测试的套接字请求。更多详细信息请点击此处

我的解决方案只是对kwarg:进行子类化和覆盖

import django.test.testcases
from django.core.servers.basehttp import WSGIServer

class LiveServerThreadWithReuse(django.test.testcases.LiveServerThread):
    """
    This miniclass overrides _create_server to allow port reuse. This avoids creating
    "address already in use" errors for tests that have been run subsequently.
    """
    def _create_server(self):
        return WSGIServer(
            (self.host, self.port),
            django.test.testcases.QuietWSGIRequestHandler,
            allow_reuse_address=True,
        )

class MyFunctionalTestCase(django.test.testcases.LiveServerTestCase):
    port = 8000
    server_thread_class = LiveServerThreadWithReuse
    def test_something(self):
        # ...

请注意,这是针对django v1.11的。在后来的版本中,名称略有更改(我认为是从WSGIServer更改为ThreadedWSGIServer)。

如果未设置环境变量DJANGO_LIVE_TEstrongERVER_ADDRESS,则启动实时测试服务器的默认地址为localhost:8081。请参阅LiveServerTestCase源代码。

  # Launch the live server's thread
    specified_address = os.environ.get(
        'DJANGO_LIVE_TEST_SERVER_ADDRESS', 'localhost:8081')

操作系统似乎在抱怨端口8081正在使用中。通过运行下面的测试,可以快速选择另一个端口(比如9000)。

/manage.py test functional_tests --liveserver :9000

但是,明确设置DJANGO_LIVE_TEstrongERVER_ADDRESS将是理想的。

export DJANGO_LIVE_TEST_SERVER_ADDRESS="localhost:9000"

如果要将测试用例分离,请更改拆卸方法

在一个文件中测试可以使用.close()方法

def tearDown(self):
    self.browser.close()

在多个文件中进行测试将需要启动新的线程。

def tearDown(self):
    self.browser.quit()

相关内容

  • 没有找到相关文章

最新更新