#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/python@3.9/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/python@3.9/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/python@3.9/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/python@3.9/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/python@3.9/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/python@3.9/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 django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/051.e76adb8399dcecbce394d360c06bedbe%40djangoproject.com.

Reply via email to