Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do you do unittest?

2 views
Skip to first unread message

Will Stuyvesant

unread,
Aug 1, 2003, 10:33:38 AM8/1/03
to
I have a unittest testfile like this:

----------------------- test_mod.py ---------------------
import sys
sys.path.append('..')
import unittest
import mod

class Test_rmlutils(unittest.TestCase):

def testNormalCase(self):
self.assertEqual(....


if __name__ == '__main__':
unittest.main()
---------------------------------------------------------

It is exactly the same as example 17-2 in "Python in a
Nutshell" (PiaN), except for the first two lines. To
quote PiaN:
"...name the test module...with a prefix such as 'test_',
and put it in a subdirectory named 'test' of the directory
where you keep the sources."

PiaN did not mention the ugly sys.path.append('..') trick
I had to use when following its advice. I need to use it
because mod.py is in the directory above the 'test'
directory.

To run a test from the source directory I have to change
to the 'test' directory and run test_mod.py there from the
commandline. Okay, I can do that from a batchfile:

----------------------- test.bat ------------------------
cd test
test_mod.py
cd ..
---------------------------------------------------------

But: I would like to get rid of the need for
sys.append('..') and I don't see a nice way to do that, do
you? Maybe something from a Python script instead of a
DOS script...I am thinking about importing sys there and
then doing some advanced unittest function like
'runsuite(blah, foo)' but I am still reading the unittest
docs and there must be somebody who did this before?

I guess the author of PiaN does not use a 'test' subdirectory
himself, as it is now the example 17-2 does only work in the
source directory.

Michele Simionato

unread,
Aug 1, 2003, 12:59:30 PM8/1/03
to
hw...@hotmail.com (Will Stuyvesant) wrote in message news:<cb035744.03080...@posting.google.com>...

It is interesting that I had a similar issue with doctest, and I
was forced to add

>>> import sys; sys.path.append('.')

to my tests. Quite ugly and at the end I wrote a script that did this
automatically. I would be curious to know what's the origin of this
path issue.

Michele

Tom Plunket

unread,
Aug 1, 2003, 1:56:59 PM8/1/03
to
Will Stuyvesant wrote:

> ----------------------- test.bat ------------------------
> cd test
> test_mod.py
> cd ..
> ---------------------------------------------------------

Could you do simply "test/test_mod.py" ? Then the current
directory would still be the "main" directory. Not sure how
Python handles the paths in a case like this though.

> I guess the author of PiaN does not use a 'test' subdirectory
> himself, as it is now the example 17-2 does only work in the
> source directory.

I just have all of my test_*.py files and my main test.py in the
main source folder. My test.py automatically runs all of the
tests that exist, I have to thank this group for getting me down
the right path.

(The 'Directory' stuff is because my unittests create lots of
files. It's a work-in-progress. RunTests() is the function most
relevant to this discussion.)

---- test.py ----

import unittest
import os, sys

def SetupDirectory(name):
testDir = os.environ['TESTING_DIRECTORY']
testDir = os.path.join(testDir, name)

if not os.path.exists(testDir):
os.mkdir(testDir)

os.chdir(testDir)

def PruneDirectory(dir):
files = os.listdir(dir)

for f in files:
fullpath = os.path.join(dir, f)

if os.path.isfile(fullpath):
os.remove(fullpath)
elif os.path.isdir(fullpath):
PruneDirectory(fullpath)

os.rmdir(dir)

def CreateTempDirectory():
# testDir = os.environ['TEMP']
# testDir = os.path.join(testDir, 'filefiend_test')
testDir = os.path.join(os.getcwd(), 'testdata')

if os.path.exists(testDir):
PruneDirectory(testDir)

os.mkdir(testDir)
os.environ['TESTING_DIRECTORY'] = testDir

def RemoveTempDirectory():
testDir = os.environ['TESTING_DIRECTORY']
os.chdir(os.path.join(testDir, os.pardir))
PruneDirectory(testDir)

def RunTests():
files = os.listdir(os.curdir)
names = []
for file in files:
if file[:5] == "test_" and file[-3:] == os.extsep+"py":
names.append(file[:-3])

CreateTempDirectory()

suite = unittest.defaultTestLoader.loadTestsFromNames(names)
runner = unittest.TextTestRunner(verbosity=1)
result = runner.run(suite)

RemoveTempDirectory()

# raw_input("\n<Enter> to continue.\n")
sys.exit(not result.wasSuccessful())


if __name__ == "__main__":
RunTests()

-tom!

--
There's really no reason to send a copy of your
followup to my email address, so please don't.

Steven Taschuk

unread,
Aug 1, 2003, 5:09:22 PM8/1/03
to
Quoth Will Stuyvesant:
[...]

> PiaN did not mention the ugly sys.path.append('..') trick
> I had to use when following its advice. I need to use it
> because mod.py is in the directory above the 'test'
> directory.
>
> To run a test from the source directory I have to change
> to the 'test' directory and run test_mod.py there from the
> commandline. [...]

Why not just stay in the directory containing mod.py and run
python test/test_mod.py
?

--
Steven Taschuk stas...@telusplanet.net
"Its force is immeasurable. Even Computer cannot determine it."
-- _Space: 1999_ episode "Black Sun"

John Roth

unread,
Aug 1, 2003, 6:24:11 PM8/1/03
to

"Will Stuyvesant" <hw...@hotmail.com> wrote in message
news:cb035744.03080...@posting.google.com...

I'm not sure what the author of Python in a Nutshell was
thinking of. I have never had any problem with running
unit tests, but my setup has the unit test modules in the
same directory as the source modules, and I also have a
script file (well, a Windows batch or command file) for
each test module, as well as a test module that creates
a suite with all of the other test modules. It works
wonderfully well; never a problem.

What's happening is that Python always puts the
directory with the module you invoked into the path
as the first directory, so I would suspect that your
project directory isn't in the path. If you only execute
out of that one directory, everything just works. If
you try to import one of those modules from somewhere
else, it doesn't work.

If you want to keep your tests in a separate library
(and there are good arguements for that - I just ignore
them for myself) your actual program directory has
to be on the Python path. The ".." workaround you've
mentioned is one way of doing that. The way I work,
I just set the Python path to what I want in the
invocation scripts, or in the script that invokes the
command prompt I use, and then simply use it.
No muss, no fuss.

John Roth


Raymond Hettinger

unread,
Aug 1, 2003, 7:53:00 PM8/1/03
to

"Will Stuyvesant" <hw...@hotmail.com> wrote in message
news:cb035744.03080...@posting.google.com...
> I have a unittest testfile like this:
>
> ----------------------- test_mod.py ---------------------
> import sys
> sys.path.append('..')
> import unittest
> import mod
>
> class Test_rmlutils(unittest.TestCase):
>
> def testNormalCase(self):
> self.assertEqual(....
>
>
> if __name__ == '__main__':
> unittest.main()
> ---------------------------------------------------------
>
> It is exactly the same as example 17-2 in "Python in a
> Nutshell" (PiaN), except for the first two lines. To
> quote PiaN:
> "...name the test module...with a prefix such as 'test_',
> and put it in a subdirectory named 'test' of the directory
> where you keep the sources."
>
> PiaN did not mention the ugly sys.path.append('..') trick
> I had to use when following its advice. I need to use it
> because mod.py is in the directory above the 'test'
> directory.

You can avoid that sort of mambo jambo by avoiding
unittest.main() and running the tests directly. I added
a simple example to the Py2.3 docs:

http://www.python.org/doc/current/lib/minimal-example.html


Raymond Hettinger

Will Stuyvesant

unread,
Aug 2, 2003, 3:18:58 AM8/2/03
to
> [Raymond Hettinger]

> You can avoid that sort of mambo jambo by avoiding
> unittest.main() and running the tests directly. I added
> a simple example to the Py2.3 docs:
>
> http://www.python.org/doc/current/lib/minimal-example.html

Thanks, I now use unittest.TextTestRunner (what a name!) in
test_mod.py in a test_mod.test function. Together with a general
test.py in the 'test' directory that does the sys.path.append('..') I
can now run tests in the test directory so I don't have all the
clutter in the source directory, and I don't have to do
sys.path.append('..') in every test_xxx.py, only in the test.py that
looks like:

# To be executed in the 'test' directory


import sys
sys.path.append('..')

import test_mod
test_mod.test()
import test_mod2
test_mod2.test()
...

0 new messages