pytest中文使用文档----9集成文档测试

  • [1. 集成doctest模块](#1. 集成doctest模块)
    • [1.1. 通过指定文本文件的方式](#1.1. 通过指定文本文件的方式)
      • [1.1.1. 文本文件的编码](#1.1.1. 文本文件的编码)
    • [1.2. 通过编写文档字符串的方式](#1.2. 通过编写文档字符串的方式)
    • [1.3. 指定额外的选项](#1.3. 指定额外的选项)
      • [1.3.1. doctest标准库自带的选项](#1.3.1. doctest标准库自带的选项)
      • [1.3.2. pytest自有的选项](#1.3.2. pytest自有的选项)
  • [2. 失败时继续执行](#2. 失败时继续执行)
  • [3. 指定输出的格式](#3. 指定输出的格式)
  • [4. 文档测试中使用fixture](#4. 文档测试中使用fixture)
  • [5. 文档测试的命名空间](#5. 文档测试的命名空间)
  • [6. 跳过文档测试](#6. 跳过文档测试)

1. 集成doctest模块

doctest是python内置的一个标准库,它可以查找代码中类似交互式会话形式的注释,并检查它们是否正确;

1.1. 通过指定文本文件的方式

默认情况下,pytest会自动收集所有名称匹配test*.txt规则的文件,并调用doctest执行它们;

下面,我们来看一个简单的例子:

python 复制代码
# src/chapter-9/test_example.txt

>>> x = 3
>>> x
3

直接使用pytest命令就可以执行它:

bash 复制代码
λ pytest src/chapter-9/test_example.txt
====================== test session starts ======================= 
platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0
rootdir: D:\Personal Files\Projects\pytest-chinese-doc
collected 1 item

src\chapter-9\test_example.txt .                            [100%]

======================= 1 passed in 0.03s ========================

我们也可以使用命令行选项--doctest-glob添加文件名称的匹配规则;

例如,匹配rst格式的文件:

bash 复制代码
pytest --doctest-glob='*.rst'

注意:--doctest-glob可以多次指定,它们之间是或者 的关系,并且依旧支持默认的test*.txt规则;

1.1.1. 文本文件的编码

doctest文件的默认编码是UTF-8 ,你可以在pytest.ini中使用doctest_encoding选项指定新的编码;例如,使用latin1编码:

ini 复制代码
[pytest]
doctest_encoding = latin1

1.2. 通过编写文档字符串的方式

除了文本文件外,pytest还支持检查文档字符串中的注释;例如:

python 复制代码
# src/chapter-9/test_module.py

def something():
    '''文档字符串示例
    
    >>> something()
    42
    '''
    return 42


def test_module():
    assert something() == 42

执行时,需要添加--doctest-modules命令行选项:

bash 复制代码
λ pytest --doctest-modules src/chapter-9/test_module.py
====================== test session starts ======================= 
platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0
rootdir: D:\Personal Files\Projects\pytest-chinese-doc
collected 2 items

src\chapter-9\test_module.py ..                             [100%]

======================= 2 passed in 0.03s ========================

--doctest-modules会查找所有名称匹配*.py的文件,收集文档字符串中类似交互式会话形式的注释,并把每一个文档字符串作为一个用例来执行,所以上面我们执行了两个测试,其中一个是文档测试;

如果想让pytest --doctest-modules正确收集到相关注释,需满足以下条件:

  • 文件名称符合*.py规则,但无需满足test_*.py或者*_test.py规则;
  • 文档字符串中的注释必须是类似python交互式会话形式的注释;

如果你不想每次执行都指定--doctest-modules选项,可以考虑在pytest.ini中添加如下配置:

ini 复制代码
[pytest]
addopts = --doctest-modules

文档字符串是一个多行字符串,使用'''或者"""包裹;一般推荐形式为,第一行简述功能,第二行空行,第三行具体描述;

并且,可以通过__doc__属性访问它;例如,上面例子的__doc__属性为:

bash 复制代码
>>> print(something.__doc__)
文档字符串示例

 >>> something()
 42

1.3. 指定额外的选项

1.3.1. doctest标准库自带的选项

python的doctest标准库自带一些选项,用于定义文档测试的模式,我们同样可以在pytest.ini中使用这些功能;例如,忽略尾随的空格:

ini 复制代码
# src/chapter-9/pytest.ini

doctest_optionflags = NORMALIZE_WHITESPACE

另外,你也可以在行注释中使能这些选项;

例如,使用# doctest: +NORMALIZE_WHITESPACE同样能忽略尾随的空格:

python 复制代码
def something():
    '''文档字符串示例
    
    >>> something()  # doctest: +NORMALIZE_WHITESPACE
    42 
    '''
    return 42

更多细节可以参考:https://docs.python.org/3/library/doctest.html#option-flags

1.3.2. pytest自有的选项

ALLOW_BYTES:在输出时,剔除字符串的b前缀;例如,以下文档测试是成功的:

python 复制代码
# src/chapter-9/options.py

def str_bytes():
    '''返回字节编码

    >>> str_bytes()  # doctest: +ALLOW_BYTES
    'bytes'
    ''' 
    return b'bytes'

ALLOW_UNICODE:相似的,在输出时,剔除字符串的u前缀;

NUMBER:为了避免出现以下导致测试失败的情况:

bash 复制代码
Expected:
    3.14
Got:
    3.141592653589793

我们可以通过配置NUMBER选项,只比较列出的精度:

python 复制代码
# src/chapter-9/options.py

def number():
    '''浮点数的精度

    >>> import math
    >>> math.pi  # doctest: +NUMBER
    3.14 
    '''
    return 1

注意:我们并不建议在全局使能NUMBER选项,因为它会修改输出中所有的浮点数的精度,甚至是在字符串或者列表中;

例如,以下文档测试也是成功的:

python 复制代码
# src/chapter-9/options.py

def str_number():
 '''浮点数字符串的精度

 >>> str_number()  # doctest: +NUMBER
 '3.14' 
 '''
 return '3.1415'

2. 失败时继续执行

默认情况下,对于一个给定的文档测试,pytest在遇到第一个失败点时退出执行;但是,我们可以通过--doctest-continue-on-failure命令行选项,让其继续执行;

例如,对于以下文档字符串,包含两个测试点,pytest --doctest-continue-on-failure会报告两个错误(默认只会报告第一个错误):

python 复制代码
def str_bytes():
    '''返回字节编码

    >>> str_bytes()  
    'bytes' 
    >>> import math
    >>> math.pi  
    3.14 
    ''' 
    return b'bytes'

3. 指定输出的格式

文档测试失败时,你可以通过以下方式更改测试输出的格式:

bash 复制代码
pytest --doctest-modules --doctest-report none
pytest --doctest-modules --doctest-report udiff
pytest --doctest-modules --doctest-report cdiff
pytest --doctest-modules --doctest-report ndiff
pytest --doctest-modules --doctest-report only_first_failure

更多细节可以参考:https://docs.python.org/3/library/doctest.html#doctest.REPORT_UDIFF

4. 文档测试中使用fixture

通过getfixture可以让你在文档字符串中使用fixture:

python 复制代码
>>> tmp = getfixture('tmpdir')
>>> ...
>>>

5. 文档测试的命名空间

doctest_namespace fixture可以用于向运行doctest测试的命名空间中注入一些信息,它是一个标准的字典对象;

例如,我们在conftest.py中定义一个方法,注入到doctest的命名空间中:

python 复制代码
# src/chapter-9/conftest.py

import pytest


def func():
    return 42


@pytest.fixture(autouse=True)
def add_func(doctest_namespace):
    doctest_namespace['function'] = func

可以在文档字符串中直接使用它:

python 复制代码
# src/chapter-9/func.txt

>>> function()
42

6. 跳过文档测试

pytest 4.4版本新增功能

我们可以通过pytest.skip跳过文档测试;例如,跳过Windows系统上的文档测试:

python 复制代码
>>> import sys, pytest
>>> if sys.platform.startswith('win'):
...     pytest.skip('this doctest does not work on Windows')
>>> function()
42
相关推荐
哦虎!1 小时前
【JavaEE】网络初识
java
砚凝霜1 小时前
【软考信息安全】第二十二章 Web服务器安全分析与增强——Apache与IIS
服务器·前端·安全
Android系统攻城狮1 小时前
Linux Gstreamer深度解析之gst_audio_ring_buffer_delay调用流程与实战(七十二)
linux·运维·服务器·gstreamer音视频·音视频进阶
for_ever_love__1 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
数字新视界2 小时前
机房动环监控提升运维效率
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
我是人✓2 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡2 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室3 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
U-Mail邮件系统3 小时前
自建邮箱服务器有哪些软件?三款主流邮件服务器软件推荐
运维·服务器
慧都小项3 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs