Pytest----如何执行文本测试

简介: Pytest----如何执行文本测试

一、pytest执行txt文件格式的文档测试

pytest 命令本身就可以直接直接执行test*.txt格式的文档测试脚本,文档测试脚本内容默认就是python解释器中额内容,如下:

test_demo01.txt

>>> 1+1
2
>>> "a"*3
'aaa'
>>> 1+1
3

执行结果如下,第二个1+1的结果被手动修改为了3,所以导致了期望结果为3,实际计算结果为2,这就是文档测试

$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo01.txt F

=============================================================================== FAILURES ===============================================================================
______________________________________________________________________ [doctest] test_demo01.txt _______________________________________________________________________
001 >>> 1+1
002 2
003 >>> "a"*3
004 'aaa'
005 >>> 1+1
Expected:
    3
Got:
    2

D:\src\blog\tests\test_demo01.txt:5: DocTestFailure
======================================================================= short test summary info ========================================================================
FAILED test_demo01.txt::test_demo01.txt
========================================================================== 1 failed in 0.03s ===========================================================================

二、修改默认的文档测试文件格式

可以通过--doctest-glob参数指定文本文件格式,如下

test_demo01.log文件,内容如下:

>>> 1+1
2
>>> "a"*3
'aaa'

执行结果如下:

$ pytest -s --doctest-glob="*.log"
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo01.log .

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

三、执行类或者函数中的测试文本内容

在类或者函数的字符串注释中可以加入文本测试的内容,这些测试文本其实就是将python解释器交互环境中的内容,使用pytest执行的时候加上--doctest-modules参数即可执行这些文本测试,如下:

demo.py内容如下,即写了求两个数之和的函数,同时在注释中加入了个交互式测试内容

def add_two(a,b):
    """
    add two elem
    :param a:
    :param b:
    :return: a+b
    >>> add_two(1,10)
    11
    >>> add_two("a","b")
    'ab'
    >>> add_two([1,2,3],[5,6,7])
    [1, 2, 3, 5, 6, 7]

    """
    return a+b

执行结果如下,可以发现用例通过了

$ pytest --doctest-modules
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

demo.py .                                                                                                                                                         [100%]

========================================================================== 1 passed in 2.21s ===========================================================================

若想默认的pytest命令就执行文本测试,则只需要在pytest.ini中增加如下内容即可

[pytest]
addopts = --doctest-modules

此时执行结果如下:

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

demo.py .                                                                                                                                                         [100%]

========================================================================== 1 passed in 2.57s ===========================================================================

四、文档测试常用的选项参数

文档测试中可以通过doctest_optionflags指定一些常用的选项参数

(1)NORMALIZE_WHITESPACE参数,忽略前后的空白字符
test_demo.txt内容如下:

>>> print(111)
111

使用pytest执行结果如下:

$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt .

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

然后把test_demo.txt修改为如下,即在结果前面增加了几个空格

>>> print(111)
   111

再次执行

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt F                                                                                                                                                   [100%]

=============================================================================== FAILURES ===============================================================================
_______________________________________________________________________ [doctest] test_demo.txt ________________________________________________________________________
001 >>> print(111)
Expected:
       111
Got:
    111

D:\src\blog\tests\test_demo.txt:1: DocTestFailure
======================================================================= short test summary info ========================================================================
FAILED test_demo.txt::test_demo.txt
========================================================================== 1 failed in 0.03s ===========================================================================

此时当在pytest.ini文件中增加如下配置:

[pytest]
doctest_optionflags = NORMALIZE_WHITESPACE

再次执行,即可以哦谈过了

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt .                                                                                                                                                   [100%]

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

(2)IGNORE_EXCEPTION_DETAIL参数
test_demo.txt内容如下:

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

执行结果如下:

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt .                                                                                                                                                   [100%]

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

当把测试内容修改如下,即只保留第一行和最后一行,此时就需要使用IGNORE_EXCEPTION_DETAIL参数了

>>> 1/0
Traceback (most recent call last):
ZeroDivisionError: division by zero

在pytest.ini配置文件中使用如下配置:

[pytest]
doctest_optionflags = NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL

如此,才能使测试通过

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt .                                                                                                                                                   [100%]

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

(3)NUMBER 参数,当NUMBER 激活后,对于浮点数数值,匹配结果只要匹配到跟期望值相同的位置时一样就算通过了

如 pytest.ini配置如下:

[pytest]
doctest_optionflags = NUMBER

在交互式解释器中计算math.pi结果如下:

>>> import math
>>> math.pi
3.141592653589793

test_demo.txt内容如下:

>>> import math
>>> math.pi
3.14

执行pytest的结果如下,是可以通过的

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt .                                                                                                                                                   [100%]

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

此时把pytest.ini中的配置删掉,再次执行,结果如下,发现此时是失败的

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt F                                                                                                                                                   [100%]

=============================================================================== FAILURES ===============================================================================
_______________________________________________________________________ [doctest] test_demo.txt ________________________________________________________________________
001 >>> import math
002 >>> math.pi
Expected:
    3.14
Got:
    3.141592653589793

D:\src\blog\tests\test_demo.txt:2: DocTestFailure
======================================================================= short test summary info ========================================================================
FAILED test_demo.txt::test_demo.txt
========================================================================== 1 failed in 0.03s ===========================================================================

(4)其他常用参数

  • ALLOW_UNICODE 默认将字符串前的u去掉
  • ALLOW_BYTES 默认将字符串前的b去掉

五、文档测试失败后继续执行

首先如下脚本,test_demo.txt内容,即第一个1+2期望结果是0显然是失败的

>>> 1+2
0
>>> 2+3
4

执行结果如下,可以发现当第一条失败后,后面的2+3则没有执行,这样的处理逻辑在有时候是不合适的,比如有100个用例,本意是想看看100个能有多少个鞥通过,结果遇到失败后面的就不执行了,这显然不合理,此时就需要失败继续执行的操作

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt F                                                                                                                                                   [100%]

=============================================================================== FAILURES ===============================================================================
_______________________________________________________________________ [doctest] test_demo.txt ________________________________________________________________________
001 >>> 1+2
Expected:
    0
Got:
    3

D:\src\blog\tests\test_demo.txt:1: DocTestFailure
======================================================================= short test summary info ========================================================================
FAILED test_demo.txt::test_demo.txt
========================================================================== 1 failed in 0.03s ===========================================================================

为失败继续执行,使用--doctest-continue-on-failure参数即可,结果如下,可以看出,第二个也拨错了,说明第一个失败后,第二个也执行了

$ pytest --doctest-continue-on-failure
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt F                                                                                                                                                   [100%]

=============================================================================== FAILURES ===============================================================================
_______________________________________________________________________ [doctest] test_demo.txt ________________________________________________________________________
001 >>> 1+2
Expected:
    0
Got:
    3

D:\src\blog\tests\test_demo.txt:1: DocTestFailure
001 >>> 1+2
002 0
003 >>> 2+3
Expected:
    4
Got:
    5

D:\src\blog\tests\test_demo.txt:3: DocTestFailure
======================================================================= short test summary info ========================================================================
FAILED test_demo.txt::test_demo.txt
========================================================================== 1 failed in 0.03s ===========================================================================

若让pytest默认执行此策略,则可以在pytest.ini中按照如下设置:

[pytest]
addopts = --doctest-continue-on-failure

六、设置失败报告输出格式类型

如下,为文档测试几种报告输出格式,有一些细微差别,可自行选择

pytest --doctest-report none
pytest --doctest-report udiff
pytest --doctest-report cdiff
pytest --doctest-report ndiff
pytest --doctest-report only_first_failure

七、文档测试中调用fixture

使用getfixure函数,参数填写fixture名称即可获取到该fixture的对象,如下
test_demo.py代码如下:

import pytest

@pytest.fixture()
def get_ten():
    return 10


def add_two(a,b):
    """
    >>> ten=getfixture("get_ten")
    >>> ten
    10
    """
    return a+b

执行结果如下:

$ pytest  --doctest-modules
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.py .                                                                                                                                                    [100%]

========================================================================== 1 passed in 3.40s ===========================================================================

八、如何使用doctest_namespace

doctest_namespace简单点说可以定义一些变量使用,如下便是一个例子

conftest.py中写一个自动加载的fixture

import pytest
import numpy


@pytest.fixture(autouse=True)
def add_np(doctest_namespace):
    doctest_namespace["np"] = numpy

test_demo.py编写如下函数,其中有文档测试

def arange():
    """
    >>> a = np.arange(10)
    >>> len(a)
    10
    """
    pass

执行结果如下,即在conftest.py中想其中写入np对应的值,然后再测试文件的文档测试中可以直接使用np变量

$ pytest  --doctest-modules
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.py .                                                                                                                                                    [100%]

========================================================================== 1 passed in 4.22s ===========================================================================

九、文档测试中的skip的应用

如下,在测试步骤后面加上‘# doctest: +SKIP’的注释即可跳过

test_demo.py代码如下:

def test_random():
    """
    >>> 1+2 # doctest: +SKIP
    0
    >>> 1 + 1
    2
    """

执行结果如下:

$ pytest  --doctest-modules
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 2 items                                                                                                                                                       

test_demo.py ..                                                                                                                                                   [100%]

========================================================================== 2 passed in 2.39s ===========================================================================

为了验证上述结论正确性,将上述跳过的注释去掉,即代码如下:

def test_random():
    """
    >>> 1+2 
    0
    >>> 1 + 1
    2
    """

执行结果如下;

$ pytest  --doctest-modules
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 2 items                                                                                                                                                       

test_demo.py F.                                                                                                                                                   [100%]

=============================================================================== FAILURES ===============================================================================
___________________________________________________________________ [doctest] test_demo.test_random ____________________________________________________________________
002
003     >>> 1+2
Expected:
    0
Got:
    3

D:\src\blog\tests\test_demo.py:3: DocTestFailure
======================================================================= short test summary info ========================================================================
FAILED test_demo.py::test_demo.test_random
===================================================================== 1 failed, 1 passed in 3.78s ======================================================================

也可以直接在注释文档中使用pytest.skip()函数,这里需要注意的是,如果在py文件即模块的函数或者类的注释文档中,pytest.skip()只能跳过当前注释文档段,不会影响当前文件其他文档注释,如下:

demo_demo.py

def test_demo01():
    """
    >>> import pytest
    >>> a=10
    >>> if a>0:
    ...     pytest.skip()
    >>> 1 + 1
    3
    """
    pass

def test_demo02():
    """
    >>> 1 + 1
    3
    """
    pass

执行结果如下:

$ pytest  --doctest-modules
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 4 items                                                                                                                                                       

test_demo.py sF..                                                                                                                                                 [100%]

=============================================================================== FAILURES ===============================================================================
___________________________________________________________________ [doctest] test_demo.test_demo02 ____________________________________________________________________
013
014     >>> 1 + 1
Expected:
    3
Got:
    2

D:\src\blog\tests\test_demo.py:14: DocTestFailure
======================================================================= short test summary info ========================================================================
FAILED test_demo.py::test_demo.test_demo02
================================================================ 1 failed, 2 passed, 1 skipped in 6.38s ================================================================

这里需要注意,当在txt文件中使用了skip,则skip后面的所有步骤都忽略

test_demo.txt内容如下:

>>> import pytest
>>> pytest.skip()
>>> 1+2
0
>>> 2+3
1
>>> 2+4
2

执行结果如下,可以看出,剩余的其他都跳过了

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item                                                                                                                                                        

test_demo.txt s                                                                                                                                                   [100%]

========================================================================== 1 skipped in 0.03s ==========================================================================
目录
相关文章
|
7月前
|
存储 设计模式 测试技术
怎么基于Pytest+Requests+Allure实现接口自动化测试?
该文介绍了一个基于Python的自动化测试框架,主要由pytest、requests和allure构成,采用关键字驱动模式。项目结构分为六层:工具层(api_keyword)封装了如get、post的请求;参数层(params)存储公共参数;用例层(case)包含测试用例;数据驱动层(data_driver)处理数据;数据层(data)提供数据;逻辑层(logic)实现用例逻辑。代码示例展示了如何使用allure装饰器增强测试报告,以及如何使用yaml文件进行数据驱动。
221 0
|
3月前
|
测试技术
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
本文介绍了如何使用Pytest和Allure生成自动化测试报告。通过安装allure-pytest和配置环境,可以生成包含用例描述、步骤、等级等详细信息的美观报告。文章还提供了代码示例和运行指南,以及重构项目时的注意事项。
324 1
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
|
3月前
|
测试技术 Python
自动化测试项目学习笔记(四):Pytest介绍和使用
本文是关于自动化测试框架Pytest的介绍和使用。Pytest是一个功能丰富的Python测试工具,支持参数化、多种测试类型,并拥有众多第三方插件。文章讲解了Pytest的编写规则、命令行参数、执行测试、参数化处理以及如何使用fixture实现测试用例间的调用。此外,还提供了pytest.ini配置文件示例。
67 2
|
4月前
|
SQL JavaScript 前端开发
基于Python访问Hive的pytest测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Python、来开发Hive应用的方法,产生的代码如下
85 6
基于Python访问Hive的pytest测试代码实现
|
5月前
|
前端开发 关系型数据库 测试技术
django集成pytest进行自动化单元测试实战
在Django项目中集成Pytest进行单元测试可以提高测试的灵活性和效率,相比于Django自带的测试框架,Pytest提供了更为丰富和强大的测试功能。本文通过一个实际项目ishareblog介绍django集成pytest进行自动化单元测试实战。
77 3
django集成pytest进行自动化单元测试实战
|
5月前
|
Web App开发 安全 测试技术
自动化测试中的Python魔法:使用Selenium和pytest框架
【8月更文挑战第31天】 在软件开发的海洋中,自动化测试是确保航行安全的灯塔。本文将带你探索如何利用Python语言结合Selenium和pytest框架,搭建一套高效的自动化测试体系。我们将从基础设置讲起,逐步深入到编写测试用例,最后通过一个实战案例来展示如何在实际项目中运用这些工具。文章旨在为读者提供一套清晰的自动化测试解决方案,让你的开发之旅更加顺畅。
|
6月前
|
Shell Python
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
|
6月前
|
监控 Python
`pytest-qt` 是一个用于在 Qt 应用程序中进行 GUI 测试的 pytest 插件。
`pytest-qt` 是一个用于在 Qt 应用程序中进行 GUI 测试的 pytest 插件。
|
8月前
|
jenkins 测试技术 持续交付
Pytest测试框架
Pytest是一个功能强大的测试框架,支持单元测试和复杂功能测试,可结合Requests和Selenium等进行接口和自动化测试。它拥有超过315个插件,兼容unittest,并能与Allure、Jenkins集成实现持续集成。安装可通过pip或Pycharm。Pytest遵循特定命名规则,测试用例由名称、步骤和断言组成。断言用于验证预期结果,当失败时程序会终止。Pytest提供setup/teardown机制来管理测试前后的资源。
|
8月前
|
测试技术 iOS开发
pytest Mark标记测试用例
使用`pytest.mark`进行测试用例分组和筛选,如`@pytest.mark.webtest`。通过`pytest -m`参数执行特定标记的用例,例如`pytest -s test_command_param.py -m webtest`。同时,pytest支持内置的skip、skipif和xfail功能来管理特殊用例:skip始终跳过,skipif条件满足时跳过,xfail则标记预期失败的测试。