Python中的文档测试与类型标注
所需环境
- Python 3.7
- IDE (这里使用VS Code)
Python测试
-
unittest
模块 -
doctest
模块
比较
测试方法 | 应用方法 | 功能 | 特点 |
---|---|---|---|
unittest |
assert |
专注于测试 | 使用复杂+精确 |
doctest |
testmod , testfile 方法 |
文档+测试 | 使用简单+不精确(全部依赖于字符串,要考虑字符串转义以及__repr__ 方法)+支持unittest
|
doctest
主要用途
- 检查docstring中的示例
- 回归测试
- 为包编写教程文档
doctest
模块使用
testmod()
方法
- 见
doctest_example.py
testfile()
方法
- 见
doctest_example.py
- 替代品
python -m doctest -v doctest_example.txt
输出内容
- 只将测试失败的用例和原因输出到stdout
- 若还要输出正确的,在CLI中添加
-v
参数
例外
- 见
doctest_exceptions_example.py
- 常用
# doctest: +ELLIPSIS
# doctest: +SKIP
- doctest Directives
doctest原理
- 见
how_doctest_works.py
- 对象(
module
,class
,function
)的__doc__
属性 -
globs
参数 注入测试执行上下文- 可以是自己构建的
dict
可以是locals()
,globals()
- 可以是自己构建的
doctest的好处
- 测试
- 自动生成文档
-
pydoc
模块读取__doc__
- 可以通过IDE直接看一个对象
- TDD闭环
- 若需要新特性,则添加一个新的测试用例
- 运行所有测试用例,新的用例会失败
- 编写通过新测试用例的最简单的代码,并且使得所有测试用例通过
- 根据需要进行重构
Python类型标注
typing
模块
- 最近更新很快,3.7
- PEP 484 输入提示
- PEP 526 变量注释
- PEP 483 输入提示理论
重要
- 类型标注只用于静态检查,运行时不会强制检查函数标注和变量注释
typing
模块使用
常用类型
None
Tuple[int, ...]
-
List[int]
,Sequence[int]
-
Dict[str, str]
,Mapping[str, str]
Union[int, str]
-
Optional[int]
等价于Union[int, None]
Callable[[Arg1Type, Arg2Type], ReturnType]
-
Iterable[int]
,Iterator[int]
Generator[YieldType, SendType, ReturnType]
泛型与用户自定义泛型
- 方括号
T = TypeVar('T')
type(..., (Generic[T], ...), dict=...)
typing
原理
- 对象的
__annotations__
属性
好处
- 继承静态检查的部分好处
- 在IDE中发现错误
- 有类型签名,开发体验好
- 复杂/不重要的变量类型标注可以写
Any
或者不写,保持Python的灵活
坏处
- 继承静态检查的坏处
- 死板,
pylance
几乎一直会犯错 - 复杂
- 某个变量的类型标注是固定的,不能改变
- 死板,
- 静态检查依赖于你自己写的类型标注,首先保证自己写对
- Python类型标注在3.5后才有,并且更新很快,许多内置包的类型标注不对