在PyDev中初始化单元测试?

时间:2011-03-25 09:36:50

标签: python eclipse unit-testing eclipse-plugin pydev

我使用PyDev单元测试在eclipse中对我的python代码进行单元测试。我右键单击相应的文件并选择 Run As - > Python单元测试。关于这个插件,我有几个问题:

  1. 有没有办法在此类中的任何其他测试之前执行 setUpClass 方法?目前我只能 setUp 工作,这是在课程的任何测试之前调用的
  2. 有没有办法在执行任何测试之前调用全局初始化?像 setUpModule 这样的东西,我也无法使用PyDev单元测试运行。
  3. 提前感谢您的回答和评论^^
    Cherio Woltan

    示例:

    class TestClass(unittest.TestCase):
    
      @classmethod
      def setUpClass(self):
          print "Setup"    
    
      def test1(self):
          print "Test1"
      def test2(self):
          print "Test2"
    

    如果我使用 Run As - >运行此操作Python单元测试 setUpClass 方法未被调用。

4 个答案:

答案 0 :(得分:7)

这是一个PyDev错误,已在2.0.1中修复。

由于PyDev 2.0.0中存在错误,

setUpModule()tearDownModule()setUpClass()tearDownClass()未在“Python单元测试”运行配置中运行早。在2.0.1中,它们在“Python单元测试”和“Python运行”配置中正确运行。我自己测试一下来验证。

答案 1 :(得分:5)

好的我会给这个镜头:我使用Pydev并一直在探索使用“nosetests”来启动测试,所以它有点相关。我的解决方案是完全破解,但在PyDev中说“Debug as 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”。

你可以:

包级别拆解:(这些存在于包级别的init脚本中)

def setup_package()
def teardown_package()

模块级拆解:

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

我喜欢使用“setup_”名称,因为它很好地描绘了鼻子特定的入口点。通过命令行从nosetests运行时,我已经很好地验证了这些工作。但他们并没有从Pydev运行“作为单元测试运行......”。一个潜在的解决方案可能是编写一个使用nose运行测试的pydev插件......也许有人有一个?您可以将我的hack与调用常用模块函数的鼻子结合起来进行实际工作。理想情况下,我们的 init ()会意识到以某种方式从Pydev启动。

答案 2 :(得分:2)

编辑:摘要

使用调试器逐步调试测试用例,看起来这是PyDev测试运行器不支持setUpClass()的限制,至少不是1.6.5,我正在使用。

也许这将在PyDev的v2.0中修复,但与此同时,我认为我们必须stick使用__init__()而不是CarlS建议。

详细信息

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>偏好> PyDev>解释器 - Python并查看正在使用的Python解释器,您可能会发现它是v2.7之前,如果我没记错的话,引入了setUpClass。

引用更新版本的python,我怀疑你的测试将按原样运行。

答案 3 :(得分:0)

不是使用自动遍历所有测试类和单个测试的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 documentation还有其他一些类似用途的例子可能会有所帮助。

编辑:直到这一刻我都不知道,似乎Python 2.7有一个setUpClass(),(应该是一个类方法,因此是装饰器),它似乎做你需要的它来。但是,在Python 2.6中并非如此,您应该提供自己的初始化例程。

相关问题