Pytest使用简介

Pytest是一种基于python的测试框架,用于编写和运行测试代码。pytest主要用来测试API,但也可以进行一些复杂的测试,像测试数据库或UI等。

Pytest 的优势:

  • Pytest 可以并行执行多个tests, 减少 test-suite 的执行时间 [第八章]
  • Pytest 可以自动地检测测试文件或测试函数,不需要被显示地提及 [第二章]
  1. test_*.py 文件
  2.  *_test.py 文件
  3. test* 函数 
  • Pytest 允许我们在运行过程中跳过一些test,执行整个test-suite的子集 [第三,四,五,六章]
  • Pytest 免费开源,易学

(一)pytest 安装

安装 pytest: pip3 install pytest
查看 pytest 是否安装成功:pip3 show pytest
复制代码

若安装成功,将会有如下显示

Name: pytest

Version: 5.3.5

Summary: pytest: simple powerful testing with Python

Home-page: https://docs.pytest.org/en/latest/

Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others

Author-email: None

License: MIT license

Location: /usr/local/lib/python3.7/site-packages

Requires: pluggy, py, importlib-metadata, more-itertools, wcwidth, attrs, packaging

Required-by: 

复制代码

(二)Pytest 测试文件/函数

2.1. Pytest 测试文件Pytest命令会自动运行当前目录下所有' test_*.py'  和 '_test.py' 文件 [1], 自动默认这些文件是测试文件。当然,我们也可以显示地指示要要运行的测试文件或测试目录。

Running pytest without mentioning a filename will run all files of format test_*.py or *_test.py in the current directory and subdirectories. Pytest automatically identifies those files as test files. We can make pytest run other filenames by explicitly mentioning them.

pytest a.py
pytest dirname

2.2. Pytest 测试函数:Pytest需要被测试函数以‘test’开头命名,不以'test' 开头的函数会被pytest自动忽略,pytest不可以像指定文件一样显示地指定被测函数,即测试函数必须以'test'开头。

Pytest requires the test function names to start with test. Function names which are not of format test* are not considered as test functions by pytest. We cannot explicitly make pytest consider any function not starting with test as a test function.

【例子1】创建Pytest文件夹,新建文件 test_nn.py 和 test_greater.py 和 test.py. 目录结构如下

Pytest

|- test.py

|- test_great.py: test_greater(); test_greater_equal(); test_less();

|- test_nn.py: testx(); test_great_haha();

运行 pytest 命令,只显示 test_great.py 和 test_nn.py 文件,因为[1],其中 test_great.py 代码如下

复制代码
def test_greater():
    num = 100
    assert num > 100

def test_greater_equal():
    num = 100
    assert num >= 100

def test_less():
    num = 100
    assert num < 200
View Code
复制代码

运行pytest 和 pytest -v 命令,运行结果分别如下左右图所示,-v 显示更

      

(三)Pytest 可以选择性测试完整test-suite的某个子集(subset)

3.1. 依照文件名匹配的方式选择测试子集 (select tests to run based on substring matching of test names)

pytest -k <substring> -v

针对【例子1】

pytest -k great -v 命令 ('great' 对应 <substring>项) 执行所有带有great的测试, 

注意:pytest -k 'substring' -v: 可识别当前目录下所有匹配文件中带有 ‘substring’ 的测试函数。

3.2. 根据 标记 选择测试组进行测试 (select tests groups to run based on the markers applied)

添加相关包:import pytest
插入标记:@pytest.mark.<markname> 运行带标记的测试:pytest -m <markname> -v

[例子2] 带标记 (marker) 的 test_mark.py 文件如下

复制代码
import pytest
@pytest.mark.great
def test_greater():
    num = 100
    assert num > 100

@pytest.mark.great
def test_greater_equal():
    num = 100
    assert num >= 100

@pytest.mark.others
def test_less():
    num = 100
    assert num < 200
View Code
复制代码

(四)Pytest 通过 Fixture 和 conftest.py 加载测试所需调用

@pytest.fixture

Fixture 是测试的输入,测试被执行前, 涉及到的 fixture 会被执行到。Pytest 提供了 @pytest.fixture 将该部分代码自动附加到测试函数中

【注意】(1) 如果不加 @pytest.fixture 的话,这部分被测试函数调用的代码不会加载进入测试函数,pytest运行时会报错 ...

            (2) @pytest.fixture 的作用域是当前文件,在其他文件中调用该 fixture 对应的函数会报错.We cannot use that fixture in another test file

Fixtures are functions, which will run before each test function to which it is applied. Fixtures are used to feed some data to the tests such as database connections, URLs to test and some sort of input data. Therefore, instead of runnng the same code for every test, we can attach fixture to the tests and it will run and return the data to the test before executing each test.

【例子3.1】创建 test_div.py 内容如下

复制代码
import pytest
@pytest.mark.great
def test_greater():
    num = 100
    assert num > 100

@pytest.mark.great
def test_greater_equal():
    num = 100
    assert num >= 100

@pytest.mark.others
def test_less():
    num = 100
    assert num < 200
View Code
复制代码

为了克服(2)的限制, 在多个测试文件中调用 Fixture, 我们需要 conftest.py 统一定义存储 Fixture

【例子3.2】新建 conftest.py 内容如下

复制代码
import pytest
@pytest.fixture
def input_value():
    input = 39
    return input
View Code
复制代码
复制代码
# content of file 'test_14'
def test_divisible_14(input_value):
    assert input_value%14 ==0 

# content of file 'test_15'
def test_divisible_15(input_value):
    assert input_value%15 ==0

# content of file 'test_16'
def test_divisible_16(input_value):
    assert input_value%16 ==0
View Code
复制代码

运行 pytest -k divisible -v 时,由于conftest.py 文件已声明 fixture, 所以input_value() 函数会自动加载到每次调用之前,测试正常进行

(五)Pytest指定测试,验证实际输出和期望输出是否一致 

Pytest 用 @pytest.mark.parametrize() 测试指定的<input, output>对

【例子4】添加@pytest.mark.parametrize()子句如下

复制代码
import pytest

@pytest.mark.parametrize("num,output",[(1,11),(2,22),(3,35),(4,44)])
def test_multiplication_11(num,output):
    assert 11*num == output
View Code
复制代码

 (六)Pytest 跳过某些测试/屏蔽某些测试错

@pytest.mark.skip 用来掉过某些测试
@pytest.mark.xfail  用来屏蔽某些测试的错误

【例子5】新建 test_op.py 文件,内容如下

复制代码
import pytest

@pytest.mark.xfail
@pytest.mark.great
def test_greater():
    num = 100
    assert num > 100

@pytest.mark.great
def test_greater_equal():
    num = 100
    assert num >= 200

@pytest.mark.skip
@pytest.mark.others
def test_divisible(input_value):
    assert input_value < 200
View Code
复制代码

运行 pytest test_op.py 运行结果如下,test_greater() 错误被屏蔽,test_greater_equal()正常报错,test_divisible()被测试跳过

 

(七)Pytest测试停止

cmd: pytest --maxfail = <num>

当检测出的错误个数等于num时,pytest 测试结束,不在对后面的代码进行测试

(八)Pytest 并行测试

pip install pytest-xdist  // 安装pytest 并行测试工具
pytest -n <num>        // runs in <num> workers

(九)Pytest 将测试结果记录到 xml 文件中

pytest -v --junitxml=<filename>

【例子6】 pytest -v --junitxml="result.xml"

 

参考(Reference)

[1] https://www.tutorialspoint.com/pytest/index.htm

posted on   猪伯  阅读(1629)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示