python - python unitets的执行顺序由他们的声明
问题描述
我正在使用 python unittests 和 selenium,在我的代码中,我有一个包含许多测试用例的测试类:
class BasicRegression(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome(executable_path=Data.driver)
cls.driver.implicitly_wait(1)
cls.driver.maximize_window()
def testcase1_some_stuff(self):
do_something()
def testcase2_some_stuff(self):
do_something()
def testcase3_some_stuff(self):
do_something()
...
@classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
if __name__ == '__main__':
unittest.main()
测试按字母顺序执行,即 testcase1、testcase2 和 testcase3,直到 testcase9。标准。testcase10等出现问题,先执行。
我的问题是如何设置他们的执行顺序?
解决方案
首先,单元测试应该是独立的。所以必须是python-unittest。通过执行的测试python-unittest
应该以能够独立运行的方式设计。纯单元测试提供了一个好处,即当它们失败时,它们通常会描述究竟出了什么问题。我们仍然倾向于使用unittest
框架编写功能测试、集成测试和系统测试,并且这些测试如果不订购它们就无法运行,因为Selenium会自动执行Browsing Context。为了实现排序,您至少需要为测试名称使用更好的命名约定,例如:test_1
, test_2
,test_3
等,这是因为测试是根据字符串的内置排序进行排序的。
但是,根据您的观察,问题出现test_10
在排序顺序似乎中断的地方等等。例如,在名称为和的 3 个测试中test_1
,似乎 unittest 在之前执行:test_2
test_10
test_10
test_2
代码:
import unittest class Test(unittest.TestCase): @classmethod def setUp(self): print("I'm in setUp") def test_1(self): print("I'm in test 1") def test_2(self): print("I'm in test 2") def test_10(self): print("I'm in test 10") @classmethod def tearDown(self): print("I'm in tearDown") if __name__ == "__main__": unittest.main()
控制台输出:
Finding files... done. Importing test modules ... done. I'm in setUp I'm in test 1 I'm in tearDown I'm in setUp I'm in test 10 I'm in tearDown I'm in setUp I'm in test 2 I'm in tearDown ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
解决方案
在不同的讨论中提出了不同的解决方案,其中一些解决方案如下:
@max 在讨论单元测试测试顺序中建议将其设置
sortTestMethodsUsing
为None
如下:import unittest unittest.TestLoader.sortTestMethodsUsing = None
@atomocopter 在讨论更改 Python 中单元测试的顺序时建议将 设置
sortTestMethodsUsing
为某个值,如下所示:import unittest unittest.TestLoader.sortTestMethodsUsing = lambda _, x, y: cmp(y, x)
@ElmarZander 在讨论Unittest 测试顺序中建议使用
nose
和编写测试用例作为函数(而不是作为某些 TestCase 派生类的方法)nose
不会改变顺序,而是使用文件中定义的函数顺序。@Keiji 在讨论Controlling the order of unittest.TestCases中提到:
sortTestMethodsUsing 需要一个类似 Python 2 的函数
cmp
,它在 Python 3 中没有等价物(我去检查 Python 3 是否有一个<=>
宇宙飞船运算符,但显然没有;他们希望你依赖单独的比较<
and==
,这似乎是一个倒退...)。该函数需要两个参数进行比较,如果第一个较小,则必须返回一个负数。值得注意的是,在这种特殊情况下,该函数可能会假设参数永远不会相等,因为unittest
不会在其测试名称列表中放置重复项。考虑到这一点,这是我发现的最简单的方法,假设您只使用一个 TestCase 类:
def make_orderer():
order = {}
def ordered(f):
order[f.__name__] = len(order)
return f
def compare(a, b):
return [1, -1][order[a] < order[b]]
return ordered, compare
ordered, compare = make_orderer()
unittest.defaultTestLoader.sortTestMethodsUsing = compare
然后,用 注释每个测试方法
@ordered
:
class TestMyClass(unittest.TestCase):
@ordered
def test_run_me_first(self):
pass
@ordered
def test_do_this_second(self):
pass
@ordered
def test_the_final_bits(self):
pass
if __name__ == '__main__':
unittest.main()
这依赖于 Python 按照带注释的函数在文件中出现的顺序调用注释。据我所知,这是有意的,如果它改变了,我会感到惊讶,但我实际上不知道它是否是有保证的行为。我认为这个解决方案甚至可以在 Python 2 中工作,对于那些不幸坚持使用它的人来说,虽然我还没有机会对此进行测试。
如果您有多个 TestCase 类,则需要
ordered, compare = make_orderer()
在定义之前为每个类运行一次class
,尽管如何使用它sortTestMethodsUsing
会更加棘手,而且我还没有能够测试它。作为记录,我正在测试的代码不依赖于固定的测试顺序 - 我完全理解你不应该依赖测试顺序,这就是人们用来避免回答这个问题的原因。我的测试顺序可以是随机的,它也可以正常工作。但是,我希望将顺序固定为文件中定义的顺序有一个很好的理由:它使一眼就能看出哪些测试失败了。
推荐阅读
- javascript - Javascript - 异步/等待 + .then
- r - Shiny Plot Gapminder 不动
- r - 在闪亮的应用程序中返回绘图时返回无效的第一个参数错误
- c# - 您能否控制 Kafka 生产者何时向 Kafka 代理发送消息
- user-interface - 如何根据文本框值在 AvaloniaUI 中启用按钮
- java - 每次创建新的不同类的对象
- mysql - MySQL,SQL如何检索特定列中包含较少使用值的整行
- html - 即使我添加了 clear:right,我的文本中也有一张图片
- javascript - Google App Script:根据列中的值将行(仅在行中选定的列)移动到另一个选项卡
- reactjs - 连接用于材质 UI 卡属性的字符串