Django тестирует соединение с БД, которое не закрыто

#python #django #selenium #testing

#python #django #selenium #тестирование

Вопрос:

Я использую Selenium для проверки правильности работы языкового переключателя на сайте Django. Для интернационализации я использую встроенные возможности Djangos.

Тесты проходят нормально, но сразу после их завершения я получаю psycopg2.OperationalError сообщение о том, что есть еще один сеанс, использующий базу данных. Тесты фактически не используют базу данных, из того, что я вижу, используется только управление сеансами djangos.

Установка SESSION_EXPIRE_AT_BROWSER_CLOSE значения True не помогает, хотя я вызываю driver.quit() tearDownCLass метод теста. Закрытие всех соединений connections.close_all() также ничего не меняет. select * from pg_stat_activity во время выполнения теста показано, что на этапе действительно открыто незанятое соединение COMMIT , пока тестовая база данных удаляется.

Я могу обойти эту проблему, определив a DiscoverRunner , который пропускает teardown_databases , но в лучшем случае это уродливое решение.

РЕДАКТИРОВАТЬ: точное сообщение об ошибке и трассировка стека.

 Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 83, in _execute
    return self.cursor.execute(sql)
psycopg2.OperationalError: database "test_postgres" is being accessed by other users
DETAIL:  There is 1 other session using the database.


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/test.py", line 26, in run_from_argv
    super().run_from_argv(argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/test.py", line 56, in handle
    failures = test_runner.run_tests(test_labels)
  File "/usr/local/lib/python3.7/site-packages/django/test/runner.py", line 607, in run_tests
    self.teardown_databases(old_config)
  File "/usr/local/lib/python3.7/site-packages/django/test/runner.py", line 580, in teardown_databases
    keepdb=self.keepdb,
  File "/usr/local/lib/python3.7/site-packages/django/test/utils.py", line 297, in teardown_databases
    connection.creation.destroy_test_db(old_name, verbosity, keepdb)
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/creation.py", line 257, in destroy_test_db
    self._destroy_test_db(test_database_name, verbosity)
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/creation.py", line 274, in _destroy_test_db
    % self.connection.ops.quote_name(test_database_name))
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 83, in _execute
    return self.cursor.execute(sql)
django.db.utils.OperationalError: database "test_postgres" is being accessed by other users
DETAIL:  There is 1 other session using the database.
  

EDIT2: пример тестового примера

 class SeleniumTest(LiveServerTestCase):
    @classmethod
    def setUpClass(cls):
        cls.port = settings.PORT
        cls.host = settings.HOSTNAME
        super().setUpClass()

        cls.selenium = webdriver.Remote(
            command_executor=settings.SELENIUM_REMOTE_EXECUTOR,
            desired_capabilities=webdriver.common.desired_capabilities.DesiredCapabilities.FIREFOX,
        )
        cls.selenium.implicitly_wait(10)
        cls.selenium.get('%s%s' % (cls.live_server_url, '/'))

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

    def setUp(self):
        self.selenium.get("{}{}".format(self.live_server_url, '/'))

class I18nTestCase(SeleniumTest):

    def wait_to_be_clickable(self, by, val):
        return WebDriverWait(self.selenium, 45).until(
            expected_conditions.element_to_be_clickable((by, val))
        )

    def wait_for_site_to_reload(self):
        def is_ready(driver):
            return driver.execute_script("return document.readyState") == "complete"

        WebDriverWait(self.selenium, 60).until(is_ready)

    def set_language_to_german(self):
        language_menu = Select(self.selenium.find_element_by_id("language_id"))
        language_menu.select_by_visible_text('Deutsch (de)')

        go_button = self.selenium.find_element_by_id("language_submit_button")
        go_button.click()

    def test_german_index(self):
        self.set_language_to_german()
        self.wait_for_site_to_reload()

        headline = self.selenium.find_element_by_xpath("/html/body/div[3]/h1").text
        self.assertEquals(headline, "Gib das zu überprüfende Passwort ein:")

        self.check_footer()
  

Комментарии:

1. «Управление сеансами Django» — это не то, что выполняется отдельно от чего-либо еще. Какую точную ошибку вы видите?

2. psycopg2.OperationalError: database "test_postgres" is being accessed by other users DETAIL: There is 1 other session using the database.

3. Опубликуйте пример вашего тестового примера.