Discussion:
[Tutor] Do not understand why test is running.
boB Stepp
2015-08-21 02:01:50 UTC
Permalink
I adopted Peter's suggestions (I think!) and now have these two paths
that are pertinent to my questions:

Projects/mcm/mcm/db/manager.py # The module I am beginning to write tests for.

Projects/mcm/test/db/test_manager.py # The file for my module tests.

The test code currently is:

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()

Out of curiosity, I changed the last two lines to comments, as I am
still feeling my way around this package structure and how things
work. I was surprised when I ran my test now:

E:\Projects\mcm>py -m unittest discover -v
test_open_db (test.db.test_manager.ManagerTestCase) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Obviously I was not expecting this! Why did the test run? I thought
it would not happen without those final two lines.
--
boB
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Steven D'Aprano
2015-08-21 03:13:21 UTC
Permalink
Post by boB Stepp
import unittest
import mcm.db.manager
# Insert setup code here...
pass
pass
# Insert tear-down code here...
pass
# 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.

But that's not the only way to run unit tests. Another way to run unit
tests is to tell the unittest module to run whatever tests it discovers
Post by boB Stepp
Out of curiosity, I changed the last two lines to comments, as I am
still feeling my way around this package structure and how things
E:\Projects\mcm>py -m unittest discover -v
test_open_db (test.db.test_manager.ManagerTestCase) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Obviously I was not expecting this! Why did the test run? I thought
it would not happen without those final two lines.
No, although they both involve unittest, the method of invoking unittest
are different. What you actually did was:

"Hey unittest, see what tests you can discover, and run those tests."

instead of:

"Hey Python, run this script."
(script says) "Hey unittest, run the tests you find inside me."
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
boB Stepp
2015-08-21 04:09:55 UTC
Permalink
Post by Steven D'Aprano
Post by boB Stepp
import unittest
import mcm.db.manager
# Insert setup code here...
pass
pass
# Insert tear-down code here...
pass
# 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
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?

Scratching my sleepy head...
boB
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Peter Otten
2015-08-21 06:16:14 UTC
Permalink
Post by boB Stepp
Post by Steven D'Aprano
Post by boB Stepp
import unittest
import mcm.db.manager
# Insert setup code here...
pass
pass
# Insert tear-down code here...
pass
# 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
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.
E:\Projects\mcm>py -m unittest ./mcm/test/db/test_manager.py
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


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alex Kleider
2015-08-21 13:26:11 UTC
Permalink
Post by Peter Otten
Yea, breaking things is an art form ;)
$ python3 -m unittest -h
usage: python3 -m unittest [-h] [-v] [-q] [-f] [-c] [-b] [tests [tests ...]]
.....
Post by Peter Otten
For test discovery all test modules must be importable from the top level
directory of the project.
How is "top level directory of the project" defined in this context?
Is it as far up as one can travel while passing through directories
containing an __init__.py file?


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Laura Creighton
2015-08-21 15:29:17 UTC
Permalink
Post by Alex Kleider
Post by Peter Otten
Yea, breaking things is an art form ;)
$ python3 -m unittest -h
usage: python3 -m unittest [-h] [-v] [-q] [-f] [-c] [-b] [tests [tests ...]]
.....
Post by Peter Otten
For test discovery all test modules must be importable from the top level
directory of the project.
How is "top level directory of the project" defined in this context?
Is it as far up as one can travel while passing through directories
containing an __init__.py file?
With python3 you don't need an __init__.py file to have a module,
see: https://www.python.org/dev/peps/pep-0420/

... scratching head ....

So I suppose you could make a test module that is importable
from the top level directory, but doesn't have an __init__.py file.

... is that true? ... more scratching ...

Laura

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
boB Stepp
2015-08-21 13:58:30 UTC
Permalink
Post by Peter Otten
Post by boB Stepp
Post by Steven D'Aprano
Post by boB Stepp
import unittest
import mcm.db.manager
# Insert setup code here...
pass
pass
# Insert tear-down code here...
pass
# 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
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.
E:\Projects\mcm>py -m unittest ./mcm/test/db/test_manager.py
In the cold light of morning, I see that in this invocation, the path
is wrong. But even if I correct it, I get the same results:

e:\Projects\mcm>py -m unittest ./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
Post by Peter Otten
Yea, breaking things is an art form ;)
Alas! I am still artless because if I do as you suggest
Post by Peter Otten
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.
e:\Projects\mcm>py ./test/db/test_manager.py
Traceback (most recent call last):
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'


This is using the path correction I mention above. (But just to be
certain, I also did the exact path Peter gave with the same results.)
Post by Peter Otten
py -m unittest <more args>
runs the unittest module which is free to do what it wants with its
The reason that I have been trying to invoke this individual test
module the way I have is because in the docs it says:

26.3.2. Command-Line Interface

The unittest module can be used from the command line to run tests
from modules, classes or even individual test methods:

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

You can pass in a list with any combination of module names, and fully
qualified class or method names.

Test modules can be specified by file path as well:

python -m unittest tests/test_something.py

This allows you to use the shell filename completion to specify the
test module. The file specified must still be importable as a module.
The path is converted to a module name by removing the ‘.py’ and
converting path separators into ‘.’

So I am still quite confused!

Uh, oh, I have to leave for work. Peter, I have not made it to the
rest of your comments yet. That will have to wait till this evening,
but many thanks for the assistance! If the answer is in your
remaining comments, then I apologize for the additional noise in
advance!!

boB
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
Peter Otten
2015-08-22 08:18:45 UTC
Permalink
Post by boB Stepp
In the cold light of morning, I see that in this invocation, the path
e:\Projects\mcm>py -m unittest ./test/db/test_manager.py
[...]
Post by boB Stepp
ValueError: Empty module name
Make sure that there are files

./test/__init__.py
./test/db/__init__.py

and then try

py -m unittest test.db.test_manager
Post by boB Stepp
e:\Projects\mcm>py ./test/db/test_manager.py
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'
Make sure the parent directory of the mcm package (I believe this is
E:\Projects\mcm) is in your PYTHONPATH, then try again.


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
boB Stepp
2015-08-23 15:42:25 UTC
Permalink
Post by Peter Otten
Post by boB Stepp
In the cold light of morning, I see that in this invocation, the path
e:\Projects\mcm>py -m unittest ./test/db/test_manager.py
[...]
Post by boB Stepp
ValueError: Empty module name
Make sure that there are files
./test/__init__.py
./test/db/__init__.py
I had done this.
Post by Peter Otten
and then try
py -m unittest test.db.test_manager
I *thought* that I had done this, but perhaps...
Post by Peter Otten
Post by boB Stepp
e:\Projects\mcm>py ./test/db/test_manager.py
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'
Make sure the parent directory of the mcm package (I believe this is
E:\Projects\mcm) is in your PYTHONPATH, then try again.
... I was not in the directory, E:\Projects\mcm. It is my
understanding that if I start in a particular directory when I invoke
Python, then it looks in that location first in PYTHONPATH. Anyway,
typing py -m unittest test.db.test_manager from this location works
(And now makes sense.).

But I still have remaining questions to clear up:

Peter said earlier in this thread:

------------------------------------------------
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.
-------------------------------------------------

If I try this or begin in E:\Projects\mcm and type py
./test/db/test_manager.py I get

E:\Projects\mcm>py ./test/db/test_manager.py
Traceback (most recent call last):
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'


I don't understand why this is the case. I did various experiments
with different file structures for the project, when I put the
test_manager.py file in the same directory as the module file being
tested, manager.py, then (after adjusting the import statement in
test_manager.py appropriately) typing py test_manager.py runs the unit
tests. So, why does the above not work? Why does it return "No
module named 'mcm'"? Especially in the context that now test
discovery has no problem and runs correctly and test.db.test_manager
runs correctly.

And am I misreading the docs at
https://docs.python.org/3/library/unittest.html#test-discovery:

-------------------------------------------------------------------------------------------------------------------
26.3.2. Command-Line Interface

[...]

Test modules can be specified by file path as well:

python -m unittest tests/test_something.py

This allows you to use the shell filename completion to specify the
test module. The file specified must still be importable as a module.
The path is converted to a module name by removing the ‘.py’ and
converting path separators into ‘.’
--------------------------------------------------------------------------------------------------------------------

According to this, from E:\Projects\mcm, I should be able to type

py -m unittest ./test/db/test_manager.py

but this continues to result in:

------------------------------------------------------------------------------------
E:\Projects\mcm>py -m unittest ./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
--------------------------------------------------------------------------------------

I believe that I understand Peter's point earlier, but if I am reading
the docs correctly, I should be able to do this. And in fact while I
was experimenting with different directory structures, I found some
that would indeed allow me to invoke unit tests by designating the
file path.

So, I can proceed with my project, but I still don't understand these
two issues.

boB
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/list
Steven D'Aprano
2015-08-23 16:37:06 UTC
Permalink
On Sun, Aug 23, 2015 at 10:42:25AM -0500, boB Stepp wrote:

[...]
Post by boB Stepp
If I try this or begin in E:\Projects\mcm and type py
./test/db/test_manager.py I get
E:\Projects\mcm>py ./test/db/test_manager.py
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'
I don't understand why this is the case.
Without seeing the complete structure of your project, I cannot be sure,
but I can think of at least two problems:

1) Does the mcm directory contain a file called __init__.py? If not,
then Python will not recognise it as a module and `import mcm` will
fail.

2) Even if mcm contains a __init__.py file, the directory itself must be
located in your PYTHONPATH. If you run this:

py -c "import sys; print(sys.path)"

it will show you the directories in the PYTHONPATH that are searched for
a module called mcm. Given that your directory is E:\Projects\mcm, that
implies that E:\Projects\ must be in the search path in order to locate
mcm as a module.

Think of it this way... simplified (very simplified!) Python does this
when you try to import a module:

# `import spam` pseudo-code
for directory in sys.path:
filenames = os.listdir(directory)
for name in filenames:
if os.path.isfile(name) and name == "spam.py":
load(directory\spam.py)
elif os.path.isdir(name) and name == "spam":
if os.path.exists(directory\spam\__init__.py):
load(directory\spam\__init__.py)


There's more, of course -- the real import code is much more complex, it
handles cached modules in sys.modules, compiled .pyc and .pyo files, zip
files, custom importers, and much more. And I daresay it is more
efficient than the pseudo-code I show above.

But the important factor is that none of the directories in the
PYTHONPATH are themselves considered modules, only their contents can be
considered modules. So, if the current directory is

E:\Projects\mcm

then that directory will be added to the PYTHONPATH, sure enough. But
there is nothing inside that directory called mcm, you need either:

E:\Projects\mcm\mcm.py

or

E:\Projects\mcm\mcm\__init__.py

in order to import it. Or you can add E:\Projects to the PYTHONPATH. Or
move up a level, to E:\Projects, and run your code from there.

To put it another way, Python will look *inside* the current directory
for modules to import, but it won't look *at* the current directory as a
module to import.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Peter Otten
2015-08-23 16:47:49 UTC
Permalink
Post by boB Stepp
Post by Peter Otten
Post by boB Stepp
In the cold light of morning, I see that in this invocation, the path
e:\Projects\mcm>py -m unittest ./test/db/test_manager.py
[...]
Post by boB Stepp
ValueError: Empty module name
Make sure that there are files
./test/__init__.py
./test/db/__init__.py
I had done this.
Post by Peter Otten
and then try
py -m unittest test.db.test_manager
I *thought* that I had done this, but perhaps...
Post by Peter Otten
Post by boB Stepp
e:\Projects\mcm>py ./test/db/test_manager.py
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'
Make sure the parent directory of the mcm package (I believe this is
E:\Projects\mcm) is in your PYTHONPATH, then try again.
... I was not in the directory, E:\Projects\mcm. It is my
understanding that if I start in a particular directory when I invoke
Python, then it looks in that location first in PYTHONPATH.
No, it looks in the location of the script, not in the working directory:

$ mkdir sub
$ echo 'print("hello")' > foo.py
$ echo 'import foo' > main.py
$ python3 main.py
hello

That's the normal situation as the main script you're working on is
typically in the working directory. Let's move it:

$ mv main.py sub
$ python3 sub/main.py
Traceback (most recent call last):
File "sub/main.py", line 1, in <module>
import foo
ImportError: No module named 'foo'

You have to add the working directory explicitly, e. g.:

$ PYTHONPATH=. python3 sub/main.py
hello
Post by boB Stepp
Anyway,
typing py -m unittest test.db.test_manager from this location works
(And now makes sense.).
------------------------------------------------
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.
-------------------------------------------------
If I try this or begin in E:\Projects\mcm and type py
./test/db/test_manager.py I get
E:\Projects\mcm>py ./test/db/test_manager.py
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'
I don't understand why this is the case. I did various experiments
with different file structures for the project, when I put the
test_manager.py file in the same directory as the module file being
tested, manager.py, then (after adjusting the import statement in
test_manager.py appropriately) typing py test_manager.py runs the unit
tests. So, why does the above not work? Why does it return "No
module named 'mcm'"? Especially in the context that now test
discovery has no problem and runs correctly and test.db.test_manager
runs correctly.
And am I misreading the docs at
-------------------------------------------------------------------------------------------------------------------
Post by boB Stepp
26.3.2. Command-Line Interface
[...]
python -m unittest tests/test_something.py
This allows you to use the shell filename completion to specify the
test module. The file specified must still be importable as a module.
The path is converted to a module name by removing the ‘.py’ and
converting path separators into ‘.’
I didn't know this.
Post by boB Stepp
According to this, from E:\Projects\mcm, I should be able to type
py -m unittest ./test/db/test_manager.py
Let's process the argument you provide following the above recipe:

(1) Remove .py

"./test/db/test_manager"

(2) Replace / with .

"..test.db.test_manager"

Do you see now why
[...]
Post by boB Stepp
File "C:\Python34\lib\unittest\loader.py", line 105, in
loadTestsFromName
module = __import__('.'.join(parts_copy))
ValueError: Empty module name
?

Without the leading ./ it will probably work.
Post by boB Stepp
I believe that I understand Peter's point earlier, but if I am reading
the docs correctly, I should be able to do this.
While I don't think it's a bug you might still file a feature request on
bugs.python.org.

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/lis
Steven D'Aprano
2015-08-24 01:41:50 UTC
Permalink
Post by boB Stepp
... I was not in the directory, E:\Projects\mcm. It is my
understanding that if I start in a particular directory when I invoke
Python, then it looks in that location first in PYTHONPATH.
I'm gobsmacked. It appears you are correct, but I could have sworn that
"." (the current working directory) was added to the path.

I could have sworn that I have seen "." at the front of sys.path, but
apparently I must have dreamed it.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
boB Stepp
2015-08-24 02:26:21 UTC
Permalink
Post by boB Stepp
Post by boB Stepp
And am I misreading the docs at
-------------------------------------------------------------------------------------------------------------------
Post by boB Stepp
26.3.2. Command-Line Interface
[...]
python -m unittest tests/test_something.py
This allows you to use the shell filename completion to specify the
test module. The file specified must still be importable as a module.
The path is converted to a module name by removing the ‘.py’ and
converting path separators into ‘.’
I didn't know this.
Post by boB Stepp
According to this, from E:\Projects\mcm, I should be able to type
py -m unittest ./test/db/test_manager.py
(1) Remove .py
"./test/db/test_manager"
(2) Replace / with .
"..test.db.test_manager"
Do you see now why
[...]
Post by boB Stepp
File "C:\Python34\lib\unittest\loader.py", line 105, in
loadTestsFromName
module = __import__('.'.join(parts_copy))
ValueError: Empty module name
?
This gets into the same issue you pointed out earlier in the thread.
Thanks for demonstrating how I *should* have applied the docs to my
current question.
Post by boB Stepp
Without the leading ./ it will probably work.
Unfortunately, no:

E:\Projects\mcm>E:\Projects\mcm>py -m unittest test/db/test_manager.py
'E:\Projects\mcm' is not recognized as an internal or external command,
operable program or batch file.

I also tried (Just to try...)

E:\Projects\mcm>E:\Projects\mcm>py -m unittest /test/db/test_manager.py
'E:\Projects\mcm' is not recognized as an internal or external command,
operable program or batch file.

However, if I use the FULL path:

E:\Projects\mcm>py -m unittest e:\Projects\mcm\test\db\test_manager.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

all is fine.
Post by boB Stepp
Post by boB Stepp
I believe that I understand Peter's point earlier, but if I am reading
the docs correctly, I should be able to do this.
With your help, I have (finally) demonstrated this.
Post by boB Stepp
While I don't think it's a bug you might still file a feature request on
bugs.python.org.
In retrospect, the only change I would suggest to the cited docs, is
to say "... full file path ..." or "... fully qualified file path ..."
instead of just "... file path ...".
--
boB
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/m
boB Stepp
2015-08-24 03:09:53 UTC
Permalink
Post by Peter Otten
Post by boB Stepp
... I was not in the directory, E:\Projects\mcm. It is my
understanding that if I start in a particular directory when I invoke
Python, then it looks in that location first in PYTHONPATH.
[...]
Post by Peter Otten
$ PYTHONPATH=. python3 sub/main.py
hello
Applying your wisdom to my remaining question, before I was doing this
unsuccessfully:


E:\Projects\mcm>py e:\Projects\mcm\test\db\test_manager.py
Traceback (most recent call last):
File "e:\Projects\mcm\test\db\test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'

But if I set the PYTHONPATH to e:/Projects/mcm as you seem to be
suggesting, gives:

E:\Projects\mcm>set PYTHONPATH=e:/Projects/mcm;

E:\Projects\mcm>py e:\Projects\mcm\test\db\test_manager.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Success! Thanks, Peter! You really clarified a LOT of points that I
just was spinning my wheels uselessly on.
Post by Peter Otten
Post by boB Stepp
------------------------------------------------
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.
-------------------------------------------------
If I try this or begin in E:\Projects\mcm and type py
./test/db/test_manager.py I get
E:\Projects\mcm>py ./test/db/test_manager.py
File "./test/db/test_manager.py", line 16, in <module>
import mcm.db.manager
ImportError: No module named 'mcm'
This final question is resolved by setting the PYTHONPATH environment
variable as above. I just want to note that this is *not* an instance
where a FULL path needs to be used to run test_manager.py as I had
earlier tried just above. Now after setting PYTHONPATH I get:

E:\Projects\mcm>py ./test/db/test_manager.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

I think this wraps up everything I was struggling with. Have I missed anything?

boB
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Continue reading on narkive:
Loading...