Python unittest.TestCase执行顺序
Pythonunit testing有没有办法设置testing用例的运行顺序?
在我目前的TestCase
类中,一些testing用例有副作用,为别人正常运行设置条件。 现在我认识到这样做的正确方法是使用setUp()
来完成所有设置实现的事情,但是我想实现一个devise,每个连续的testing都build立了稍微更多的状态,以便下一个可以使用。 我觉得这更优雅。
class MyTest(TestCase): def test_setup(self): #do something def test_thing(self) #do something that depends on test_setup()
理想情况下,我希望testing按照他们在课堂上出现的顺序进行。 看来,他们按字母顺序运行。
不要让他们独立testing – 如果你想要一个单一的testing,写一个单一的testing。
class Monolithic(TestCase): def step1(self): ... def step2(self): ... def _steps(self): for name in sorted(dir(self)): if name.startswith("step"): yield name, getattr(self, name) def test_steps(self): for name, step in self._steps(): try: step() except Exception as e: self.fail("{} failed ({}: {})".format(step, type(e), e))
如果稍后testing开始失败,并且希望获取有关所有失败步骤的信息,而不是在第一个失败的步骤中停止testing用例,则可以使用subtests
function: https : //docs.python.org/3/library/unittest.html #区分testing迭代-使用-测验
(子testingfunction可以通过unittest2
获得Python 3.4之前的版本: https : //pypi.python.org/pypi/unittest2 )
它是一个很好的做法,总是写一个单片testing这样的期望,但是如果你是一个愚蠢的哥们,那么你可以简单地按照字母顺序编写难看的方法,以便他们从a到bsorting,正如python文档中提到的http ://docs.python.org/library/unittest.html
请注意,各种testing用例的运行顺序是通过对testing函数名称进行sorting来确定的
例:
def test_a_first(): print "1" def test_b_next(): print "2" def test_c_last(): print "3"
http://docs.python.org/library/unittest.html
请注意,各种testing用例的运行顺序是通过对testing函数名称和string的内置sorting进行sorting来确定的。
所以只要确保test_setup
的名字具有最小的string值。
请注意,您不应该依赖这种行为 – 不同的testing函数应该独立于执行顺序。 如果您明确需要订单,请参阅上面的ngcohlan答案。
老问题,但另一种方式,我没有看到任何相关的问题列出: 使用TestSuite
。
另一种完成sorting的方法是将testing添加到unitest.TestSuite
。 这看起来像使用suite.addTest(...)
考虑了将testing添加到套件的suite.addTest(...)
。 去做这个:
-
创build一个或多个TestCase子类,
class FooTestCase(unittest.TestCase): def test_ten(): print('Testing ten (10)...') def test_eleven(): print('Testing eleven (11)...') class BarTestCase(unittest.TestCase): def test_twelve(): print('Testing twelve (12)...') def test_nine(): print('Testing nine (09)...')
-
按照您希望的顺序创build一个可调用的testing套件生成,从文档和此问题进行调整 :
def suite(): suite = unittest.TestSuite() suite.addTest(BarTestCase('test_nine')) suite.addTest(FooTestCase('test_ten')) suite.addTest(FooTestCase('test_eleven')) suite.addTest(BarTestCase('test_twelve')) return suite
-
执行testing套件,例如,
if __name__ == '__main__': runner = unittest.TextTestRunner(failfast=True) runner.run(suite())
对于上下文,我需要这个,并不满意其他选项。 我在上面做testing订购的方式解决了。 我没有看到这个TestSuite方法列出了几个“unit testing订购问题”(例如,这个问题和其他包括执行顺序 ,或更改顺序或testing订单 )。
当我来到这个线程时,@ ncoghlan的答案正是我所期待的。 我结束了修改它,以允许每个步骤testing运行,即使前面的步骤已经抛出一个错误; 这有助于我(也许你!)发现和计划在multithreading数据库中心软件中传播错误。
class Monolithic(TestCase): def step1_testName1(self): ... def step2_testName2(self): ... def steps(self): ''' Generates the step methods from their parent object ''' for name in sorted(dir(self)): if name.startswith('step'): yield name, getattr(self, name) def test_steps(self): ''' Run the individual steps associated with this test ''' # Create a flag that determines whether to raise an error at # the end of the test failed = False # An empty string that the will accumulate error messages for # each failing step fail_message = '' for name, step in self.steps(): try: step() except Exception as e: # A step has failed, the test should continue through # the remaining steps, but eventually fail failed = True # get the name of the method -- so the fail message is # nicer to read :) name = name.split('_')[1] # append this step's exception to the fail message fail_message += "\n\nFAIL: {}\n {} failed ({}: {})".format(name, step, type(e), e) # check if any of the steps failed if failed is True: # fail the test with the accumulated exception message self.fail(fail_message)
testing真正依赖于彼此应该明确地链接到一个testing。
需要不同级别的设置的testing,也可以有相应的setUp()
运行足够的设置 – 各种方式可想而知。
否则unittest
默认按字母顺序处理testing类中的testing类和testing方法(即使loader.sortTestMethodsUsing
为None)。 dir()
在内部使用,按保证sorting。
后一种行为可以用于实用性 – 例如,为了使最新的工作testing首先运行以加快编辑 – testing – 循环。 但是这种行为不应该被用来build立真正的依赖关系 。 考虑到可以通过命令行选项单独运行testing