簡體   English   中英

在PyDev中初始化單元測試?

[英]Initialization of unit-test in PyDev?

我使用PyDev單元測試在eclipse中對我的python代碼進行單元測試。 我右鍵單擊相應的文件並選擇Run As - > Python unit-test 關於這個插件,我有幾個問題:

  1. 有沒有辦法在這個類中的任何其他測試之前執行setUpClass方法? 目前我只能使setUp工作,這是在任何類測試之前調用的
  2. 有沒有辦法在執行任何測試之前調用全局初始化? setUpModule這樣的東西,我也無法使用PyDev單元測試運行。

在此先感謝您的回答和評論^^
切里奧沃爾坦

例:

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方法。

這是一個PyDev錯誤,已在2.0.1中修復。

由於PyDev 2.0.0及更早版本中的錯誤, setUpModule()tearDownModule()setUpClass()tearDownClass()不會在'Python unit-test'運行配置中運行。 在2.0.1中,它們在“Python單元測試”和“Python運行”配置中正確運行。 我自己測試一下來驗證。

好吧,我會給這個鏡頭:我使用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

額外

如果您正在使用nosetests進一步調查,那么它已經涵蓋了您,請參閱“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啟動。

編輯:摘要

使用調試器setUpClass()調試您的測試用例,看起來這是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版本。

如果你檢查Window> Preferences> PyDev> Interpreter - Python並查看正在使用的Python解釋器,你可能會發現它是v2.7之前,如果我沒記錯的話,引入了setUpClass。

引用更新版本的python,我懷疑你的測試將按原樣運行。

您可以自行決定從每個類中單獨加載測試並執行它們,包括在每個類測試必要的初始化之前,而不是使用自動遍歷所有測試類和單個測試的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 文檔還有一些其他類似用途的例子可能會有所幫助。

編輯:直到這一刻我都不知道,似乎Python 2.7有一個setUpClass() ,(應該是一個類方法,因此是裝飾器),它似乎做你需要的東西。 但是,在Python 2.6中並非如此,您應該提供自己的初始化例程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM