Mik*_*ike 68 python unit-testing
Python中有没有办法unittest设置运行测试用例的顺序?
在我目前的TestCase课程中,一些测试用例具有副作用,为其他测试用例设置正常运行的条件.现在我意识到这样做的正确方法是使用setUp()所有设置实现的东西,但我想实现一个设计,其中每个连续的测试建立稍微更多的状态,下一个可以使用.我发现这更优雅.
class MyTest(TestCase):
def test_setup(self):
#do something
def test_thing(self)
#do something that depends on test_setup()
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望测试按照它们在课堂中出现的顺序运行.它们似乎按字母顺序运行.
nco*_*lan 66
不要让它们独立测试 - 如果你想进行单片测试,那就写一个单片测试.
class Monolithic(TestCase):
def step1(self):
...
def step2(self):
...
def _steps(self):
for name in dir(self): # dir() result is implicitly sorted
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))
Run Code Online (Sandbox Code Playgroud)
如果测试稍后开始失败并且您想要了解所有失败步骤的信息而不是在第一个失败步骤中停止测试用例,则可以使用以下subtests功能:https://docs.python.org/3/library/unittest.html#区分测试迭代-使用-子测试
(通过unittest2Python 3.4之前的版本可以使用子测试功能:https://pypi.python.org/pypi/unittest2)
var*_*run 34
总是为这样的期望写一个单一的测试是一个很好的做法,但是如果你像我一样傻傻的家伙,那么你可以简单地按字母顺序编写难看的方法,以便它们从a到b排序,如python docs http中所述://docs.python.org/library/unittest.html
请注意,运行各种测试用例的顺序是通过根据字符串的内置顺序对测试函数名称进行排序来确定的.
例:
def test_a_first():
print "1"
def test_b_next():
print "2"
def test_c_last():
print "3"
Run Code Online (Sandbox Code Playgroud)
ken*_*ytm 24
http://docs.python.org/library/unittest.html
请注意,运行各种测试用例的顺序是通过根据字符串的内置顺序对测试函数名称进行排序来确定的.
所以只要确保test_setup名称的字符串值最小.
请注意,您不应该依赖此行为 - 不同的测试函数应该独立于执行顺序.如果您明确需要订单,请参阅ngcohlan上面的答案以获得解决方案.
hoc*_*age 16
老问题,但我没有看到在任何相关问题中列出的另一种方式:使用aTestSuite.
完成排序的另一种方法是将测试添加到a unitest.TestSuite.这似乎尊重测试添加到套件中的顺序suite.addTest(...).去做这个:
创建一个或多个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)...')
Run Code Online (Sandbox Code Playgroud)创建一个按所需顺序添加的可调用测试套件生成,根据文档和此问题进行调整:
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
Run Code Online (Sandbox Code Playgroud)执行测试套件,例如,
if __name__ == '__main__':
runner = unittest.TextTestRunner(failfast=True)
runner.run(suite())
Run Code Online (Sandbox Code Playgroud)对于上下文,我需要这个,并且对其他选项不满意.我决定采用上面的测试排序方式.我没有看到这个TestSuite方法列出了几个"单元测试排序问题"中的任何一个(例如,这个问题和其他包括执行顺序,或更改顺序或测试顺序).
我最终得到了一个对我有用的简单解决方案:
class SequentialTestLoader(unittest.TestLoader):
def getTestCaseNames(self, testCaseClass):
test_names = super().getTestCaseNames(testCaseClass)
testcase_methods = list(testCaseClass.__dict__.keys())
test_names.sort(key=testcase_methods.index)
return test_names
Run Code Online (Sandbox Code Playgroud)
进而
unittest.main(testLoader=utils.SequentialTestLoader())
Run Code Online (Sandbox Code Playgroud)
一种简单而灵活的方法是将比较器函数分配给unittest.TestLoader.sortTestMethodsUsing:
用于在对方法名称
getTestCaseNames()和所有loadTestsFrom*()方法进行排序时比较方法名称的函数。
最小用量:
import unittest
class Test(unittest.TestCase):
def test_foo(self):
""" test foo """
self.assertEqual(1, 1)
def test_bar(self):
""" test bar """
self.assertEqual(1, 1)
if __name__ == "__main__":
test_order = ["test_foo", "test_bar"] # could be sys.argv
loader = unittest.TestLoader()
loader.sortTestMethodsUsing = lambda x, y: test_order.index(x) - test_order.index(y)
unittest.main(testLoader=loader, verbosity=2)
Run Code Online (Sandbox Code Playgroud)
输出:
import unittest
class Test(unittest.TestCase):
def test_foo(self):
""" test foo """
self.assertEqual(1, 1)
def test_bar(self):
""" test bar """
self.assertEqual(1, 1)
if __name__ == "__main__":
test_order = ["test_foo", "test_bar"] # could be sys.argv
loader = unittest.TestLoader()
loader.sortTestMethodsUsing = lambda x, y: test_order.index(x) - test_order.index(y)
unittest.main(testLoader=loader, verbosity=2)
Run Code Online (Sandbox Code Playgroud)
这是按源代码顺序而不是默认词汇顺序运行测试的概念证明(输出如上)。
import inspect
import unittest
class Test(unittest.TestCase):
def test_foo(self):
""" test foo """
self.assertEqual(1, 1)
def test_bar(self):
""" test bar """
self.assertEqual(1, 1)
if __name__ == "__main__":
test_src = inspect.getsource(Test)
unittest.TestLoader.sortTestMethodsUsing = lambda _, x, y: (
test_src.index(f"def {x}") - test_src.index(f"def {y}")
)
unittest.main(verbosity=2)
Run Code Online (Sandbox Code Playgroud)
我在这篇文章中使用了 Python 3.8.0。
| 归档时间: |
|
| 查看次数: |
41566 次 |
| 最近记录: |