当前位置: 首页 > 面试题库 >

python unitests通过其声明的执行顺序

祁聪
2023-03-14
问题内容

我正在使用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会自动实现 浏览上下文
。为了实现排序,你,至少使用一个更好的命名约定为testnames,作为一个例子需要:test_1test_2test_3,等等,这是有效的,因为测试是根据字符串的内置顺序进行排序的。

但是,根据您的观察,问题出现test_10在排序顺序似乎中断的地方。作为一个例子,其中3次试验用的名称test_1test_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讨论单元测试测试的顺序建议设置sortTestMethodsUsingNone如下:

    import unittest
    

    unittest.TestLoader.sortTestMethodsUsing = None

  • @atomocopter在讨论更改Python中的单元测试顺序时,建议将设置sortTestMethodsUsing为以下值:

    import unittest
    

    unittest.TestLoader.sortTestMethodsUsing = lambda _, x, y: cmp(y, x)

  • @ElmarZander在讨论的单元测试顺序建议中建议使用nose和编写您的测试用例,因为它们是函数(而不是某些TestCase派生类的方法),nose它不会改变顺序,而是使用文件中定义的函数顺序。

  • @Keiji在讨论控制unittest.TestCases的顺序时提到:

sortTestMethodsUsing希望像Python 2层的一个功能cmp,它在Python 3里没有相应的(我去检查,如果Python
3中有一个<=>
飞船运营商还没有,但显然不是,他们希望你能依靠独立的比较<==,这似乎太大的倒退一步…)。该函数接受两个参数进行比较,如果第一个较小,则必须返回负数。值得注意的是,在
这种特殊情况下 ,该函数可以假定参数永远不相等,因为 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 会更加棘手,而且我也无法对其进行测试。

记录下来,我正在测试的代码 依赖于固定的测试顺序-
我完全理解您不应该依赖于测试顺序,这就是人们避免回答这个问题的原因。我的测试顺序可以是随机的,也可以正常工作。但是,有一个很好的理由,我希望将顺序固定为文件中定义的顺序:一目了然
,可以 轻松查看 哪些 测试失败。



 类似资料:
  • 我在我的网络应用程序中偶然发现了一个错误,在我发现发生了什么之前,这个错误让我抓耳挠腮(最终扯了扯头发)。 基本上,我在我的网站上定义了两个过滤器。xml和两个类似的映射: 它们都是Spring MVC过滤器。我的问题是,我得到的表单数据没有被解释为UTF-8,尽管事实上编码过滤器应该在其他任何东西有机会从中读取之前将请求编码设置为UTF-8。 我最后注意到,表单方法过滤器在编码过滤器之前执行,尽

  • 不论是客户端,还是服务器,都可以添加多个过滤器。假设我们按照添加的顺序把它们叫做 filter1, filter2, … filterN。那幺它们的执行顺序是这样的。 在客户端的执行顺序 +------------------- OutputFilter -------------------+ | +-------+ +-------+ +-------

  • 我的Androidanifest.xml文件是这样的 我正在使用build。渐变版 build.gradle(APP)文件是这样的 但是它总是显示这个警告在Androidanifest.xml文件,如何解决这个警告? 问题: > 警告是关于什么的? 我该怎么修?

  • 我正在尝试理解代码的调用顺序。来人,请解释一下通话顺序。 根据我的理解,静态块将在JVM开始执行时立即执行,甚至在main类之前执行。然后执行实例初始化块。则应执行构造函数。但如果我们从静态字段调用main方法,回调是如何工作的。以及哪个main将首先被执行,哪个JVM正常执行,哪个static字段显式调用。 附注:我修改了我的问题。前面我把普通方法和构造函数混淆了,所以一些答案看起来可能不相关,

  • [错误]脚本行:39-40----------------------ORA-06550:第2行,第7列:PLS-00103:当需要下列情况之一时,遇到符号“文件结束”: &=-+;in是mod余数而不是rem<>或!=或~=>=<=<>和或类似于2类似于4类似于multiset成员submultiset脚本第38行,语句第2行,第7列

  • 问题内容: 我已经读过这个问题,我的一个同事让我感到怀疑: 在过滤查询中,何时应用过滤器?在执行查询之前还是之后?什么时候缓存结果? 如果事先应用了过滤器,那么在过滤器中复制查询部分不是一件好事吗?如果之后应用了筛选器,那么我将无法理解缓存的内容。 问题答案: 幸运的是,ES为您提供了两种类型的过滤器供您使用: 在第一种情况下,过滤器将应用于查询找到的所有文档。在第二种情况下,将在查询运行之前过滤

  • 问题内容: 我想我已经写了如下几千遍: 但是直到现在我才考虑这些命令的顺序是否重要?我知道这之间并不要紧,因为在大多数1这些将被读取的,但它是 更好的 (以适应未来发展等方面)做W3C标准第一或最后? 问题答案: 毫无疑问,最佳做法是最后保留未添加前缀的属性: 无论是上期开出和将是已使用的一个。 是“实验”属性-实现可能包含与规范的偏差。的实现应与规范中的实现匹配。 最好在可用时使用 W3C实施

  • 这是发生在中的一种奇怪行为,下面是一个场景,一个名为Entity的类: 主要课程包括: 输出: 好的,它们是有序的,这很好,但是当您设置对某个