#33454: Django 4 TestRunner does not pick up tests correctly.
---------------------------------------------+------------------------
               Reporter:  Thorbenl           |          Owner:  nobody
                   Type:  Bug                |         Status:  new
              Component:  Testing framework  |        Version:  4.0
               Severity:  Normal             |       Keywords:
           Triage Stage:  Unreviewed         |      Has patch:  0
    Needs documentation:  0                  |    Needs tests:  0
Patch needs improvement:  0                  |  Easy pickings:  0
                  UI/UX:  0                  |
---------------------------------------------+------------------------
 Hey!
 We use Django for an online webshop, and want to upgrade to Django 4.
 However, since upgrading on a test branch, we have encountered a problem,
 that did not appear before upgrading:

 We serve two different markets, lets call them Market A and B. Since these
 two markets can have different functionalities, our INSTALLED_APPS gets
 populated like so:
 Here is more information, and the error traces:



 {{{
 INSTALLED_APPS = [
    ...
    'payments', # THIS INCLUDES `BasePayment` Model
    ....
 ]
 }}}




 {{{
 MARKET_SPECIFIC_APPS = {
     MARKET_B: [
         'market_b.apps.MarketBConfig',
         'market_b_payments.apps.MarketBPaymentsConfig'
     ],
     MARKET_A: [
         'market_a.apps.MarketAConfig',
         'market_a_payments.apps.MarketAPaymentsConfig'
     ],
 }
 }}}



 {{{
 if MARKET in MARKET_SPECIFIC_APPS:
     # If there is a market-specific app, add it to INSTALLED_APPS
     INSTALLED_APPS += MARKET_SPECIFIC_APPS[MARKET]
 }}}



 {{{
 ======================================================================
 ERROR [0.004s]: market_a.test_redirects (unittest.loader._FailedTest)
 ----------------------------------------------------------------------
 ImportError: Failed to import test module: market_a.test_redirects
 Traceback (most recent call last):
   File
 
"/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/loader.py",
 line 436, in _find_test_path
     module = self._get_module_from_name(name)
   File
 
"/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/loader.py",
 line 377, in _get_module_from_name
     __import__(name)
   File "/e-commerce/market_a/test_redirects.py", line 5, in <module>
     from market_a.models import AdvertisementIdMapping
   File "/e-commerce/market_a/models.py", line 14, in <module>
     class MigratedMissingData(models.Model):
   File "/e-commerce/venv/lib/python3.9/site-
 packages/django/db/models/base.py", line 113, in __new__
     raise RuntimeError(
 RuntimeError: Model class market_a.models.MigratedMissingData doesn't
 declare an explicit app_label and isn't in an application in
 INSTALLED_APPS.


 ======================================================================
 ERROR [0.000s]: market_a_payments.models (unittest.loader._FailedTest)
 ----------------------------------------------------------------------
 ImportError: Failed to import test module: market_a_payments.models
 Traceback (most recent call last):
   File
 
"/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/loader.py",
 line 470, in _find_test_path
     package = self._get_module_from_name(name)
   File
 
"/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/loader.py",
 line 377, in _get_module_from_name
     __import__(name)
   File "/e-commerce/market_a_payments/models/__init__.py", line 1, in
 <module>
     from .payment import Payment
   File "/e-commerce/market_a_payments/models/payment.py", line 12, in
 <module>
     class Payment(BasePayment):
   File "/e-commerce/venv/lib/python3.9/site-
 packages/django/db/models/base.py", line 113, in __new__
     raise RuntimeError(
 RuntimeError: Model class market_a_payments.models.payment.Payments
 doesn't declare an explicit app_label and isn't in an application in
 INSTALLED_APPS.


 ======================================================================
 ERROR [0.000s]: market_a_payments.tests (unittest.loader._FailedTest)
 ----------------------------------------------------------------------
 ImportError: Failed to import test module: market_a_payments.tests
 Traceback (most recent call last):
   File
 
"/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/loader.py",
 line 436, in _find_test_path
     module = self._get_module_from_name(name)
   File
 
"/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/loader.py",
 line 377, in _get_module_from_name
     __import__(name)
   File "/e-commerce/market_a_payments/tests.py", line 20, in <module>
     from market_a_payments.models import Payment
   File "/e-commerce/market_a_payments/models/__init__.py", line 1, in
 <module>
     from .payment import Payment
   File "/e-commerce/market_a_payments/models/payment.py", line 12, in
 <module>
     class Payment(BasePayment):
   File "/e-commerce/venv/lib/python3.9/site-
 packages/django/db/models/base.py", line 113, in __new__
     raise RuntimeError(
 RuntimeError: Model class market_a_payments.models.payment.Payments
 doesn't declare an explicit app_label and isn't in an application in
 INSTALLED_APPS.
 }}}

 all these test sit in an app called `market_a_payments`
 This app should not be discovered when running tests for market b:


 {{{
 MARKET=MARKET_B python3 manage.py test --tag market_b --timing
 }}}


 I can try to share a bit of the test, and where it fails according to the
 stack:


 {{{
 from urllib.parse import quote
 from django.test import TestCase, Client
 from core.mocks import Mocks
 ... other imports

 MARKET_A = "market_a"
 MARKET_B = "market_b"


 def valid_market(market: str):
     return market in [MARKET_A, MARKET_B]

 def override_market(market):
     if not valid_market(market):
         raise Exception(f"{market} is not a valid market.")
     return tag(market)

 class TestRedirects(TestCase):

     @override_market(MARKET_A)
     def test_landing_page_redirects(self):
         client = Client()
         cases = {
        ....
         }

         for input, dst in cases.items():
             with self.subTest(input):
                 response = client.get(input, secure=False, follow=True)
                 self.assertRedirects(response, dst, 301, 200)

 }}}



 Line 12 is actually `class TestRedirects(TestCase):`

 Django 3.2.8 worked super fine, so i assume sth in the test runner must
 have changed from that version to 4, as our code remained unchanged in
 this test.
 Annotating the `class` with  the `@override_market(MARKET_A)` didnt do
 anything either.

 Test are run on circleci using `circleci/python:3.9.7-node-browsers`
 image.
 The overall goal here is that this test only gets run/discovered when the
 specified market gets hit.
 so `MARKET=MARKET_B python3 manage.py test --tag market_b --timing` should
 not discover or run this test. taking off `--parallel` as suggested didnt
 do anything either.

 Minimal reproduction here:
 https://github.com/Thorbenl/django4-testrunner.git

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33454>
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/051.e76adb8399dcecbce394d360c06bedbe%40djangoproject.com.

Reply via email to