Pytest-django: рдПрдХрд╛рдзрд┐рдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдмреАрдЪ рд╕рдорд░реНрдерди рд╕рдлрд╛рдИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 20 рдорд╛рд░реНрдЪ 2014  ┬╖  20рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: pytest-dev/pytest-django

рдХрдИ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде Django рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп pytest-django рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдмреАрдЪ рд╕рд╛рдл рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд╕рдорд╕реНрдпрд╛ рдЗрд╕ рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдкреНрд░рд╢реНрди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ: http://stackoverflow.com/questions/10121485/django-testcase-not-use-transactions-on-secondary-database

db рд╕реНрдерд┐рд░рддрд╛ рдХрд╡рд░ рдХреЗ рддрд╣рдд Django рдХреЗ рдЯреЗрд╕реНрдЯрдХреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред

рдореВрд▓ db рд╕реНрдерд┐рд░рддрд╛ рд╕реЗ рдХреЛрдб рдпрд╣рд╛рдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

case = TestCase(methodName='__init__')
case._pre_setup()
request.addfinalizer(case._post_teardown)
request.addfinalizer(_django_cursor_wrapper.disable)

рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕реЗ рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╕реЗ рдкреИрдЪ рдХрд┐рдпрд╛:

case = TestCase(methodName='__init__')
case.multi_db = True
case._pre_setup()
request.addfinalizer(case._post_teardown)
request.addfinalizer(_django_cursor_wrapper.disable)

рдЬрд╛рд╣рд┐рд░ рд╣реИ рдХрд┐ multi_db рдзреНрд╡рдЬ рдореМрдЬреВрдж рд╣реИ рдФрд░ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЧрд▓рдд рдкрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ pytest_django рдореЗрдВ multi_db рд╕рдорд░реНрдерди рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХрд╛ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдмрджрд▓рд╛рд╡ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реИред

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рд╕реБрдЭрд╛рд╡ рд╣реИ рддреЛ рдореИрдВ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдкрд░ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдЕрд╕реНрдерд╛рдпреА рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП multi_db рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдкред рдЗрд╕реЗ conftest.py . рдореЗрдВ рдбрд╛рд▓реЗрдВ

def pytest_sessionstart(session):
    from django.test import TransactionTestCase
    TransactionTestCase.multi_db = True

рд╕рднреА 20 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рдкреИрдЪ рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░реАрдХреНрд╖рдг рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рджреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ рдХрд┐ рдХрд┐рддрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рджреВрд╕рд░реЗ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ рдлрд┐рд░ multi_db рдХреЛ рд╕рддреНрдп рдкрд░ рд╕реЗрдЯ рдХрд░рдирд╛ред

DATABASES = {
    'default': {
        'ENGINE'   : 'django.db.backends.sqlite3',
        'NAME'     : 'default.db',
    },
    'operations': {
        'ENGINE'   : 'django.db.backends.sqlite3',
        'NAME'     : 'operations.db',
    },
}

рдореЗрд░реЗ рдЕрдзрд┐рдХрд╛рдВрд╢/рд╕рднреА рдореЙрдбрд▓ рджреВрд╕рд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ "рдСрдкрд░реЗрд╢рдВрд╕" рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВред рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ Django рдХрд╛ рдЯреЗрд╕реНрдЯрдХреЗрд╕ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдбреАрдмреА рдкрд░ рд▓реЗрдирджреЗрди рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдлреНрд▓рд╢ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдиреНрдп рдирд╣реАрдВ рдЬрдм рддрдХ multi_db=True ред

рдпрд╣рд╛рдВ рдХреБрдЫ рдирдореВрдирд╛ рдкрд░реАрдХреНрд╖рдг рджрд┐рдП рдЧрдП рд╣реИрдВ:

from collection.models import Foo

def test_one(db):
    Foo.objects.create()
    assert Foo.objects.count() == 1

def test_two(db):
    assert Foo.objects.count() == 0

рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдореЗрд░реЗ рдкреИрдЪ рдХрд┐рдП рдЧрдП db рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рд╕рд╛рде рдЖрдЙрдЯрдкреБрдЯ рдпрд╣рд╛рдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

$ py.test multi_db_test/ -vv
======================================= test session starts =======================================
platform linux2 -- Python 2.7.2 -- py-1.4.20 -- pytest-2.5.2 -- bin/python
plugins: django
collected 2 items

multi_db_test/test_foo.py:3: test_one PASSED
multi_db_test/test_foo.py:7: test_two PASSED

==================================== 2 passed in 5.75 seconds =====================================

рдпрд╣рд╛рдБ pytest_django рдХреЗ рдЕрдкрдиреЗ db рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рд╕рд╛рде рдЖрдЙрдЯрдкреБрдЯ рд╣реИ:

$ py.test multi_db_test/ -vv
======================================= test session starts =======================================
platform linux2 -- Python 2.7.2 -- py-1.4.20 -- pytest-2.5.2 -- bin/python
plugins: django
collected 2 items

multi_db_test/test_foo.py:3: test_one PASSED
multi_db_test/test_foo.py:7: test_two FAILED

============================================ FAILURES =============================================
____________________________________________ test_two _____________________________________________

db = None

    def test_two(db):
>       assert Foo.objects.count() == 0
E       assert 1 == 0
E        +  where 1 = <bound method Manager.count of <django.db.models.manager.Manager object at 0x3cd0890>>()
E        +    where <bound method Manager.count of <django.db.models.manager.Manager object at 0x3cd0890>> = <django.db.models.manager.Manager object at 0x3cd0890>.count
E        +      where <django.db.models.manager.Manager object at 0x3cd0890> = Foo.objects

multi_db_test/test_foo.py:8: AssertionError
=============================== 1 failed, 1 passed in 5.85 seconds ===============================

рддреЛ рдПрдХ рддреНрд╡рд░рд┐рдд рд░реВрдк рд╕реЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ multi_db рд╕реНрдерд┐рд░рддрд╛ рдФрд░ pytest.mark.django_db(multi=True) рдПрдХ рдПрдкреАрдЖрдИ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ? рдХрд┐рд╕реА рдФрд░ рдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдмреЗрд╣рддрд░ рд╡рд┐рдЪрд╛рд░ рд╣реИ?

рдпрд╣ рд╡рд╛рдЬрд┐рдм рд▓рдЧрддрд╛ рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреНрдп рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рд╣реИрдВ, рдмреЗрд╣рддрд░ рдпрд╛ рдЕрдиреНрдпрдерд╛ред

рдирдорд╕реНрдХрд╛рд░ред рдХреНрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ multi_db рд╕рдорд░реНрдерди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдЪрд░реНрдЪрд╛ рд╣реИ? рдбреЙрдХреНрд╕ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдХреЛ рд╕рдВрдкрд░реНрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рд▓реЗрдХрд┐рди рдЗрд╕ рдкрд░ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреНрдпрд╛ рд╣реИ?

@slafs рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдмрд╣реБ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЪрд░реНрдЪрд╛/рдЕрдиреБрд░реЛрдз рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВред

multi_db=True рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рджреНрд╡рд┐рддреАрдпрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗрдЯ рдЕрдк рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЕрдЧрд░ рдХреЛрдИ рдЗрд╕ рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЛ рддреИрдпрд╛рд░ рд╣реИ, рддреЛ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ :)

рдореИрдВ рд╢реБрд░реБрдЖрддреА рдкреЛрд╕реНрдЯ рдореЗрдВ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб @ftobia рдЙрд▓реНрд▓реЗрдЦреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди 1.7 рд╕реЗ Django 1.8.4 рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдЗрд╕рдиреЗ рдХрд╛рдо рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ред

рдПрдХ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдмрдЬрд╛рдп multi_db рд╡рд░реНрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдб рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╕реЗрдЯрдЕрдк/рдЯрд┐рдпрд░рдбрд╛рдЙрди рд▓реБрдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП Django рдкрд░рд┐рд╡рд░реНрддрди рдерд╛ред

@ftobia рдХреЗ рдХрд╛рд░реНрдп-рдЖрд╕рдкрд╛рд╕ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЗрдВ рдмрджрд▓рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП

case = TestCase(methodName='__init__')
case.__class__.multi_db = True
case._pre_setup()
request.addfinalizer(case._post_teardown)
request.addfinalizer(_django_cursor_wrapper.disable)

+1:+1:

рдпрд╣ рд╣рдореЗрдВ Django рдЯреЗрд╕реНрдЯ рд░рдирд░ рд╕реЗ pytest рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХ рд░рд╣рд╛ рд╣реИред

рдпрд╣рд╛рдБ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ django_case.multi_db = True рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рди рдХрд░реЗрдВ https://github.com/pytest-dev/pytest-django/blob/master/pytest_django/fixtures.py#L107 ?

+1

+1

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ django_db рдорд╛рд░реНрдХрд░ рдкрд░ рдорд╛рд░реНрдХрд░ рд╣реЛрдиреЗ рд╕реЗ рдореИрдВ рдЕрдЪреНрдЫрд╛ рдПрдкреАрдЖрдИ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛:

@pytest.mark.django_db(transactional=True, multi_db=True)
def test_a():
    pass

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд reset_sequences (рдкреАрдЖрд░ #308) рдпрд╛ serialized_rollback (рдкреАрдЖрд░ #353) рдХреЗ рд╕рдорд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

"рдореБрд╢реНрдХрд┐рд▓" рднрд╛рдЧ рдХрдИ рдбреЗрдЯрд╛рдмреЗрд╕ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП pytest-django рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдЕрдЧрд░ рдХреЛрдИ рдЗрд╕рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ рддреЛ рдореИрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░реВрдВрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдорд░реНрдЬ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реВрдВрдЧрд╛ред рдкреАрдЖрд░ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ рдпрджрд┐ рдпрд╣ рдРрд╕рд╛ рдХреБрдЫ рд╣реИ рдЬреЛ рдЖрдкрдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛!

https://github.com/pytest-dev/pytest-django/pull/397#issuecomment -261987751 рдкрд░ рдХреБрдЫ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдЫреЛрдбрд╝ рджреАрдВ, рдФрд░ рдПрдХ рдкреАрдЖрд░ рдмрдирд╛рдпрд╛, рдЬреЛ рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛: https://githubред com/pytest-dev/pytest-django/pull/431.

рдЕрд╕реНрдерд╛рдпреА рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП multi_db рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдкред рдЗрд╕реЗ conftest.py . рдореЗрдВ рдбрд╛рд▓реЗрдВ

def pytest_sessionstart(session):
    from django.test import TransactionTestCase
    TransactionTestCase.multi_db = True

рдХрд╛рдордХрд╛рдЬ рдХреА рддрд▓рд╛рд╢ рдореЗрдВ рдХрд┐рд╕реА рдФрд░ рдХреЗ рд▓рд┐рдП, рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ multi_db Django 2.2 рдореЗрдВ рдмрд╣рд┐рд╖реНрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╣реИ:

TransactionTestCase.databases = set(settings.DATABASES.keys())

@jcushman рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдкреВрд░реНрдг рд╕реНрдерд┐рд░рддрд╛ рдпрд╛ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?

рдЬреЛ рднреА рдХрд╛рд░рдг рдХреЗ рд▓рд┐рдП, pytest_sessionstart() рд╣рдорд╛рд░реЗ рдЖрдзрд╛рд░ рдореЗрдВ conftest.py рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рдерд╛ред рдорд╛рдирдХ рдкрд╛рдЗрдЯреЗрд╕реНрдЯ monkeypatch рд╕рд╛рдорд╛рди рдХреЗ рд╕рд╛рде #342 рд╕реЗ рдПрдХ рдкреГрд╖реНрда рд▓рд┐рдпрд╛ рдФрд░ рд╣рдорд╛рд░реЗ рдмрд╣реБ-рдбреЗрдЯрд╛рдмреЗрд╕ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░ рдкрд╣реБрдВрдЪреЗ:

# OPTION 1: Function fixture; must be included with tests
@pytest.fixture
def django_db_multiple(monkeypatch, request, settings):
    """
    Ensure all test functions using Django test cases have multiple database
    support. This is mostly/only so that Django will wrap ALL database use with
    atomic blocks like it does for DEFAULT_DB_ALIAS.

    https://github.com/django/django/blob/master/django/test/testcases.py#L903
    https://github.com/pytest-dev/pytest-django/issues/76
    """
    from django.test import TestCase
    from django.test import TransactionTestCase

    db_keys = set(settings.DATABASES.keys())

    monkeypatch.setattr(TestCase, 'databases', db_keys)
    monkeypatch.setattr(TransactionTestCase, 'databases', db_keys)

@pytest.mark.django_db
def test_some_test(django_db_multiple):
    pass

# OPTION 2: Session fixture
@pytest.fixture(autouse=True, scope='session')
def django_db_multiple():
    """
    Ensure all test functions using Django test cases have multiple database
    support. This is mostly/only so that Django will wrap ALL database use with
    atomic blocks like it does for DEFAULT_DB_ALIAS.

    https://github.com/django/django/blob/master/django/test/testcases.py#L903
    https://github.com/pytest-dev/pytest-django/issues/76
    https://github.com/pytest-dev/pytest/issues/1872
    """
    from _pytest.monkeypatch import MonkeyPatch
    from django.test import TestCase
    from django.test import TransactionTestCase
    from django.conf import settings

    db_keys = set(settings.DATABASES.keys())

    monkeypatch = MonkeyPatch()
    monkeypatch.setattr(TestCase, 'databases', db_keys)
    monkeypatch.setattr(TransactionTestCase, 'databases', db_keys)

    yield monkeypatch

    monkeypatch.undo()

_рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рд╣рдо рдПрдХ рд╕рддреНрд░ рд╕реНрдерд┐рд░рддрд╛ рдореЗрдВ рдЪрд▓реЗ рдЧрдПред_

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ Django рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░рдХреЗ pytest рдорд╣рд╛рд╢рдХреНрддрд┐рдпреЛрдВ рдХреЛ рдвреАрд▓рд╛ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЗрд╕ рдмрджрд╕реВрд░рдд (рдЕрднреА рддрдХ рдХрд╛рдо рдХрд░ рд░рд╣реЗ!) рд╣реИрдХ рдХреЗ рд▓рд┐рдП pytest-django рдЖрдВрддрд░рд┐рдХ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдИ рдФрд░ рдкреИрдЪ рдХрд┐рдпрд╛:

from typing import Optional, Type, TypeVar

import pytest
from django.test import TransactionTestCase
from pytest_django.django_compat import is_django_unittest

TestCase = TypeVar('TestCase', bound=TransactionTestCase)


def _django_db_fixture_helper(
    request, django_db_blocker, transactional: bool = False, reset_sequences: bool = False,
) -> Optional[Type[TestCase]]:
    if is_django_unittest(request):
        return None

    if not transactional and 'live_server' in request.fixturenames:
        # Do nothing, we get called with transactional=True, too.
        return None

    django_db_blocker.unblock()
    request.addfinalizer(django_db_blocker.restore)

    if transactional:
        from django.test import TransactionTestCase as DjangoTestCase  # noqa: WPS433

        if reset_sequences:

            class ResetSequenceTestCase(DjangoTestCase):  # noqa: WPS431
                reset_sequences = True

            DjangoTestCase = ResetSequenceTestCase  # type: ignore[misc] # noqa: N806
    else:
        from django.test import TestCase as DjangoTestCase  # type: ignore[no-redef] # noqa: WPS433

    return DjangoTestCase  # type: ignore[return-value]


@pytest.fixture()
def db_case(request, django_db_setup, django_db_blocker):
    """Require a django test database.

    This database will be setup with the default fixtures and will have
    the transaction management disabled. At the end of the test the outer
    transaction that wraps the test itself will be rolled back to undo any
    changes to the database (in case the backend supports transactions).
    This is more limited than the ``transactional_db`` resource but
    faster.

    If multiple database fixtures are requested, they take precedence
    over each other in the following order (the last one wins): ``db``,
    ``transactional_db``, ``django_db_reset_sequences``.
    """
    if 'django_db_reset_sequences' in request.fixturenames:
        request.getfixturevalue('django_db_reset_sequences')
    if (
        'transactional_db' in request.fixturenames
        or 'live_server' in request.fixturenames
    ):
        request.getfixturevalue('transactional_db')
    else:
        django_case: Optional[Type[TransactionTestCase]] = _django_db_fixture_helper(
            request, django_db_blocker, transactional=False,
        )

        def factory(dbs=None):  # noqa: WPS430
            if django_case is None:
                return
            CaseType: Type[TransactionTestCase] = django_case  # noqa: N806
            if dbs is not None:
                class DatabasesSetTestCase(  # noqa: WPS431
                    CaseType,  # type: ignore[valid-type, misc]
                ):
                    databases = dbs
                CaseType = DatabasesSetTestCase  # noqa: N806
            test_case: TransactionTestCase = CaseType(methodName='__init__')
            test_case._pre_setup()  # type: ignore[attr-defined] # noqa: WPS437
            request.addfinalizer(
                test_case._post_teardown,  # type: ignore[attr-defined] # noqa: WPS437
            )

        return factory

рдЗрд╕рдХреЗ рд╕рд╛рде рдХреЛрдИ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

class TestCase(object):

    def test_ok(
        self,
        db_case,
        ...
    ):
        db_case(dbs=('non_default_db_alias',))

рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ db рд╕реНрдерд┐рд░рддрд╛ рдпрд╛ pytest.mark.django_db рдЪрд┐рд╣реНрди рдХреЗ рдмрдЬрд╛рдп рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

@jcushman рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдкреВрд░реНрдг рд╕реНрдерд┐рд░рддрд╛ рдпрд╛ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?

рдЕрдЧрд░ рдХреЛрдИ рдФрд░ рдЗрд╕рдореЗрдВ рдЯрдХрд░рд╛рдПрдЧрд╛ рддреЛ рдЬрд╡рд╛рдм рдЬреЛрдбрд╝рдирд╛ред

рдЖрдкрдХреЛ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ conftest.py рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рд╕реНрдерд┐рд░рддрд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрдард╛рдИ рдЬрд╛рддреА рд╣реИ рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдХрд┐рд╕реА рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

`` `рдкреАрдИ
def pytest_sessionstart (рд╕рддреНрд░):
django.test рдЖрдпрд╛рдд рд╕реЗ TransactionTestCase

TransactionTestCase.databases = set(settings.DATABASES.keys())

````

рдЗрд╕рд▓рд┐рдП рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рдореБрджреНрджрд╛ рдЙрдЪрд┐рдд рдмрд╣реБ-рдбреАрдмреА рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рдЖрддрд╛ рд╣реИред рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЙрд╕рдХреЗ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдВрдж рдХрд░ рджреВрдВрдЧрд╛ред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

WoLpH picture WoLpH  ┬╖  7рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

aljosa picture aljosa  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ryankask picture ryankask  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ojake picture ojake  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

clintonb picture clintonb  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ