由其声明确定的Python单元的执行顺序
问题描述
我使用的是python单元测试和Selify,在我的代码中,我有一个带有许多测试用例的测试类:
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()
测试按字母顺序执行,即,测试用例1、测试用例2和测试用例3,直到测试用例9。标准。问题出现在测试用例10中,依此类推,它首先被执行。
我的问题是如何设置他们的执行顺序?
解决方案
首先,单元测试应该是独立的。所以一定是python-unittest。通过python-unittest
执行的测试应该设计为能够独立运行。纯粹的单元测试提供了一个好处,当它们失败时,它们通常会描述出到底出了什么问题。尽管如此,我们仍然倾向于使用unittest
框架编写功能测试、集成测试和系统测试,如果不对它们进行排序,这些测试将无法运行,因为Selenium会自动执行浏览上下文。要实现排序,您至少需要对测试名使用更好的命名约定,例如:test_1
、test_2
、test_3
等,这是可行的,因为测试是按照字符串的内置排序进行排序的。
test_10
等排序顺序似乎被破坏的地方。例如,在名为test_1
、test_2
和test_10
的3个测试中,unittest似乎在test_2
之前执行test_10
:
编码:
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讨论Unittest tests order建议将
sortTestMethodsUsing
设置为None
如下:import unittest unittest.TestLoader.sortTestMethodsUsing = None
@topocopter在讨论changing order of unit tests in Python中建议将
sortTestMethodsUsing
设置如下:import unittest unittest.TestLoader.sortTestMethodsUsing = lambda _, x, y: cmp(y, x)
@ElmarZander在Unittest tests order讨论中建议使用
nose
并将您的测试用例编写为函数(而不是某个TestCase派生类的方法)nose
不调整顺序,而是使用文件中定义的函数顺序。@Keiji在讨论中Controlling the order of unittest.TestCases提到:
SortTestMethodsUsing需要一个类似于Python2的函数,该函数 在Python3中没有等效项(我去检查了一下是否有<=>
宇宙飞船操作员,但显然不是;他们希望你依赖 分别比较<
和==
,这似乎是一种倒退 步骤...)。该函数接受两个参数进行比较,并且必须返回 如果第一个较小,则为负数。值得注意的是这一特殊情况 大小写时,该函数可能会假定参数永远不相等,因为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以被批注的顺序调用批注 函数将出现在文件中。据我所知,这是有意的,而且 如果它变了,我会很惊讶,但我不知道它是不是 有保障的行为。我认为这个解决方案甚至可以在Python2中运行 同样,对于那些不幸被它困住的人,尽管我 我还没有机会对此进行测试。 如果您有多个TestCase类,则需要在class
之前为每个类运行一次 定义,但如何将其与sortTestMethodsUsing
一起使用 将更加棘手,我也还无法对其进行测试。郑重声明,我测试的代码不依赖于测试 秩序是固定的-我完全理解你不应该依赖于 测试顺序,这就是人们用来避免回答这个问题的原因 问题。我的测试顺序可以是随机的,它只会起作用 也是。然而,我有一个非常好的理由希望订单 固定到它们在文件中定义的顺序:这使它 更容易看到哪些测试失败。
相关文章