Python PyDev中单元测试的初始化?
我正在eclipse中使用PyDev单元测试对python代码进行单元测试。我右键单击适当的文件并选择RunAs->Python单元测试。关于这个插件,我有几个问题:Python PyDev中单元测试的初始化?,python,eclipse,unit-testing,eclipse-plugin,pydev,Python,Eclipse,Unit Testing,Eclipse Plugin,Pydev,我正在eclipse中使用PyDev单元测试对python代码进行单元测试。我右键单击适当的文件并选择RunAs->Python单元测试。关于这个插件,我有几个问题: 是否有一种方法可以在该类中的任何其他测试之前执行setUpClass方法?目前,我只能让设置工作,这是在任何类测试之前调用的 是否有一种方法可以在执行任何测试之前调用全局初始化?类似于setUpModule的东西,我也无法使用PyDev单元测试运行它 提前感谢您的回答和评论^^ 切里奥沃尔坦 示例: class TestClass
切里奥沃尔坦 示例:
class TestClass(unittest.TestCase):
@classmethod
def setUpClass(self):
print "Setup"
def test1(self):
print "Test1"
def test2(self):
print "Test2"
如果我使用run As->Python unit test运行此测试,则不会调用setUpClass方法。而不是使用
unittest.main()
,它会自动遍历所有测试类和单个测试,您可以分别从每个类加载测试并自行执行它们,在每个类测试之前包括必要的初始化。您也可以在所有这些之前进行一些全局初始化。请参见下面的示例:
import unittest
class MyTestClass1(unittest.TestCase):
def setUp(self):
pass
@classmethod
def setUpClass(cls):
pass
def test1(self):
pass
# lots of tests
class MyTestClass2(unittest.TestCase):
def setUp(self):
pass
@classmethod
def setUpClass(cls):
pass
def test1(self):
pass
# another whole lot of tests
if __name__=="__main__":
# add your global initialization code here
global_initialization()
# MyTestClass1 initialization:
MyTestClass1.setUpClass() # python 2.7 only
suite = unittest.TestLoader().loadTestsFromTestCase(MyTestClass1)
unittest.TextTestRunner().run(suite)
# MyTestClass1 initialization:
MyTestClass2.setUpClass() # python 2.7 only
suite = unittest.TestLoader().loadTestsFromTestCase(MyTestClass2)
unittest.TextTestRunner().run(suite)
unittest
还有其他一些类似的例子,可以提供帮助
Edit:直到现在我还不知道,Python 2.7似乎有一个
setUpClass()
,(应该是一个类方法,因此是decorator),它似乎完成了您需要的任务。但是,Python2.6中的情况并非如此,您应该提供自己的初始化例程。好的,我来试一试:我使用Pydev,并且一直在探索使用“nosetests”来启动测试,因此它有点相关。我的解决方案完全是一种黑客行为,但在PyDev中说“调试为UnitTest”时似乎确实有效:
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..."
不幸的是,这在使用nosetests时不起作用,但在从pydev运行时确实起作用。我猜想,nosetests被编码为在运行每个测试方法之前实例化测试对象,在这种情况下,您的init方法就足够了
关于鼻测试,我说得太多了:
- 支持异常和定时 测试
- 支持注释“属性”
- 与个人资料、覆盖率和xunit结果报告集成
- 测试用例的递归发现和属性化执行
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
附加的
在进一步调查中,如果您正在使用鼻测试,那么它已涵盖您,请参阅“http://somethingaboutorange.com/mrl/projects/nose/1.0.0/writing_tests.html“
你可以有:
包级拆卸:(这些位于包级初始化脚本中)
模块级拆卸:
def setup_module()
def teardown_module()
班级级别:
class MyTestCase(unittest.TestCase):
@classmethod
def setup_class(cls): pass
@classmethod
def teardown_class(cls): pass
和试验方法等级:
class MyTestCase(unittest.TestCase):
def setUp(self): pass
def tearDown(cls): pass
我喜欢使用“设置”名称,因为它很好地描绘了特定于鼻子的入口点。当通过命令行从nosetest运行时,我已经很好地验证了这些功能。但它们不是从Pydev“作为单元测试运行…”运行的。一个潜在的解决方案可能是编写一个pydev插件,使用nose运行测试。。。也许有人有?您可以将我的hack与nose结合起来,调用公共模块函数来完成实际工作。理想情况下,我们的init()应该知道以某种方式从Pydev启动。编辑:摘要
使用调试器逐步检查测试用例,这似乎是PyDev的测试运行程序不支持setUpClass()
,至少不支持我正在使用的1.6.5的一个限制
也许这将在PyDev的v2.0中得到修复,但与此同时,我认为我们将不得不使用\uuuu init\uuuu()
,正如建议的那样
细节
PyDev 1.6.5 PyDevTestSuite类使用:
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
这与python 2.6中的TestSuite.run()非常相似,而python 2.7.1的unittest中的TestSuite.run()做得更多:
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
旧答案
我怀疑这可能是由于所引用的Python版本造成的
如果您检查Window>Preferences>PyDev>解释器-Python并查看正在使用的Python解释器,您可能会发现它是v2.7之前的版本,如果我没记错的话,setUpClass是在这里引入的
参考较新版本的python,我怀疑您的测试将按原样工作。这是一个PyDev错误,已在2.0.1中修复
由于PyDev 2.0.0及更早版本中的错误,
setUpModule()
、tearDownModule()
、setUpClass()
和tearDownClass()
未在“Python单元测试”运行配置中运行。在2.0.1中,它们在“Python单元测试”和“Python运行”配置中正确运行。我自己测试过以验证。您好,谢谢您的发帖。这确实是一种很好的方法,但我的问题是关于PyDev插件的PyUnit功能的。以某种方式使用PyUnit时,不会调用main。因此,其中的任何初始化都不会执行。也许PyUnit不是使用单元测试的最佳方式,但也许它确实支持一些初始化功能?!嗨,卡尔,这是一个有趣的黑客,完全符合我的要求。很遗憾,这种方法与nosetest框架不兼容。嗨,Carl,再次感谢你伟大的回答!如果我能抽出时间,也许我会看看PyDev的源代码,看看里面发生了什么。在此之前,我将使用您的“hack”。您好,Mark,thx作为您的答案,但我使用的是Python 2.7,它也被选为Python解释器。所以这似乎不是问题所在。cherio WoltanFYI测试了PyDev的v2.0版,但问题没有解决。感谢您检查系列8217。但我认为它不值得一个bug报告,因为它更像是一个功能请求。我为它提交了一份报告,开发人员立即修复了这个问题。如果您从更新PyDev,您将能够下载最新版本的修复程序(版本2.0.1)。我在一些代码上尝试了这一点,并且
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