11. 文档和测试
在软件开发的过程中,除了代码的编写外,还有两个重要的环节,分别是代码对应的文档和代码的测试。对于编写好的函数或者方法,详细的文档将会帮助使用者更好的使用,代码的测试则是为了更好的交付,保证代码的正常运行。在 Python 中对应的提供了强大的文档生成和查看模块 pydoc
以及单元测试框架 unittest
。
11.1. 文档的生成和查看
为函数、类以及类中方法等编写文档,只需要在函数、类以及类中方法的定义后再定一个字符串即可,这个字符串就是对应函数、类以及类中方法的文档。新建一个名为 document.py
的 Python 文件,详细代码如下所示:
def my_max(x, y):
'''
返回变量 x 和变量 y 中较大的值
'''
z = x if x > y else y
# 返回变量 z 的值
return z
class Person:
'''
定义一个 Person 类
类中包括 name 、 age 两个变量
'''
def __init__(self, name, age):
'''
name 初始化该用户的 name
age 初始化该用户的 age
'''
self.name = name
self.age = age
def info(self):
'''
定义信息输出的方法
'''
print("Hello, ", self.name, " , ", self.age)
11.1.1. help()
函数和 __doc__
属性
Python 中内置的 help()
函数可以用于查看指定函数的说明文档,也可以通过函数的 __doc__
属性查看函数的说明文档,以 document
模块中的 my_max()
函数为例,首先是 help()
函数,具体的使用方法如下代码所示:
from document import my_max
# 使用 help() 函数查看 my_max() 函数的帮助文档
help(my_max)
运行代码,得到如下的运行结果:
__doc__
属性的使用方法如下代码所示:
from document import my_max
# 使用 __doc__ 属性查看 my_max() 函数的帮助文档
print(my_max.__doc__)
运行代码,得到如下的运行结果:
类与函数的帮助信息的查看方法一样,只是将上述的函数名替换成类名即可。
11.1.2. 使用 pydoc
生成文档
通过 Python 内置的 pydoc
模块,也可以生成、查看帮助文档,使用 pydoc
模块在控制台中查看帮助文档的命令如下:
python3 -m pydoc module_name
其中, -m
是 Python 命令的一个选项,表示运行指定模块,此处表示运行 pydoc
模块。针对上述的 document
模块,执行以下的命令:
python3 -m pydoc document
运行上述命令后,得到如下的结果:
这种在控制台中查看指定模块的帮助信息依然不太方便,通过 pydoc
模块可以生成 HTML 格式的文档,命令如下:
python3 -m pydoc -w module_name
与之前的命令对比,只是额外指定了-w
选项,该选项代表 write
,表明输出 HTML 文挡,针对上述的 document
模块,运行命令后得到一个 document.html
文件,打开文件可以看到完整的帮助文档:
11.2. 代码测试
通常在编写完代码后,除了要有完善的文档,另一个方面就是在交付代码前进行详细的测试,最简单的测试方法可以使用 print()
方法测试需要测试的运行结果的值。
上述的方法只能是在开发的过程中检查基本的编码逻辑,验证程序的运行结果是否符合预期,是一种非正规的软件测试方法。单元测试是软件测试领域使用较多的一种测试方法,作为一个软件的开发人员需要了解并掌握基本的单元测试方法。在 Python 中提供了 PyUnit
单元测试框架,通过使用 PyUnit
,开发人员可以非常方便地为函数、类提供配套的、可复用的单元测试。
11.2.1. 使用 PyUnit
—— unittest
PyUnit
是一个简单、易用的测试框架,其使用断言方法判断期望值和实际值的差异,返回 bool 值。以下述一个简单的 my_add()
函数和 my_sub()
函数为例,新建一个 my_fun.py
文件,具体的代码如下所示:
def my_add(a, b):
'''
实现简单的加法运算
'''
return a + b
def my_sub(a, b):
'''
实现简单的减法运算
'''
return a - b
接下来为该模块编写单元测试代码,要想使用 unittest
,在单元测试类中必须继承 unittest.TestCase
,该类中的测试方法需要满足以下几个条件,第一,测试方法没有返回值,第二,测试方法不能有任何参数,第三,测试方法应以 test
开头。因此新建一个test_my_fun.py
文件,具体的代码如下所示:
import unittest
from my_fun import my_add, my_sub
class TestModule(unittest.TestCase):
# 测试 add() 函数
def test_my_add(self):
# 断言 add() 函数的值
self.assertEqual(my_add(5, 9), 14)
self.assertTrue(my_add(4, 10) == 14)
self.assertFalse(my_add(4, 10) == 13)
# 测试 sub() 函数
def test_my_sub(self):
# 断言 sub() 函数的值
self.assertEqual(my_sub(9, 5), 4)
self.assertTrue(my_sub(10, 4) == 6)
self.assertFalse(my_sub(10, 4) == 5)
编写完上述的测试代码后,要想运行测试,需要在 增加如下的代码:
if __name__ == "__main__":
unittest.main()
运行上述的 Python 文件,如果没有错误,将得到如下结果:
除了上述的断言,在 unittest.TestCase
中还内置了其他的一些方法来执行断言,常用的方法如下所示:
11.2.2. 跳过测试用例
在默认情况下, unittest
会自动测试每一个测试用例,但如果希望临时跳过某个测试用例,则可以通过如下两种方式来实现。
- 使用
skipXxx
装饰器来跳过测试用例。unittest
一共提供了 3 个装饰器,分别是@unittest.skip(reason)
、@unittest.skipIf(condition, reason)
和@unittest.skipUnless(condition, reason)
- 使用
TestCase
的skipTest()
方法来跳过测试用例
具体使用方法如下代码所示:
# 跳过测试 sub() 函数
@unittest.skip("skip my_sub")
def test_my_sub(self):
# 断言 sub() 函数的值
self.assertEqual(my_sub(9, 5), 4)
self.assertTrue(my_sub(10, 4) == 6)
self.assertFalse(my_sub(10, 4) == 5)
11.3. 本章小结
本章主要介绍了与 Python 开发相关的两个相关知识,即文档和测试。对于编写好的函数或者方法,详细的文档将会帮助使用者更好的使用,代码的测试则是为了更好的交付,保证代码的正常运行。Python 提供了 pydoc
工具来查看、生成文档,只要开发者为 Python 程序提供了符合格式的文档说明,使用 pydoc
就可直接查看程序中的文档,也可为之生成 HTML 文档。 Python 还提供了单元测试框架 unittest
,方便使用断言的方式对代码进行测试。
本章需要掌握知识点:
- 掌握
pydoc
生成文档,查看文档 - 掌握单元测试框架
unittest
的使用方法