Opened 4 years ago

Closed 4 years ago

#32532 closed Cleanup/optimization (fixed)

Provide friendlier error if a file path is passed as a test label when running tests

Reported by: Chris Jerdonek Owned by: Chris Jerdonek
Component: Testing framework Version: 3.1
Severity: Normal Keywords: DiscoverRunner, test labels
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently, if a user passes a file path as a test label to DiscoverRunner, they will get a somewhat unfriendly error that looks something like the following:

$ ./runtests.py test_runner/tests.py 
Testing against Django installed in '.../django/django' with up to 8 processes
Traceback (most recent call last):
  File "./runtests.py", line 593, in <module>
    options.timing,
  File "./runtests.py", line 325, in django_tests
    failures = test_runner.run_tests(test_labels or get_installed())
  File ".../django/django/test/runner.py", line 721, in run_tests
    suite = self.build_suite(test_labels, extra_tests)
  File ".../django/django/test/runner.py", line 612, in build_suite
    suite.addTests(tests)
  File ".../unittest/suite.py", line 57, in addTests
    for test in tests:
TypeError: 'NoneType' object is not iterable

This is because DiscoverRunner.build_suite() starts out with tests = None in each iteration of the loop and doesn't have an else clause for the file path case:
https://github.com/django/django/blob/6f5dbe9dbe45b23b3befe4f1cd2ea13b6049ab96/django/test/runner.py#L574-L600

I imagine this is a common error because the help string tells the user to use "paths":

"Optional path(s) to test modules; e.g. "i18n" or "i18n.tests.TranslationTests.test_lazy_objects".

but without saying that file paths aren't allowed.

A more friendly error message could tell the user that they provided a path to a file, but that only dotted module paths and directory paths are supported.

Change History (12)

comment:1 by Chris Jerdonek, 4 years ago

Another option would be to support passing file paths, but that could be done separately, after first doing the easier thing of providing a nicer error message.

comment:2 by Mariusz Felisiak, 4 years ago

Easy pickings: set
Triage Stage: UnreviewedAccepted

comment:3 by Chris Jerdonek, 4 years ago

I would suggest that this not be done until after #32540, since it affects the if logic.

comment:4 by Chris Jerdonek, 4 years ago

Owner: changed from nobody to Chris Jerdonek
Status: newassigned

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

In 235d23cf:

Refs #32532 -- Added DiscoverRunner.load_tests_for_label().

comment:7 by Mariusz Felisiak, 4 years ago

Has patch: unset

comment:9 by Chris Jerdonek, 4 years ago

Easy pickings: unset

With my posted patch, the new error will look like this:

$ ./runtests.py test_runner/tests.py
Testing against Django installed in '.../django/django' with up to 8 processes
Traceback (most recent call last):
  ...
RuntimeError: One of the test labels is a path to a file: 'test_runner/tests.py'
Test labels that are paths but not importable as names can only be directories.

(By the way, I unchecked "easy" because this wasn't necessarily so easy given that is_discoverable() had to be broken up to get the info needed for the patch.)

comment:10 by Mariusz Felisiak, 4 years ago

Triage Stage: AcceptedReady for checkin

comment:11 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

In 0af81b2:

Refs #32532 -- Replaced is_discoverable() with try_importing().

comment:12 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In a89e975c:

Fixed #32532 -- Made DiscoverRunner raise RuntimeError when a test label is a file path.

Note: See TracTickets for help on using tickets.
Back to Top