Почему я получаю пустые наборы запросов django при использовании ThreadPoolExecutor с pytest-django? - PullRequest
1 голос
/ 04 июля 2019

Я пытался отследить некоторые ошибки в некотором параллельном коде и хотел написать тест, который выполнял функцию параллельно.Я использую Django с postgres в качестве базы данных и тестирую с использованием pytest и pytest-django.

Для запуска своей функции я использую ThreadPoolExecutor и просто запрашиваю базу данных и возвращаю количество объектов.Вот тест в оболочке django, работающий как ожидалось:

>>> from concurrent.futures import *
>>> def count_accounts():
...     return Account.objects.all().count()
...
>>> count_accounts()
2
>>> with ThreadPoolExecutor(max_workers=1) as e:
...     future = e.submit(count_accounts)
...
>>> for f in as_completed([future]):
...     print(f.result())
...
2

Однако, когда я запускаю его как тест под pytest, кажется, что функция в потоке возвращает пустые наборы запросов:

class TestCountAccounts(TestCase):
    def test_count_accounts(self):
        def count_accounts():
            return Account.objects.all().count()

        initial_result = count_accounts()  # 2
        with ThreadPoolExecutor(max_workers=1) as e:
            future = e.submit(count_accounts)

        for f in as_completed([future]):
            assert f.result() == initial_result  # 0 != 2

Могу ли я в любом случае получить вызов внутри потока, чтобы вернуть правильное значение / получить доступ к БД правильно?

1 Ответ

1 голос
/ 04 июля 2019

Попробуйте использовать TransactionTestCase вместо TestCase. TestCase оборачивает класс atomic(), а каждый тест - atomic(), поэтому вполне вероятно, что поток выполняется вне транзакции, в которой создаются ваши тестовые данные.

Для получения дополнительной информации о разнице между ними: http://rahmonov.me/posts/testcase-vs-transactiontestcase-in-django/

...