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 ==========================================================================
目录
相关文章
|
4月前
|
数据可视化 测试技术 持续交付
自动化测试神器:Python之Pytest库入门使用
自动化测试神器:Python之Pytest库入门使用
102 4
|
4月前
|
存储 测试技术 Python
软件测试/测试开发全日制|Pytest结合CSV实现测试的数据驱动
软件测试/测试开发全日制|Pytest结合CSV实现测试的数据驱动
37 0
|
4月前
|
存储 测试技术 Python
软件测试/测试开发全日制|Pytest结合Excel实现数据驱动
软件测试/测试开发全日制|Pytest结合Excel实现数据驱动
43 0
|
4月前
|
存储 测试技术 Python
软件测试/测试开发全日制|Pytest结合yaml实现数据驱动
软件测试/测试开发全日制|Pytest结合yaml实现数据驱动
43 0
|
4月前
|
测试技术
软件测试/测试开发/全日制|Pytest如何灵活地运行用例
软件测试/测试开发/全日制|Pytest如何灵活地运行用例
35 0
|
8月前
|
Web App开发 前端开发 JavaScript
SAP UI5 应用开发教程之八十五 - 如何用 OPA5 编写测试用例来测试用户输入文本的功能试读版
SAP UI5 应用开发教程之八十五 - 如何用 OPA5 编写测试用例来测试用户输入文本的功能试读版
35 0
|
20天前
|
前端开发 测试技术 C++
Python自动化测试面试:unittest、pytest与Selenium详解
【4月更文挑战第19天】本文聚焦Python自动化测试面试,重点讨论unittest、pytest和Selenium三大框架。unittest涉及断言、TestSuite和覆盖率报告;易错点包括测试代码冗余和异常处理。pytest涵盖fixtures、参数化测试和插件系统,要注意避免过度依赖unittest特性。Selenium的核心是WebDriver操作、等待策略和测试报告生成,强调智能等待和元素定位策略。掌握这些关键点将有助于提升面试表现。
26 0
|
3月前
|
测试技术 API Python
Python自动化测试:unittest与pytest的实战技巧
Python自动化测试:unittest与pytest的实战技巧
|
4月前
|
测试技术 Python
设置pycharm使用pytest执行测试用例时,输出print语句至控制台
设置pycharm使用pytest执行测试用例时,输出print语句至控制台
66 0
|
4月前
|
测试技术
软件测试/测试开发全日制|Pytest中yield的用法详解
软件测试/测试开发全日制|Pytest中yield的用法详解
27 0

热门文章

最新文章