【问题标题】:Execution order of python unitests by their declarationpython unitets的执行顺序由他们的声明
【发布时间】:2020-03-04 08:04:01
【问题描述】:

我正在使用 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等出现问题,先执行。

我的问题是如何设置它们的执行顺序?

【问题讨论】:

  • 首先:需要固定的测试顺序通常不是一个好主意,因为这意味着测试相互依赖。如果你真的需要这个,你可以调整测试名称以使用testcase01_... ...testcase10_...。测试总是由默认的 testrunner 按字母顺序执行。
  • 另见this answer关于定义测试顺序。

标签: python selenium python-unittest


【解决方案1】:

从单元测试开始应该是独立的。所以必须是。通过python-unittest 执行的测试应该以能够独立运行的方式设计。纯单元测试提供了一个好处,即当它们失败时,它们通常会描述究竟出了什么问题。我们仍然倾向于使用unittest 框架编写功能测试、集成测试和系统测试,并且这些测试如果不订购它们就无法运行,因为Selenium 会自动浏览上下文。为了实现排序,您至少需要对测试名称使用更好的命名约定,例如:test_1test_2test_3 等,这是因为测试是按照内置的排序的为字符串排序。

但是,根据您的观察,问题出现在test_10 等等,排序顺序似乎中断了。例如,在名称为test_1test_2test_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
    
  • @atomocopter 在讨论中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 需要一个类似于 Python 2 的 cmp 的函数,它 在 Python 3 中没有等价物(我去检查 Python 3 是否有 <=> 宇宙飞船操作员,但显然不是;他们希望你依靠 <== 的单独比较,这似乎是倒退 步...)。该函数需要两个参数进行比较,并且必须返回 如果第一个较小,则为负数。尤其是在这个特殊的 case,函数可以假设参数永远不相等,因为 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 一起使用 会更棘手,我还没有能够测试这个。

郑重声明,我正在测试的代码依赖于测试 订单已修复 - 我完全理解您不应该依赖 测试顺序,这就是人们用来避免回答这个问题的原因 问题。我的测试顺序可以是随机的,而且可以正常工作 也是。但是,有一个很好的理由我想要订单 被固定为它们在文件中定义的顺序:它使它变得如此之多 一目了然哪些测试失败了。

【讨论】:

    猜你喜欢
    • 2014-01-19
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    相关资源
    最近更新 更多