#32409: TestCase async tests are not transaction-aware
-------------------------------------+-------------------------------------
     Reporter:  David                |                    Owner:  KangDo96
         Type:  New feature          |                   Status:  assigned
    Component:  Testing framework    |                  Version:  3.1
     Severity:  Normal               |               Resolution:
     Keywords:  TestCase, async,     |             Triage Stage:  Accepted
  transaction                        |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Oleg):

 I have faced the same issue when writing tests for API implemented using
 `strawberry-graphql-django`.
 Strawberry converts django calls using `sync_to_async(func,
 thread_sensitive=True)`.
 Initially, I've converted tests to fully async ones, for example:
 {{{#!python
 @pytest.mark.django_db
 async def test_currencies(setup_for_currency):
     schema = gql.Schema(query=Query)
     result = await schema.execute(
         """
         query {
           currency {
             currencies {
               name
             }
           }
         }
         """
     )
 }}}
 As a result, tests based on `TestCase` don't work, while
 `TransactionTestCase` based do work. This happens because fixture
 `setup_for_currency` and `TestCase` setup and tear-down are executed
 against a different DB connection.
 However, if I change upper-level test-case to synchronous one, everything
 works!
 {{{#!python
 @pytest.mark.django_db
 def test_currencies(setup_for_currency):
     schema = gql.Schema(query=Query)
     result = async_to_sync(schema.execute)(
         """
         query {
           currency {
             currencies {
               name
             }
           }
         }
         """
     )
 }}}

 Looks like this happens according to `asgiref` documentation:
 >If the outermost program is async (i.e. SyncToAsync is outermost), then
 >this will be a dedicated single sub-thread that all sync code runs in,
 >one after the other. If the outermost program is sync (i.e. AsyncToSync
 is
 >outermost), this will just be the main thread. This is achieved by idling
 >with a CurrentThreadExecutor while AsyncToSync is blocking its sync
 parent,
 >rather than just blocking.

 However, this behavior is still very confusing, I have no idea if this
 could be fixed.
 Using `TransactionTestCase` everywhere is a no-no for large projects, but
 my solution still looks like a hack.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32409#comment:20>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070181e51f05c9-c29cd252-70c9-4656-a682-b2bb414fe1d7-000000%40eu-central-1.amazonses.com.

Reply via email to