我目前正在清理我的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()