geekdoc-python-zh/docs/askpython/doctests-in-python.md

6.4 KiB
Raw Permalink Blame History

Python 中的文档测试——概述

原文:https://www.askpython.com/python-modules/doctests-in-python

让我们了解一下 Python 中一种特殊的测试和调试机制。Python 中的文档测试是函数的测试用例,它们可以用来验证函数是否按预期工作。

Python 中的 docstrings 是什么?

在我们继续进行文档测试之前,我们需要了解一下文档字符串

  • 文档字符串是包含在三重引号中的可选字符串,它是在声明函数时首先写入的。
  • 文档字符串用于描述一个函数。我们可以写一个函数做什么,它是如何工作的,它接受的参数数量,它返回的对象类型,等等。

所有这些都向程序员描述了函数的用途,程序员可以使用__doc__属性访问函数的 docstring。

让我们举一个打印数字阶乘的函数的例子..

def factorial(num):
    """
    A function that returns the factorial of a given number.
    No. of arguments: 1, Integer
    Returns: Integer
    """
    res = 1
    for i in range(1, num+1):
        res *= i
    print(res)

正如你所看到的,在声明函数之后,在做任何事情之前,我们写了一个用三重引号括起来的字符串来描述函数。 这将使该字符串成为该函数的文档,访问属性__doc__将返回该字符串。让我们现在做那件事。

print(factorial.__doc__)

输出:

 A function that returns the factorial of a given number.
    No. of arguments: 1, Integer
    Returns: Integer 

现在我们清楚了什么是 docstring我们可以继续进行 doctests 了。

Python 中的 doctests 是什么?

正如我们前面讨论的Python 中的 doctests 是在 docstring 内部编写的测试用例。在我们的例子中5 的阶乘是 120因此调用factorial(5)将打印120,同样,调用factorial(0)将打印1

这些可以是我们可以验证函数的测试用例,为此,我们在 docstring 中使用如下语法描述它们:

def factorial(num):
    """
    A function that returns the factorial of a given number.
    No. of arguments: 1, Integer
    Returns: Integer

    >>> factorial(5)
    120

    >>> factorial(0)
    1
    """
    res = 1
    for i in range(1, num+1):
        res *= i
    print(res)

如果您还记得 Python shell我们将所有代码都写在 shell 中的三个尖括号(>>>)之后,当我们按 enter 键时,代码会立即执行。

因此,如果我们通过 Python shell 调用factorial(5),它看起来就像我们在上面的 docstring 中编写的一样。

在 docstring 中指定这一点告诉 Python上面几行是在 shell 中运行factorial(5)后的预期输出。

类似地,下面我们写了factorial(0)的确切预期输出。

注意doctests 对空格和制表符很敏感,所以我们需要准确地写出我们想要的结果。

我们还可以指定函数由于错误输入而可能返回的异常和错误。

现在我们已经在函数中编写了一些 doctests让我们使用它们并检查函数是否正常工作。

Python 中成功的文档测试

import doctest
doctest.testmod(name='factorial', verbose=True)

这就是我们在 Python 中使用 doctests 的方式。我们导入一个名为doctest的模块,并使用它的testmod函数,如图所示。

输出将如下所示:

Trying:
    factorial(5)
Expecting:
    120
ok
Trying:
    factorial(0)
Expecting:
    1
ok
1 items had no tests:
    factorial
1 items passed all tests:
   2 tests in factorial.factorial
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
TestResults(failed=0, attempted=2)

如您所见,它将运行每个测试用例,并检查实际输出是否与预期输出相匹配。最后,它将打印测试结果,程序员将能够分析该函数的执行情况。

如果任何一个测试用例失败,它将在预期的输出之后打印出准确的输出,并指定最后失败的测试用例的数量。

Python 中失败的文档测试

让我们用 Python 做一些我们知道会失败的文档测试:

def factorial(num):
    """
    A function that returns the factorial of a given number.
    No. of arguments: 1, Integer
    Returns: Integer

    >>> factorial(5)
    120

    >>> factorial(0)
    1

    >>> factorial(2)
    Two
    """
    res = 1
    for i in range(1, num+1):
        res *= i
    print(res)

import doctest
doctest.testmod(name='factorial', verbose=True)

在第三个 doctest 中,发送2永远不会打印Two,所以让我们看看输出:

Trying:
    factorial(5)
Expecting:
    120
ok
Trying:
    factorial(0)
Expecting:
    1
ok
Trying:
    factorial(2)
Expecting:
    Two
**********************************************************************
File "__main__", line 13, in factorial.factorial
Failed example:
    factorial(2)
Expected:
    Two
Got:
    2
1 items had no tests:
    factorial
**********************************************************************
1 items had failures:
   1 of   3 in factorial.factorial
3 tests in 2 items.
2 passed and 1 failed.
***Test Failed*** 1 failures.
TestResults(failed=1, attempted=3)

对于第三个测试用例,它失败了,模块准确地显示了它是如何失败的,最后,我们看到尝试了三个测试用例,一个失败了。

Python 中 Doctests 的使用?

Python 中的 Doctests 是为了在创建函数时考虑预期的输出而使用的。

如果你需要一个函数在调用时准确地输出一些内容,那么你可以在 doctest 中指定它最后doctest 模块将允许你一次运行所有的测试用例,你将能够看到这个函数是如何执行的。

提到的测试用例应该正是你所期望的,如果其中任何一个失败了,那就表明函数中有一个 bug 应该被纠正。

成品的文件测试必须总是成功的。

虽然我们不能编写每一个测试用例,但是在一个大项目中,编写那些可能由于意外输入而失败的测试用例是一个好主意,比如 09999999-1或者“banana”。

结论

在本教程中,我们学习了 Python 中的 doctests 是什么,如何编写,如何使用,以及何时使用。

我们讨论了 doctests 如何成为程序员的测试机制,以及它如何使编写测试用例变得容易。

我希望你学到了一些东西,并在另一个教程中看到你。