PyDev 中单元测试的初始化?

发布于 2024-10-26 16:47:20 字数 669 浏览 1 评论 0原文

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

  1. 有没有办法让 setUpClass 方法在此类中的任何其他测试之前执行?目前我只能让 setUp 工作,它在类的任何测试之前调用
  2. 有没有办法在执行任何测试之前调用全局初始化?像 setUpModule 这样的东西我也无法使用 PyDev 单元测试来运行。

预先感谢您的任何答复和评论^^
Cherio Woltan

示例:

class TestClass(unittest.TestCase):

  @classmethod
  def setUpClass(self):
      print "Setup"    

  def test1(self):
      print "Test1"
  def test2(self):
      print "Test2"

如果我使用“运行方式 ->”运行此命令Python 单元测试 setUpClass 方法没有被调用。

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:

  1. Is there a way to have a setUpClass method that is being executed before any other test within this class? Currently I am only able to get setUp working, which is called before any test of the class
  2. Is there a way to have a global initialization that is being called before any test is executed? Something like setUpModule which I am also not able to get running using PyDev unit-testing.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

春夜浅 2024-11-02 16:47:20

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

setUpModule()tearDownModule()setUpClass()tearDownClass() 不在 '由于 PyDev 2.0.0 及更早版本中的错误,Python 单元测试的运行配置。在 2.0.1 中,它们在“Python 单元测试”和“Python 运行”配置中正确运行。我自己测试了一下来验证一下。

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.

被你宠の有点坏 2024-11-02 16:47:20

好的,我会尝试一下:我使用 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..."

不幸的是,这在使用 Nostests 时不起作用,但在从 pydev 运行时确实有效。我猜测,nosetests 被编码为在运行每个测试方法之前实例化测试对象,在这种情况下,您的 init 方法就足够了。

关于nosetests,我无法说太多好话:

  • 支持异常和定时
    测试。
  • 支持注释“归因”。
  • 与概况、覆盖范围和 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

附加

如果您正在使用nosetests,那么它已经涵盖了您的进一步调查,请参阅“http://somethingaboutorange.com/mrl/projects/nose/1.0.0/writing_tests.html”。

您可以有:

包级别拆卸:(这些位于包级别初始化脚本中)

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_”名称,因为它很好地描绘了鼻子特定的入口点。当通过命令行从鼻子测试运行时,我已经验证了这些工作良好。但它们不从 Pydev“作为单元测试运行...”运行。一个潜在的解决方案可能是编写一个使用鼻子来运行测试的 pydev 插件......也许有人有一个?您可以将我的黑客与调用通用模块函数的鼻子的黑客结合起来来完成实际的工作。理想情况下,我们的 init() 会以某种方式意识到从 Pydev 启动。

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:

  • support for exceptions and timed
    tests.
  • support for annotation "attribution".
  • integration with profile, coverage and xunit reporting of results.
  • recursive discovery and attributed execution of test cases.

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

Additional

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.

彼岸花似海 2024-11-02 16:47:20

编辑:摘要

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

也许这会在 PyDev v2.0 中得到修复,但与此同时,我认为我们必须 坚持改为使用__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 版本。

如果您检查窗口>首选项> PyDev > Interpreter - Python 看看正在使用哪个 Python Interpreter,您可能会发现它是 v2.7 之前的版本,如果我没记错的话,引入了 setUpClass。

引用较新版本的 python,我怀疑您的测试将按原样工作。

Edit: Summary

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.

Details

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

Old answer

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.

醉城メ夜风 2024-11-02 16:47:20

您可以单独加载每个类的测试并根据您的判断执行它们,包括在每个类测试必要的初始化。您还可以在所有这些之前进行一些全局初始化。请参阅下面的示例:

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 文档 还有一些其他示例类似的用途可能会有所帮助。

编辑:直到此刻我才知道,Python 2.7似乎有一个setUpClass(),(应该是一个类方法,因此是装饰器),它似乎做了什么你需要它。然而,Python 2.6 中的情况并非如此,您应该提供自己的初始化例程。

Instead of using unittest.main(), which automatically goes through all your test classes and individual tests, you can load the tests from each class separately and execute them at your discretion, including before each class test the necessary initializations. You can precede all that with some global initialization as well. See an example below:

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)

The unittest documentation has some other examples of similar use which could be of assistance.

Edit: Unbeknown to me until this moment, it seems that Python 2.7 has a setUpClass(), (should be a class method, hence the decorator) which seems to do what you need it to . However, that's not the case in Python 2.6 and you should provide your own initialization routines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文