[Tutor] Do not understand why test is running.
Peter Otten
__peter__ at web.de
Fri Aug 21 08:16:14 CEST 2015
boB Stepp wrote:
> On Thu, Aug 20, 2015 at 10:13 PM, Steven D'Aprano <steve at pearwood.info>
> wrote:
>> On Thu, Aug 20, 2015 at 09:01:50PM -0500, boB Stepp wrote:
>>
>>
>>> import unittest
>>>
>>> # import modules to be tested:
>>> import mcm.db.manager
>>>
>>> class ManagerTestCase(unittest.TestCase):
>>> def setUp(self):
>>> # Insert setup code here...
>>> pass
>>>
>>> def test_open_db(self):
>>> pass
>>>
>>> def tearDown(self):
>>> # Insert tear-down code here...
>>> pass
>>>
>>> #if __name__ == "__main__":
>>> # unittest.main()
>>
>>
>> The two commented out lines at the end would, if uncommented, run
>> unittest.main() if and only if you are running this specific module as a
>> thread. In other words, if you were to run:
>>
>> python /path/to/the/test.py
>>
>> then __name__ would be set to the string "__main__", the if clause would
>> trigger, and unittest.main() would run. Since those lines are commented
>> out, that cannot happen.
>
> Okay, I uncommented those two lines and got:
>
> E:\Projects\mcm>py -m unittest ./mcm/test/db/test_manager.py
> Traceback (most recent call last):
> File "C:\Python34\lib\runpy.py", line 170, in _run_module_as_main
> "__main__", mod_spec)
> File "C:\Python34\lib\runpy.py", line 85, in _run_code
> exec(code, run_globals)
> File "C:\Python34\lib\unittest\__main__.py", line 18, in <module>
> main(module=None)
> File "C:\Python34\lib\unittest\main.py", line 92, in __init__
> self.parseArgs(argv)
> File "C:\Python34\lib\unittest\main.py", line 139, in parseArgs
> self.createTests()
> File "C:\Python34\lib\unittest\main.py", line 146, in createTests
> self.module)
> File "C:\Python34\lib\unittest\loader.py", line 146, in
> loadTestsFromNames
> suites = [self.loadTestsFromName(name, module) for name in names]
> File "C:\Python34\lib\unittest\loader.py", line 146, in <listcomp>
> suites = [self.loadTestsFromName(name, module) for name in names]
> File "C:\Python34\lib\unittest\loader.py", line 105, in
> loadTestsFromName
> module = __import__('.'.join(parts_copy))
> ValueError: Empty module name
>
> Now what?
Yea, breaking things is an art form ;)
If you want to trigger the
if __name__ == "__main__": ...
you have to invoke the test script with
py ./mcm/test/db/test_manager.py
the same way you would invoke any other script.
py -m unittest <more args>
runs the unittest module which is free to do what it wants with its
arguments. Let's see:
$ python3 -m unittest -h
usage: python3 -m unittest [-h] [-v] [-q] [-f] [-c] [-b] [tests [tests ...]]
positional arguments:
tests a list of any number of test modules, classes and test
methods.
optional arguments:
-h, --help show this help message and exit
-v, --verbose Verbose output
-q, --quiet Quiet output
-f, --failfast Stop on first fail or error
-c, --catch Catch ctrl-C and display results so far
-b, --buffer Buffer stdout and stderr during tests
Examples:
python3 -m unittest test_module - run tests from test_module
python3 -m unittest module.TestClass - run tests from
module.TestClass
python3 -m unittest module.Class.test_method - run specified test method
usage: python3 -m unittest discover [-h] [-v] [-q] [-f] [-c] [-b] [-s START]
[-p PATTERN] [-t TOP]
optional arguments:
-h, --help show this help message and exit
-v, --verbose Verbose output
-q, --quiet Quiet output
-f, --failfast Stop on first fail or error
-c, --catch Catch ctrl-C and display results so far
-b, --buffer Buffer stdout and stderr during tests
-s START, --start-directory START
Directory to start discovery ('.' default)
-p PATTERN, --pattern PATTERN
Pattern to match tests ('test*.py' default)
-t TOP, --top-level-directory TOP
Top level directory of project (defaults to start
directory)
For test discovery all test modules must be importable from the top level
directory of the project.
Did you spot the relevant lines? It's
"""
positional arguments:
tests a list of any number of test modules, classes and test
methods.
"""
"""
or
python3 -m unittest module.TestClass - run tests from
module.TestClass
"""
Unfortunately the implementation is dumb enough to interpret
./mcm/test/db/test_manager.py
as class "/mcm/test/db/test_manager.py" in module "". You get the same
complaint as for ".foo" (or just "."):
$ python3 -m unittest .foo
Traceback (most recent call last):
File "/usr/lib/python3.4/runpy.py", line 170, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.4/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/usr/lib/python3.4/unittest/__main__.py", line 18, in <module>
main(module=None)
File "/usr/lib/python3.4/unittest/main.py", line 92, in __init__
self.parseArgs(argv)
File "/usr/lib/python3.4/unittest/main.py", line 139, in parseArgs
self.createTests()
File "/usr/lib/python3.4/unittest/main.py", line 146, in createTests
self.module)
File "/usr/lib/python3.4/unittest/loader.py", line 146, in
loadTestsFromNames
suites = [self.loadTestsFromName(name, module) for name in names]
File "/usr/lib/python3.4/unittest/loader.py", line 146, in <listcomp>
suites = [self.loadTestsFromName(name, module) for name in names]
File "/usr/lib/python3.4/unittest/loader.py", line 105, in
loadTestsFromName
module = __import__('.'.join(parts_copy))
ValueError: Empty module name
More information about the Tutor
mailing list