#35402: DatabaseFeatures.django_test_skips crashes when it references a class in
another test module
-------------------------------------+-------------------------------------
Reporter: Tim | Owner: nobody
Graham |
Type: Bug | Status: new
Component: Database | Version: dev
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Since the introduction of `DatabaseFeatures.django_test_skips` (#32178),
I've used it to skip test classes, however, this can crash if there are
multiple test modules in a package.
To reproduce, first make this modification to skip a class
{{{#!diff
diff --git a/django/db/backends/sqlite3/features.py
b/django/db/backends/sqlite3/features.py
index d95c6fb2d1..51229fe970 100644
--- a/django/db/backends/sqlite3/features.py
+++ b/django/db/backends/sqlite3/features.py
@@ -68,8 +68,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
def django_test_skips(self):
skips = {
"SQLite stores values rounded to 15 significant digits.": {
- "model_fields.test_decimalfield.DecimalFieldTests."
- "test_fetch_from_db_without_float_rounding",
+ "model_fields.test_decimalfield.DecimalFieldTests",
},
"SQLite naively remakes the table on field alteration.": {
}}}
Then try to execute a test module in `model_fields` besides the one with
the skip:
{{{#!shell
$ ./tests/runtests.py model_fields.test_autofield
Testing against Django installed in '/home/tim/code/django/django' with up
to 3 processes
Found 62 test(s).
Creating test database for alias 'default'...
Traceback (most recent call last):
File "/home/tim/code/django/django/utils/module_loading.py", line 30, in
import_string
return cached_import(module_path, class_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/tim/code/django/django/utils/module_loading.py", line 16, in
cached_import
return getattr(module, class_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'model_fields' has no attribute 'test_decimalfield'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/tim/code/django/./tests/runtests.py", line 784, in <module>
failures = django_tests(
^^^^^^^^^^^^^
File "/home/tim/code/django/./tests/runtests.py", line 422, in
django_tests
failures = test_runner.run_tests(test_labels)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/tim/code/django/django/test/runner.py", line 1066, in
run_tests
old_config = self.setup_databases(
^^^^^^^^^^^^^^^^^^^^^
File "/home/tim/code/django/django/test/runner.py", line 964, in
setup_databases
return _setup_databases(
^^^^^^^^^^^^^^^^^
File "/home/tim/code/django/django/test/utils.py", line 206, in
setup_databases
connection.creation.create_test_db(
File "/home/tim/code/django/django/db/backends/base/creation.py", line
102, in create_test_db
self.mark_expected_failures_and_skips()
File "/home/tim/code/django/django/db/backends/base/creation.py", line
356, in mark_expected_failures_and_skips
test_case = import_string(test_case_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/tim/code/django/django/utils/module_loading.py", line 32, in
import_string
raise ImportError(
ImportError: Module "model_fields" does not define a "test_decimalfield"
attribute/class
}}}
A naive fix:
{{{#!diff
diff --git a/django/db/backends/base/creation.py
b/django/db/backends/base/creation.py
index 6856fdb596..f6cc270b16 100644
--- a/django/db/backends/base/creation.py
+++ b/django/db/backends/base/creation.py
@@ -350,6 +350,9 @@ class BaseDatabaseCreation:
test_app = test_name.split(".")[0]
# Importing a test app that isn't installed raises
RuntimeError.
if test_app in settings.INSTALLED_APPS:
+ # If this is a a test class, it may need to be
imported.
+ if test_name.count(".") == 2:
+ import_string(test_name)
test_case = import_string(test_case_name)
test_method = getattr(test_case, test_method_name)
setattr(test_case, test_method_name,
skip(reason)(test_method))
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/35402>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.