【问题标题】:Python unittest counting the number of testsPython unittest 计算测试次数
【发布时间】:2017-02-17 18:42:20
【问题描述】:

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

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

例如,我想测试方法是否正常工作,Python 仅将以下内容计为 2 个测试,尽管有 4 个断言语句。它真的让我措手不及,就像 Java 的 JUnit 一样,它会计算断言语句的数量。

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 中的“规范”是什么?每个方法应该只有一个断言语句吗?

【问题讨论】:

  • “与 Java 的 JUnit 一样,它会计算断言语句的数量,而不是” - 什么?从什么时候开始?
  • 在以往的经验中,只要我有@Test 上面我想测试的方法,相应方法中的所有断言语句都会出现在Eclipse 的JUnit 测试面板中。例如,一个带有 4 个用 Java 编写的断言语句的方法——所有四个断言都将显示在 Eclipse 中。这些用 Python 和 pyunit 编写的相同断言说“在 0.001 秒内运行 1 次测试,OK。”
  • pyunit 是第 3 方测试模块,不同于标准库中 CPython 附带的 unittest 模块。如果您使用的是unittest,那么您应该编辑文本以删除pyunitpyunit 标记。如果您发布了 MCVE stackoverflow.com/help/mcve,那么您使用的是哪个模块是毫无疑问的。
  • @TerryJanReedy wiki.python.org/moin/PyUnit 不同意? The docs 也说 unittest 有时被称为 PyUnit。这部分在 Python 3 的文档中已经消失了……
  • 看来 unittest 开始于名为 pyunit 的第 3 方模块,在 Junit 之后。该页面和单独的版本,最后一次更新是在 2001 年,有点像化石。标准库中的 Unittest 已经看到许多修复和更新,并且有不同的主要维护者。

标签: python python-unittest


【解决方案1】:

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 shell 中运行import this 发现):“简单胜于复杂”。因此,通过将类似的断言分组到一个方法中,让您的单元测试保持简单和结构化。

【讨论】:

    【解决方案2】:

    你的问题'''python 中的“规范”是什么?每个方法应该只有一个断言语句吗?''' 是“否”。有些人可能会说“是”,但包括我在内的 CPython 核心开发人员通常会在测试方法中使用多个断言。查看Lib/test 中的test_xyz 文件(如果您的安装包含该目录)。

    确实,一种方法应该测试一个单元,甚至一个单元的一种行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多