'Django channels tests fails

I have followed the tutorial from readthedocs: https://channels.readthedocs.io/en/stable/tutorial/index.html for django channels. Everything worked fine until the last part of the tutorial, about testing.

Here is the test file as well as the traceback.

# chat/tests.py
from channels.testing import ChannelsLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.wait import WebDriverWait

class ChatTests(ChannelsLiveServerTestCase):
    serve_static = True  # emulate StaticLiveServerTestCase

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        try:
            # NOTE: Requires "chromedriver" binary to be installed in $PATH
            cls.driver = webdriver.Chrome()
        except:
            super().tearDownClass()
            raise

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

    def test_when_chat_message_posted_then_seen_by_everyone_in_same_room(self):
        try:
            self._enter_chat_room('room_1')

            self._open_new_window()
            self._enter_chat_room('room_1')

            self._switch_to_window(0)
            self._post_message('hello')
            WebDriverWait(self.driver, 2).until(lambda _:
                                                'hello' in self._chat_log_value,
                                                'Message was not received by window 1 from window 1')
            self._switch_to_window(1)
            WebDriverWait(self.driver, 2).until(lambda _:
                                                'hello' in self._chat_log_value,
                                                'Message was not received by window 2 from window 1')
        finally:
            self._close_all_new_windows()

    def test_when_chat_message_posted_then_not_seen_by_anyone_in_different_room(self):
        try:
            self._enter_chat_room('room_1')

            self._open_new_window()
            self._enter_chat_room('room_2')

            self._switch_to_window(0)
            self._post_message('hello')
            WebDriverWait(self.driver, 2).until(lambda _:
                                                'hello' in self._chat_log_value,
                                                'Message was not received by window 1 from window 1')

            self._switch_to_window(1)
            self._post_message('world')
            WebDriverWait(self.driver, 2).until(lambda _:
                                                'world' in self._chat_log_value,
                                                'Message was not received by window 2 from window 2')
            self.assertTrue('hello' not in self._chat_log_value,
                            'Message was improperly received by window 2 from window 1')
        finally:
            self._close_all_new_windows()

    # === Utility ===

    def _enter_chat_room(self, room_name):
        self.driver.get(self.live_server_url + '/chat/')
        ActionChains(self.driver).send_keys(room_name + '\n').perform()
        WebDriverWait(self.driver, 2).until(lambda _:
                                            room_name in self.driver.current_url)

    def _open_new_window(self):
        self.driver.execute_script('window.open("about:blank", "_blank");')
        self.driver.switch_to_window(self.driver.window_handles[-1])

    def _close_all_new_windows(self):
        while len(self.driver.window_handles) > 1:
            self.driver.switch_to_window(self.driver.window_handles[-1])
            self.driver.execute_script('window.close();')
        if len(self.driver.window_handles) == 1:
            self.driver.switch_to_window(self.driver.window_handles[0])

    def _switch_to_window(self, window_index):
        self.driver.switch_to_window(self.driver.window_handles[window_index])

    def _post_message(self, message):
        ActionChains(self.driver).send_keys(message + '\n').perform()

    @property
    def _chat_log_value(self):
        return self.driver.find_element_by_css_selector('#chat-log').get_property('value')
PS C:\Users\regis\PycharmProjects\mysite> py manage.py test chat.tests
Found 2 test(s).
Creating test database for alias 'default'...
Destroying old test database for alias 'default'...
System check identified no issues (0 silenced).

DevTools listening on ws://127.0.0.1:8872/devtools/browser/6bb10b6b-1101-4147-8f75-bc0b54800912
EETraceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\spawn.py", line 107, in spawn_main
    new_handle = reduction.duplicate(pipe_handle,
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\reduction.py", line 79, in duplicate
    return _winapi.DuplicateHandle(
OSError: [WinError 6] The handle is invalid
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\spawn.py", line 109, in spawn_main
    fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY)
OSError: [Errno 9] Bad file descriptor

======================================================================
ERROR: test_when_chat_message_posted_then_not_seen_by_anyone_in_different_room (chat.tests.ChatTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\regis\PycharmProjects\mysite\env\lib\site-packages\django\test\testcases.py", line 266, in _setup_and_call
    self._pre_setup()
  File "C:\Users\regis\PycharmProjects\mysite\env\lib\site-packages\channels\testing\live.py", line 52, in _pre_setup
    self._server_process.start()
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\context.py", line 327, in _Popen
    return Popen(process_obj)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'convert_exception_to_response.<locals>.inner'

======================================================================
ERROR: test_when_chat_message_posted_then_seen_by_everyone_in_same_room (chat.tests.ChatTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\regis\PycharmProjects\mysite\env\lib\site-packages\django\test\testcases.py", line 266, in _setup_and_call
    self._pre_setup()
  File "C:\Users\regis\PycharmProjects\mysite\env\lib\site-packages\channels\testing\live.py", line 52, in _pre_setup
    self._server_process.start()
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\context.py", line 327, in _Popen
    return Popen(process_obj)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Users\regis\AppData\Local\Programs\Python\Python39\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'convert_exception_to_response.<locals>.inner'

----------------------------------------------------------------------
Ran 0 tests in 3.753s

FAILED (errors=2)
Destroying test database for alias 'default'...

I am newbie to channels. So far I have only focused on the first error message for the spawn.py file on line 107 but I didn't find out much. Some posts are mentioning forking with multiprocessing not working on Windows but I have no idea what it means.

Thanks for help



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source