计算测试数量的Python单元测试

更新时间:2023-04-02 14:10:37

问题阐述

这是我第一次为了学校的作业而玩弄Python的单元测试。我基本上有一个Circle对象,我在其中使用pyunit来确保数据被正确存储。

我注意到,Python只计算作为测试用例的方法的数量,而不是Assert语句的数量。

例如,我想测试方法是否正常工作,尽管有4条Assert语句,但Python只将以下内容计为2个测试。它真的让我措手不及,因为对于Java的JUnit,它将计算Assert语句的数量。

def test_xcrd(self): 
    self.assertTrue(self.point.xcrd() == 1) 
    self.assertFalse(self.point.xcrd() == 5)

def test_ycrd(self): 
    self.assertTrue(self.point.ycrd() == 2) 
    self.assertFalse(self.point.ycrd() == 10)

Python中的"规范"是什么?每个方法是否应该只有一条Assert语句?

Python

精准答案的unittest包允许您以您所注意到的不同方法来组织您的单元测试。这在您想要测试密切相关且不需要单独的单元测试的情况下很有用。

unittest测试从unittest.Test子类化开始,然后向子类化添加方法。因此,您可以在不同的单元测试之间添加几个层间隔,这些层之间的相关性更高,相关性更小。

Python Docs中的一个示例演示了被认为是Python单元测试的最佳实践:

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

您可以在此处观察到以下几点:

  1. TestStringMethods的三种方法是单独的单元测试。
  2. test_isuppertest_split都包含两个断言,因为它们关系非常密切。为test_isupper中的两个断言添加单独的测试将给代码添加大量膨胀,并可能导致非常奇怪的问题。

例如,如果str.isupper()以一种奇怪的方式中断,则覆盖此单一函数的单一单元测试将中断。但是,如果"FOO""Foo"的两个测试是分开的,则一个测试可能通过,而另一个测试可能失败。因此,测试单个函数的功能更好地保存在带有多个断言的单个单元测试中。

同样适用于test_split方法;检查str.split()是否起作用和它引发的TypeError密切相关,因此在代码中也应保持紧密相关。

因此,回到您的问题:每个方法可以(有时应该)有多个断言,因为这会导致更简单、更清晰的代码,并减少混淆。引用"PYTHON的禅宗"(通过在PYTHON外壳中运行import this即可找到):"简单胜过复杂"。因此,通过在单个方法中对类似的断言进行分组来保持您的单元测试简单和结构化。