unittest test discovery: regular packages vs. namespace packages

Ralf M. Ralf_M at t-online.de
Fri Jul 10 13:33:15 EDT 2020


Hello,

to my last question I got many helpful and enlightening answers.
So I try again with a completely different topic.

https://docs.python.org/3/library/unittest.html#test-discovery
says about test discovery:

"Unittest supports simple test discovery. In order to be compatible with 
test discovery, all of the test files must be modules or packages 
(including namespace packages) importable from the top-level directory 
of the project (this means that their filenames must be valid identifiers).
[...]
Note: As a shortcut, python -m unittest is the equivalent of python -m 
unittest discover."

Therefore I expected
python -m unittest
to run all tests in the current directory and its subdirectories, 
regardless of whether the subdirectories contain a __init__.py or not.

However, this only works for me if an (empty) __init__.py is present, 
i.e. the package is a regular one. As soon as I delete the __init__.py, 
turning the regular package into a namespace package, unittest doesn't 
find the test files any more. When I recreate __init__.py, the test file 
(e.g. test_demo.py) is found again. See demo session further down.

I tried the following Python versions, all showed the same behavior:
  Python 3.7.1 (python.org) on Win10
  Python 3.7.4 (python.org) on Win7
  Python 3.7.7 (Anaconda) on Win10
  Python 3.8.3 (Anaconda) on Win10

What am I missing / misunderstanding?


Demo session:

F:\demo>dir /s /b
F:\demo\test_we4n7uke5vx
F:\demo\test_we4n7uke5vx\test_demo.py
F:\demo\test_we4n7uke5vx\__init__.py

F:\demo>type test_we4n7uke5vx\__init__.py

F:\demo>type test_we4n7uke5vx\test_demo.py
import unittest
class SomeTestCase(unittest.TestCase):
     def test_fail_always(self):
         self.assertTrue(False)

F:\demo>py -m unittest
F
======================================================================
FAIL: test_fail_always (test_we4n7uke5vx.test_demo.SomeTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "F:\demo\test_we4n7uke5vx\test_demo.py", line 4, in test_fail_always
     self.assertTrue(False)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

F:\demo>del test_we4n7uke5vx\__init__.py

F:\demo>py -m unittest

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

F:\demo>echo # > test_we4n7uke5vx\__init__.py

F:\demo>py -m unittest
F
======================================================================
FAIL: test_fail_always (test_we4n7uke5vx.test_demo.SomeTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "F:\demo\test_we4n7uke5vx\test_demo.py", line 4, in test_fail_always
     self.assertTrue(False)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

F:\demo>


More information about the Python-list mailing list