Skip to main content

pytest-testkit

pytest用例环境注册和日志记录插件

安装

仓库发行版中下载whl

wget https://gitcode.com/openlibing/openlibing-pytest-executor/releases/download/v1.0.0-alpha/pytest_testkit-1.0.0-py3-none-any.whl

安装

pip install --force-reinstall pytest_testkit-1.0.0-py3-none-any.whl

本地调试测试用例执行

安装完成后,pytest 会自动使用插件。

测试仓库下生成 testbed 模版:

pytest --collect-only --outtestbed=testbed.json

生成的 testbed.json 举例如下:

{
  "devices": [
    {
      "template_type": "multi_device_cover_single_type",
      "env_definition": [
        {
          "name": "device_1",
          "ip": "",
          "port": 22,
          "user": "",
          "pwd": ""
        },
        {
          "name": "device_2",
          "ip": "",
          "port": 22,
          "user": "",
          "pwd": ""
        }
      ]
    }
  ]
}

修改 testbed.json 中设备信息后,执行下面命令即可识别环境信息,执行测试用例:

pytest --testbed=testbed.json testcase/test_demo.py -k test_single_device_get_npu_info -s

在 pytest 中,你可以通过在命令行中使用 :: 符号来精确指定要执行的测试文件、测试类或单个测试方法,如: 文件名::类名::方法名 

执行后,可以在 根目录/logs/TestCases 下查看用例的html格式日志

💡 提示:如果想要调试 环境调度直接分配的是容器场景的话,可以在环境上拉起容器时设置映射的端口,这样本地调试就可以直接连接上容器,模拟直接 在容器内执行命令的场景, 映射的命令:

docker run -d --name <name> -p 2222:22 <image>:<tag>

logger 使用

导入 logger:

from pytest_testkit.lib.common.log import logger

使用 logger 记录日志:

logger.info(f"[Device._login] Successfully connected to device")

日志目录结构

执行测试后,日志文件会按以下结构组织:

logs/
└── TestCases/
    └── 2026-06-02/                    # 日期目录(YYYY-MM-DD)
        └── test_npu_info_11-38-05/     # 用例名_时间目录(HH-MM-SS)
            └── test_npu_info.html      # HTML 报告文件

目录结构说明

  • TestCases: 测试用例日志根目录
  • 日期目录: 按执行日期组织(格式:YYYY-MM-DD
  • 用例子目录: 按用例名和执行时间命名(格式:用例名_HH-MM-SS
  • HTML 文件: 插件生成的测试报告,文件名与用例名一致

通过 logger.path 属性可以获取当前用例的日志归档目录路径,方便在测试用例中创建自定义文件。

日志级别:

级别 方法 说明
TRACE 5 logger.trace() 跟踪信息(最小级别)
INFO 20 logger.info() 一般信息
TC_START 21 logger.tc_start() 测试用例开始
TC_STEP 22 logger.tc_step() 测试步骤记录
PRE_SET 23 logger.pre_set() 前置设置
POST_SET 24 logger.post_set() 后置设置
CMD 25 logger.cmd() 命令日志
CMD_RESPONSE 26 logger.cmd_response() 命令响应日志
TC_END 27 logger.tc_end() 测试用例结束
WARN 30 logger.warning() 警告信息
FAIL 35 logger.fail() 测试失败
ERROR 40 logger.error() 错误信息

logger的默认输出目录为logs,级别默认为INFO,如果需要配置:

1、在pytest.ini中配置(推荐做法)

infra_log_dir = logs
infra_log_level = INFO

2、在执行命令时指定

pytest --testbed=testbed.json --infra_log_level=INFO ./testcase/test_demo.py::TestDemoExecution::test_single_device

用例环境模板使用

基本用法

包含一个json文件和两个py文件

# resource/device_desc/template/single_device_template.json
{
  "template_type": "single_device",
  "env_definition": {
    "nodes_1": [
      {
        "name": "device",
        "pool": "default",
        "label": "server"
      }
    ]
  }
}
# resource/mapper.py
from typing import Dict
ENV_TEMPLATES: Dict[str, str] = {
    "single_device": "resource/device_desc/template/single_device_template.json",
}

# test_case.py
from resource.mapper import ENV_TEMPLATES
@pytest.mark.env(template=ENV_TEMPLATES["single_device"])
def test_custom_attrs():
    assert True

模板结构说明

device_template/
├── template_type          #模版类型,模本的唯一性标识,请保证不同模版间值唯一
├── env_definition         #环境定义列表
│   ├── nodes_1            #第一套设备组合,代表用例需要覆盖的一种硬件形态,多套设备组合代表用例要覆盖多种硬件形态,会执行多次
        ├── device1        #设备1,设备详情字段见下表
        ├── device2        #设备2
│   ├── nodes_2            #第二套设备组合,一套设备组合中的设备必须是同一种类型(都为容器或都为裸机)
        ├── device
│   ├── ...

容器类型device字段说明:

字段名 含义 示例
name 设备名称标识,必填 "device_1"
res_type 资源类型,标识为容器,必填 固定值:"container"
cpu_arch CPU架构类型,非必填,默认值:ARM 可选值:"ARM"、"X86"
cpu_core_num CPU核数,非必填,默认值:1 1
npu_gen NPU代际版本,非必填,不填则此项无要求 "A2"
npu_model NPU具体型号,非必填,不填则此项无要求 "Ascend 910B4"
npu_num NPU数量,非必填,不填则无NPU 1
memory_size 内存大小,单位GB,非必填,默认值2 2
storage_opt_size 容器存储大小,单位GB,默认值40 40
softwares 软件列表,非必填,name: 软件名称,version:软件版本,config: 安装配置 [{"name":"cann","version":"8.0.T16","config":""}]
image_label 容器镜像,如果使用日构建镜像,此处可不填,由CI透传 "cann8.5.0-py3.11-torch2.9.0-torch_npu2.9.0rc1"
command 容器启动命令,非必填 ["/bin/bash", "-c", "python app.py"]
mount_source_data 需要挂载的共享存储数据源,非必填 ["deepseek_v4_pro", "baai_taco"]
mount_dest_dir 共享存储挂载的目的路径,按照索引和数据源对应,非必填 ["/mnt/ascend/models/deepseek_v4_pro", "/mnt/ascend/dataset/baai_taco"]

说明:
1、软件安装:需要业务自己提前写好安装脚本,提供给HidevLab归档后,申请环境时才可以安装
2、共享存储挂载:数据需要提前在共享存储服务器维护,并在HidevLab配置数据和存储路径的映射关系

容器类型环境模板示例:

{
    "name": "device_1",
    "res_type": "container",
    "cpu_arch": "ARM",
    "cpu_core_num": 1,
    "npu_gen": "A2",
    "npu_model": "Ascend 910B4",
    "npu_num": 1,
    "memory_size": 32,
    "storage_opt_size": 40,
    "softwares": [
      {
        "name": "cann",
        "version": "8.0.T16",
        "config": ""
      }
    ],
    "image_label": "swr.cn-north-4.myhuaweicloud.com/hw-test-images/ubuntu-310-sshd:latest",
    "command": ["/bin/bash", "-c","python app.py"],
    "mount_source_data": ["deepseek_v4_pro", "baai_taco"],
    "mount_dest_dir": ["/mnt/ascend/models/deepseek_v4_pro", "/mnt/ascend/dataset/baai_taco"]
}

裸机类型device字段说明:

字段名 含义 示例
name 设备名称标识 "device_2"
res_type 资源类型,标识为物理机,必填 固定值:"bms"
device_model 物理服务器设备型号,非必填,不填则此项无要求 "TS200 2280H V2"
cpu_arch CPU架构类型,非必填,默认值:ARM 可选值:"ARM"、"X86"
cpu_core_min_num 最小CPU核心数量要求,非必填,不填则此项无要求 1
npu_gen NPU代际版本,非必填,不填则此项无要求 "A2"
npu_model NPU具体型号,非必填,不填则此项无要求 "Ascend 910B4"
npu_min_num 最小NPU数量要求,非必填,不填则此项无要求 1
memory_min_size 最小内存容量(GB),非必填,不填则此项无要求 16
storage_min_size 最小存储容量(GB),非必填,不填则此项无要求 300
softwares 软件列表,非必填,name: 软件名称,version:软件版本,config: 安装配置 [{"name":"cann","version":"8.0.T16","config":""}]
os_release 操作系统版本信息,非必填,不填则此项无要求 CentOS 7.6
mount_source_data 需要挂载的共享存储数据源,非必填 ["deepseek_v4_pro", "baai_taco"]
mount_dest_dir 共享存储挂载的目的路径,按照索引和数据源对应,非必填 ["/mnt/ascend/models/deepseek_v4_pro", "/mnt/ascend/dataset/baai_taco"]

说明:
1、软件安装:需要业务自己提前写好安装脚本,提供给HidevLab归档后,申请环境时才可以安装
2、共享存储挂载:数据需要提前在共享存储服务器维护,并在HidevLab配置数据和存储路径的映射关系

裸机类型环境模板示例:

{
    "name": "device_1",
    "res_type": "bms",
    "device_model": "TS200 2280H V2",
    "cpu_arch": "ARM",
    "cpu_core_min_num": 1,
    "npu_gen": "A2",
    "npu_model": "Ascend 910B4",
    "npu_min_num": 1,
    "memory_min_size": 16,
    "storage_min_size": 300,
    "softwares": [
      {
        "name": "cann",
        "version": "8.0.T16",
        "config": ""
      }
    ],
    "os_release": "CentOS 7.6",
    "mount_source_data": ["deepseek_v4_pro", "baai_taco"],
    "mount_dest_dir": ["/mnt/ascend/models/deepseek_v4_pro", "/mnt/ascend/dataset/baai_taco"]
}

case_info 标记使用

pytest-testkit 插件支持通过 case_info 标记为测试用例添加自定义属性,用于用例分类和筛选。

基本用法

# 支持任意自定义属性
@pytest.mark.case_info(
    level="P1", type="Performance", owner="team1", module="auth", tags="perf"
)
def test_custom_attrs():
    assert True

用例筛选

在 pytest.ini 中配置筛选条件,只运行匹配的用例:

[pytest]

# 筛选 level=P1 且 module=auth 的用例
[case_info]
level = P1
module = auth

筛选逻辑说明

  • 精确匹配:ini 中配置的属性必须与用例属性精确匹配
  • 通配:ini 中未配置的属性不参与筛选(匹配所有)

示例

# 只筛选 level=P1 的用例
[case_info]
level = P1
# 筛选 level=P1 且 owner=team1 的用例
[case_info]
level = P1
owner = team1

error_log_fail 功能

pytest-testkit 插件支持当测试执行过程中出现 ERROR/WARN/FAIL 等级别日志时自动标记测试失败。

支持CLI 参数 和 ini 配置,默认为禁用

使用方式:

1、命令行参数(推荐用于临时启用)

pytest --error-log-fail --testbed=testbed.json testcase/

2、pytest.ini 配置(推荐用于项目级永久配置)

[pytest]
error_log_fail = true

使用示例:

# 开启error_log_fail功能后 用例结果为fail
def test_environment(logger):
    logger.error("this is a error log")
    assert True

quiet_stdout 功能

pytest-testkit 插件支持全局静默 sendcmd / sendcmd_interactive 的 stdout 输出,避免大量回显淹没日志。 开启后,stdout 内容不会出现在日志中,即使调用方显式传 echo_output=True 也会被全局压制。 exit_code、prompt、stderr 等信息不受影响。

支持CLI 参数 和 ini 配置,默认为禁用

使用方式:

1、命令行参数(推荐用于临时启用)

pytest --quiet-stdout --testbed=testbed.json testcase/

2、pytest.ini 配置(推荐用于项目级永久配置)

[pytest]
quiet_stdout = true

支持的 fixture

  • logger: 提供日志对象

    • info, warning, error等方法: 记录不同级别的日志
      • msg: 日志消息字符串

    日志记录示例:

    def test_environment(logger):
        logger.info("this is a info log")
        logger.warning("this is a waring log")
        logger.error("this is a error log")
    
    • set_header, set_footer: 设置 HTML 报告头部和尾部内容
      • html_content: 要注入的 HTML 内容
      • append: 是否追加到现有内容之后,默认覆盖

    HTML 内容注入示例:

    def test_example(logger):
        # 设置 HTML 报告头部内容(注入位置:统计信息头之后、详细信息表格之前)
        logger.set_header('<span class="custom-header">算子测试结果</span>')
    
        # 设置 HTML 报告尾部内容(注入位置:详细信息表格之后)
        logger.set_footer('<span class="custom-footer">测试完成</span>')
    
        # 多次注入内容默认覆盖,可通过 append=True 追加内容
        logger.set_header("<span>第一部分</span>", append=True)
        logger.set_header("<span>第二部分</span>", append=True)  # 结果:第一部分 + 第二部分
    
    • path: 获取当前用例的日志归档目录路径(只读属性)
      • 返回值: 当前用例的日志归档目录路径字符串,若未进入用例则返回 None

    获取日志目录路径示例:

    def test_example(logger):
        # 获取当前用例的日志归档目录路径
        log_dir = logger.path
        if log_dir:
            print(f"当前用例日志目录: {log_dir}")
            # 可以在此目录下创建自定义文件
            custom_file = os.path.join(log_dir, "custom_report.txt")
            with open(custom_file, "w") as f:
                f.write("自定义报告内容")
    
  • environment/environments: 提供单设备/多设备对象

    • sendcmd(cmd, timeout=None, env_vars=None, cwd=None, ignore_err=False, only_stdout=True):执行命令(非交互式)

      • cmd: 要执行的命令字符串
      • timeout: 命令执行超时时间(秒)
      • env_vars: 环境变量字典
      • cwd: 工作目录,命令将在该目录下执行(可选)
      • ignore_err: 是否忽略命令执行错误,默认 False。设为 True 时即使命令失败 success 也为 True
      • only_stdout: 为 True 时只返回 stdout 字符串,为 False 时返回完整字典
      • 返回值: 默认返回 stdout 字符串;当 only_stdout=False 时返回 {'success': bool, 'stdout': str, 'stderr': str}
    • sendcmd_interactive(cmd, expect_prompt=None, timeout=600, cwd=None, ignore_err=False, only_stdout=True):执行命令(交互式)

      • cmd: 要执行的命令字符串
      • expect_prompt: 期望匹配的提示符正则表达式(可选)
      • timeout: 命令执行超时时间(秒)。默认值600s
      • cwd: 工作目录,命令将在该目录下执行(可选)
      • ignore_err: 是否忽略提示符匹配失败,默认 False。设为 True 时即使未匹配到提示符 success 也为 True
      • only_stdout: 为 True 时只返回 stdout 字符串,为 False 时返回完整字典
      • 返回值: 默认返回 stdout 字符串;当 only_stdout=False 时返回 {'success': bool, 'stdout': str, 'stderr': str}
      • 输出清理: 返回的 stdout 会自动清理以下内容,便于用户直接使用:
        • CSI 控制序列(如 \x1b[32m 颜色代码、\x1b[?2004h bracketed paste mode 等)
        • OSC 控制序列(如 \x1b]0;title\x07 窗口标题设置等)
        • 命令回显及其之前的内容(包括 Login Banner)
        • 回车换行符统一转换为 \n\r\n\r 自动处理)
    • upload_file(local_file, remote_file):上传文件

      • local_file: 本地文件路径
      • remote_file: 远程文件路径
      • 返回值: 上传成功返回True,失败返回False
    • download_file(remote_file, local_file):下载文件

      • remote_file: 远程文件路径
      • local_file: 本地文件路径
      • 返回值: 下载成功返回True,失败返回False
    • reconnect():设备重连

      • 返回值: 重连成功返回True,失败返回False

    设备参数使用方法示例如下:

    # 单设备
    def test_environment(environment):
        my_env_dict = {"MY_VAR": "value"}
        output = environment.sendcmd("ls", timeout=5, env_vars=my_env_dict)
        print(output)  # 直接打印stdout字符串
    
        # 需要获取完整结果时
        result = environment.sendcmd("ls", only_stdout=False)
        assert result["success"]
        print(result["stdout"])
    
        # 在指定目录执行命令
        output = environment.sendcmd("pwd", cwd="/tmp")
    
        # 忽略命令执行错误并获取完整结果
        result = environment.sendcmd("some_command", ignore_err=True, only_stdout=False)
        # result['success'] 总是 True
    
        environment.upload_file("local.txt", "/remote/path/remote.txt")
        environment.download_file("/remote/path/remote.txt", "local.txt")
    
    
    # 多设备 device1_name为模板中name 其他用法与单设备相同 参考单设备示例
    def test_environments(environments):
        environment_device1 = environments["device1_name"]
        output = environment_device1.sendcmd("ls")
        # 需要检查执行结果时
        result = environment_device1.sendcmd("ls", only_stdout=False)
        if not result["success"]:
            print(f"Error: {result['stderr']}")
    
  • set_docker(docker_name_or_id):注册 Docker 容器(名称或 ID)

    • docker_name_or_id: 容器名称或容器 ID(Docker ID 为小写十六进制字符串)
    • 返回值: None
    • 功能: 注册设备上的 Docker 容器,注册后可通过 __getitem__ 获取容器代理对象
    • 查询顺序: 先尝试按 ID 查询,若找不到再尝试按名称精确查询
  • DockerProxy 容器代理对象:通过 environment["container_name"] 获取

    • 代理对象提供与 Device 一致的接口,自动包装 docker exec 命令

    • sendcmd(cmd, timeout=None, ignore_err=False, only_stdout=True):非交互式命令

      • 每次独立执行 docker exec {docker_name} {cmd}
      • 返回值: stdout 字符串或完整字典
    • sendcmd_interactive(cmd, expect_prompt=None, timeout=600, cwd=None, ignore_err=False, only_stdout=True):交互式命令

      • 持久 session 模式:首次调用进入容器,后续调用在同一 session 执行
      • 只有交互式 shell 命令(bash/sh/python/mysql 等)才创建持久 session
      • 非交互式命令(cat/ls/grep 等)执行后自动退出,不设置 session 状态
      • 参数与 Device.sendcmd_interactive 相同
      • 返回值: stdout 字符串或完整字典
    • exit_docker(expect_prompt=None, timeout=3):退出容器 session

      • 执行 exit 命令退出容器,回到主机 shell
      • 若未进入 session 状态,打印 warning 日志并返回空字符串

    Docker 容器代理使用示例:

    # 单设备场景
    def test_with_docker(environment):
        # 在裸机上拉起容器
        environment.sendcmd("docker run -d --name my_container ubuntu:latest sleep 3600")
    
        # 注册容器
        environment.set_docker("my_container")
    
        # 获取容器代理对象
        container = environment["my_container"]
    
        # 非交互式命令(每次独立执行)
        output = container.sendcmd("ls /")
        assert "bin" in output
    
        # 进入容器交互式 session
        # 必须使用/bin/bash 、/bin/sh 等交互式 shell 命令才能进入交互式 session
        container.sendcmd_interactive("/bin/bash")
    
        # 在同一 session 中执行多条命令
        container.sendcmd_interactive("ls -la")
        container.sendcmd_interactive("cat /etc/hosts")
    
        # 退出容器交互式 session 非交互式无需调用
        container.exit_docker()
    
        # environment.sendcmd 仍执行裸机命令
        environment.sendcmd("docker ps")
    
    
    # 多设备场景
    def test_multi_device_with_docker(environments):
        dev1 = environments["device1"]
    
        # 在 device1 上拉起容器
        dev1.sendcmd("docker run -d --name app_container nginx:latest")
    
        # 注册容器
        dev1.set_docker("app_container")
    
        # 获取容器代理对象(两级字典取值)
        container = dev1["app_container"]
        output = container.sendcmd("nginx -v")
    
        # 非 shell 命令不会创建交互式 session
        container.sendcmd_interactive("cat /root/abc.txt")
        container.exit_docker()  # 打印 warning,不执行 exit
    
    
    # 通过容器 ID 注册(适合容器无名称的情况)
    def test_with_docker_by_id(environment):
        # 在裸机上拉起容器(不指定名称)
        environment.sendcmd("docker run -d ubuntu:latest sleep 3600")
    
        # 获取容器 ID
        output = environment.sendcmd("docker ps -q --filter ancestor=ubuntu:latest")
        container_id = output.strip()  # 例如 "a1b2c3d4e5f67890..."
    
        # 注册容器(通过 ID,支持短 ID 或完整 ID)
        # Docker ID 为小写十六进制字符串(至少需要能唯一标识容器)
        environment.set_docker(container_id[:12])  # 使用短 ID(12 位)
        # 或使用完整 ID: environment.set_docker(container_id)
    
        # 获取容器代理对象
        container = environment[container_id[:12]]
    
        # 执行命令
        output = container.sendcmd("ls /")
        assert "bin" in output
    
        # 清理容器
        environment.sendcmd(f"docker stop {container_id}")
        environment.sendcmd(f"docker rm {container_id}")
    

    注意

    • 交互式 shell 命令集合:bash、sh、ash、dash、zsh、python、python3、mysql、psql 等
    • 非交互式命令(cat/ls/grep 等)使用 sendcmd_interactive 后执行完毕自动退出容器,不会设置 session 状态
    • 进入交互式shell后需调用 exit_docker() 退出容器 session,非交互式无需调用
    • set_docker 支持容器名称和容器 ID,查询顺序:先尝试 ID 查询,失败后再尝试名称精确查询

前置动作注册

支持在测试执行前注册并执行前置动作,用于环境变量加载、参数注入、设备初始化等场景。

核心特性:

  • conftest.pypytest_runtest_setup 中通过 register_pre_action 注册前置动作
  • pytest_runtest_setup在每个用例执行前都会被调用
  • 前置动作在环境分配后、每个测试用例执行前自动执行
  • 执行失败时用例直接报错,报错信息包含失败动作名称和详细错误

使用方式:

conftest.py 中定义并注册前置动作:

import pytest
from pytest_testkit import (
    register_pre_action,
    clear_pre_action_registry
)

def load_env_var(environments):
    """在远程设备上设置环境变量"""
    device = list(environments.values())[0]
    result = device.sendcmd_interactive("export TEST_MODE=MY_ENV", timeout=5)
    return "set succ"

def wait_seconds(delay):
    """本地等待(第一个参数不是 environments,不注入设备)"""
    import time
    time.sleep(delay)
    return {"waited": delay}

@pytest.hookimpl(hookwrapper=True)  # 装饰器必选
def pytest_runtest_setup(item):
    # 可选  执行前置动作前清空历史注册的前置动作
    clear_pre_action_registry()
    # load_env_var函数第一个参数是 environments,注入设备字典
    register_pre_action(
        name="load_env_var",
        func=load_env_var,
    )
    # wait_seconds函数第一个参数不是 environments,不注入设备字典
    register_pre_action(
        name="wait_seconds",
        func=wait_seconds,
        args=[2]
    )
    # 必选  需放在register_pre_action后,可理解为调用插件的pytest_runtest_setup函数,执行前置动作
    yield

多个conftest.py调用顺序:

假设有两组用例分别在TestRepo/testsTestRepo/unittest下, conftest.py可选位置及pytest_runtest_setup的调用顺序举例如下

# 目录结构
TestRepo
├── conftest.py
├── tests/
│   └── conftest.py
└── unittest/
    └── conftest.py

# 以tests/下用例某个用例为例,
# pytest_runtest_setup先调用用例同级的conftest.py文件,再调用父级目录下的
TestRepo/tests/conftest.py
          ↓
TestRepo/conftest.py

register_pre_action 接口参数说明:

参数 类型 说明
name str 前置动作唯一标识
func Callable 执行函数
args list 传递给 func 的位置参数
kwargs dict 传递给 func 的关键字参数
forced bool 是否强制执行。默认为 False,相同name的前置动作在整个 session 中只执行一次;设置为 True 时,即使已执行过也会在每个测试用例前重新执行

函数签名规则:

系统通过检测函数第一个参数名判断是否注入 environments

  1. 第一个参数是 environments:系统自动注入设备字典,可使用environment提供的方法操作环境,如sendcmd
def my_action(environments, **kwargs):
    for name, device in environments.items():
        device.sendcmd("hostname")

register_pre_action(name="my_action", func=my_action)
  1. 第一个参数不是 environments:不注入设备字典
def local_action(delay, message):
    import time
    time.sleep(delay)
    print(message)
    return {"done": True}

register_pre_action(name="local_action", func=local_action, args=[1, "hello"])

错误处理:

  • Registry 未初始化:抛出 RegistryNotInitializedError
  • 执行失败:抛出 PreActionError,测试用例报错终止

执行测试

基本命令

# 指定 testbed 文件执行测试
pytest --testbed=./testbed.json testcase/

# 指定测试目录
pytest --testbed=./testbed.json tests/

# 运行指定测试
pytest --testbed=./testbed.json testcase/test_demo.py::TestDemoExecution::test_single_device

# 过滤测试用例(按 level 和 type)
pytest --testbed=./testbed.json testcase/ -v

# 生成 testbed 模板
pytest --collect-only --outtestbed=testbed.json

pytest.ini 配置

[pytest]
# 日志配置:目录、级别
infra_log_dir = logs
infra_log_level = INFO

# 错误日志失败配置:当检测到 ERROR/WARN/FAIL 日志时标记测试失败
error_log_fail = true

# 指定测试文件搜索路径(可提升收集速度,避免扫描无关目录)
testpaths = tests/demo

# 默认命令行选项(每次运行 pytest 时自动应用)
addopts =
    -v                          # 详细输出
    --tb=short                  # 精简 traceback
    -m smoke                    # 按自定义mark过滤

# 注册自定义 markers(避免使用未声明的 marker 产生警告)
markers =
    smoke: 标记冒烟测试用例
    ui: UI 自动化测试
    api: 接口测试

# 忽略某些文件或目录(可选)
; ignore =
;     tests/old/
;     tests/conftest_legacy.py

# 指定 Python 文件匹配模式
python_files = test_*.py

# 指定测试类和函数的命名规则
python_classes = Test*
python_functions = test_*

# 自定义用例筛选条件,对应用例的自定义mark中的case_info信息
[case_info]
level = P0
type = Functional

# 用例id列表筛选条件,使用用例函数名筛选,多个用例函数名使用英文逗号隔开不要带空格
[test_ids]
include = id1,id2
exclude = id3,id4

Dependencies

见requirements.txt

License

MIT License

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_testkit-1.0.0.tar.gz (94.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_testkit-1.0.0-py3-none-any.whl (71.2 kB view details)

Uploaded Python 3

File details

Details for the file pytest_testkit-1.0.0.tar.gz.

File metadata

  • Download URL: pytest_testkit-1.0.0.tar.gz
  • Upload date:
  • Size: 94.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.12

File hashes

Hashes for pytest_testkit-1.0.0.tar.gz
Algorithm Hash digest
SHA256 34bdc52e813664398b7b3fda3ac3ab6b07229e7f20f96081cd13f9fc817afc65
MD5 65aaf53e3b2812f1d0d94144994ad32d
BLAKE2b-256 d681fbad3002c3bee6ca7f39255e6634a48ffc68a1aae81050d8869a603ca08f

See more details on using hashes here.

File details

Details for the file pytest_testkit-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pytest_testkit-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 71.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.12

File hashes

Hashes for pytest_testkit-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dd079cc8d74a77d67feff03301334d54310885f2997dc3004674bf16bcd5b931
MD5 a0a150c9a4d884425166d49c94361fb3
BLAKE2b-256 44520789b31d9b2c3ab380a5f9f0f389cdd47c2981e168903812ddb0e36de6db

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page