I am unit-testing my python code in eclipse using PyDev unit-testing. I right click on the appropriate file and select Run As -> Python unit-test. Concerning this plugin I have a few questions:
Thanks in advance for any answer and comment^^
Cherio Woltan
Example:
class TestClass(unittest.TestCase):
@classmethod
def setUpClass(self):
print "Setup"
def test1(self):
print "Test1"
def test2(self):
print "Test2"
If I run this with Run As -> Python unit-test the setUpClass method is not being called.
It's a PyDev bug, and has been fixed in 2.0.1.
setUpModule()
, tearDownModule()
, setUpClass()
, and tearDownClass()
are not run in the 'Python unit-test' run configuration due to the bug in PyDev 2.0.0 and earlier. In 2.0.1 they run correctly in the 'Python unit-test' and 'Python Run' configurations. I tested it myself to verify.
OK I'll give this a shot: I use Pydev and have been exploring using "nosetests" to launch tests so it's sort of relevant. My solution is a total hack, but does seem to work when saying "Debug as UnitTest" from within PyDev:
print "before any tests (global) just once..."
class MyTestCase(unittest.TestCase):
class_setup_called = False
def __init__(self, test_name):
unittest.TestCase.__init__(self, test_name)
if not self.__class__.class_setup_called:
self.setUpClass()
self.__class__.class_setup_called = True
@staticmethod
def setUpClass():
print "before first test only..."
def setUp(self):
print "before each test..."
Unfortunately this will not work when using nosetests, but it does work when running from pydev. I'm guessing that nosetests is coded to instantiate test objects before each test method is run, in which case your init method would suffice.
I can't say enough nice things about nosetests:
examples:
import unittest
@raises(TypeError)
def test_forexceptions(self):
pass
@attr('benchmark')
@timed(5.0)
def test_benchmark(self):
pass # do something real slow and run nosetests --with-profile -a benchmark
On further investigation if you are using nosetests then it has you covered, see "http://somethingaboutorange.com/mrl/projects/nose/1.0.0/writing_tests.html".
You can have:
package level teardowns: (these live in package level init scripts)
def setup_package()
def teardown_package()
module level teardowns:
def setup_module()
def teardown_module()
class level:
class MyTestCase(unittest.TestCase):
@classmethod
def setup_class(cls): pass
@classmethod
def teardown_class(cls): pass
and test method level:
class MyTestCase(unittest.TestCase):
def setUp(self): pass
def tearDown(cls): pass
I like to use the the "setup_" names as it nicely delineates the nose specific entry points. I've verified these work nicely when run from nosetests via the command line. But they do NOT run from Pydev "run as unit test...". A potential solution may be writing a pydev plugin that uses nose to run the tests... perhaps someone has one? You could combine my hack with the nose ones calling common module functions to do the actual work. Ideally our init() would be aware of being launched from Pydev somehow.
Stepping through your test case with the debugger, it look's like this is a limitation of PyDev's test runner not supporting setUpClass()
, at least not with 1.6.5, which I'm using.
Maybe this will be fixed in v2.0 of PyDev, but in the meantime, I think we will have to stick to using __init__()
instead, as CarlS suggests.
The PyDev 1.6.5 PyDevTestSuite class uses:
def run(self, result):
for index, test in enumerate(self._tests):
if result.shouldStop:
break
test(result)
# Let the memory be released!
self._tests[index] = None
return result
which is very similar to TestSuite.run() in python 2.6, whereas TestSuite.run() in python 2.7.1's unittest does rather more:
def run(self, result, debug=False):
topLevel = False
if getattr(result, '_testRunEntered', False) is False:
result._testRunEntered = topLevel = True
for test in self:
if result.shouldStop:
break
if _isnotsuite(test):
self._tearDownPreviousClass(test, result)
self._handleModuleFixture(test, result)
self._handleClassSetUp(test, result)
result._previousTestClass = test.__class__
if (getattr(test.__class__, '_classSetupFailed', False) or
getattr(result, '_moduleSetUpFailed', False)):
continue
if not debug:
test(result)
else:
test.debug()
if topLevel:
self._tearDownPreviousClass(None, result)
self._handleModuleTearDown(result)
return result
I suspect this may be down to the version of Python that is being referenced.
If you check Window > Preferences > PyDev > Interpreter - Python and look at which Python Interpretter is being used, you may well find that it is pre v2.7 where, if I remember correctly, setUpClass was introduced.
Reference a newer version of python and I suspect your tests will work as is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With