Django StaticLiveServerTestCase有时结尾为:远程主机强行关闭了现有连接

时间:2018-11-15 14:09:54

标签: python django selenium google-chrome selenium-chromedriver

在我刚创建的Django应用程序中,将其更改为使用PostgreSQL,并创建了一个应用程序,我进行了以下测试:

from django.contrib.auth.models import User
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys


class TestWebBrowser(StaticLiveServerTestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.webdriver = webdriver.Chrome()
        cls.webdriver.implicitly_wait(10)

    @classmethod
    def tearDownClass(cls):
        cls.webdriver.close()
        cls.webdriver.quit()
        super().tearDownClass()

    def setUp(self):
        self.admin = User.objects.create_superuser(username="username", password="password",
                                                   email="example@example.com")

    def test_log_in(self):
        self.webdriver.get(f"{self.live_server_url}/admin")
        self.webdriver.find_element_by_id("id_username").send_keys("username")
        self.webdriver.find_element_by_id("id_password").send_keys("password")
        self.webdriver.find_element_by_id("id_password").send_keys(Keys.RETURN)
        self.webdriver.find_element_by_link_text("Users").click()

测试始终运行,Chrome启动,按照测试内容执行操作,但最后,有时会抛出此错误:

Exception happened during processing of request from ('127.0.0.1', 55283)
Traceback (most recent call last):
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socketserver.py", line 647, in process_request_thread
    self.finish_request(request, client_address)
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socketserver.py", line 357, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socketserver.py", line 717, in __init__
    self.handle()
  File "C:\Users\pupeno\Temporary\untitled\venv\lib\site-packages\django\core\servers\basehttp.py", line 139, in handle
    self.raw_requestline = self.rfile.readline(65537)
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socket.py", line 589, in readinto
    return self._sock.recv_into(b)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

所有测试均通过。我刚到STDERR。有什么想法吗?我想念一些拆解吗?

如果我将tearDownClass更改为:

@classmethod
def tearDownClass(cls):
    cls.webdriver.quit()

在相同的频率下,我会得到相同的错误(据我所观察到的,没有测量)。

我正在跑步:

Django==2.1.2
selenium==3.141.0

> chromedriver.exe --version
ChromeDriver 2.43.600210 (68dcf5eebde37173d4027fa8635e332711d2874a)

Google Chrome Version 70.0.3538.102 (Official Build) (64-bit)

运行测试的完整输出如下:

Testing started at 15:33 ...
C:\Users\pupeno\Temporary\untitled\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm 2018.2.4\helpers\pycharm\django_test_manage.py" test foo.tests.TestImportCRMData C:\Users\pupeno\Temporary\untitled
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 49825)
Traceback (most recent call last):
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socketserver.py", line 647, in process_request_thread
    self.finish_request(request, client_address)
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socketserver.py", line 357, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socketserver.py", line 717, in __init__
    self.handle()
  File "C:\Users\pupeno\Temporary\untitled\venv\lib\site-packages\django\core\servers\basehttp.py", line 139, in handle
    self.raw_requestline = self.rfile.readline(65537)
  File "C:\Users\pupeno\scoop\apps\python\current\lib\socket.py", line 589, in readinto
    return self._sock.recv_into(b)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
----------------------------------------
Destroying test database for alias 'default'...

Process finished with exit code 0

1 个答案:

答案 0 :(得分:0)

此错误消息...

ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

...表示 ChromeDriver 无法与 WebBrowsing会话(即 Chrome浏览器”会话进行通信,因为该会话已被Windows强行关闭)远程主机。

您的主要问题是以 webdriver.close() webdriver.quit()

的形式进行的多次通话

按照最佳做法通过 Selenium 自动执行以终止连接时,您应始终在driver.quit()方法内调用tearDown(){}来关闭和销毁 WebDriver Web客户端实例。通过发送带有 {“ flags”:[“ eForceQuit”]] “退出” 命令,调用quit()方法DELETE可以当前浏览会话最后在 /关闭 EndPoint上发送 GET 请求。下面是一个示例:

1503397488598   webdriver::server   DEBUG   -> DELETE /session/8e457516-3335-4d3b-9140-53fb52aa8b74 
1503397488607   geckodriver::marionette TRACE   -> 37:[0,4,"quit",{"flags":["eForceQuit"]}]
1503397488821   webdriver::server   DEBUG   -> GET /shutdown

因此,在调用 quit() 方法时,Web Browser会话和WebDriver实例将被完全杀死。因此,您不必合并任何其他步骤(调用close()),而这是现行标准的开销。

解决方案

首先,您删除以下行:

cls.webdriver.close()

下一行:

cls.webdriver.quit()

必须以最佳方式终止连接。

在这里您可以找到有关Selenium : How to stop geckodriver process impacting PC memory, without calling driver.quit()?的详细讨论

更新A

根据liveservertestcase tearDownClass() @classmethod 定义为:

@classmethod
def tearDownClass(cls):
    cls.selenium.quit()
    super().tearDownClass()

根据django/django/test/testcases.py,这称为:

@classmethod
def tearDownClass(cls):
    cls._tearDownClassInternal()
    cls._live_server_modified_settings.disable()
    super().tearDownClass()