Skip to main content

KDTest Playwright Edition - 关键字驱动测试框架,专为 Element Plus/Vue3 优化

Project description

KDTest-Playwright

基于 Playwright 的关键字驱动测试框架,专为 Element Plus/Vue3 优化,兼容原版 kdtest 插件。

目录

安装

# 从 PyPI 安装
pip install kdtest-pw

# 安装 Playwright 浏览器
playwright install chromium

快速开始

1. 创建配置文件 parameters.json

{
    "testCaseFile": [
        {
            "caseFilePath": "testCases.xlsx",
            "caseItem": ["Sheet1"]
        }
    ],
    "browser": "chromium",
    "url": "http://localhost:8080",
    "headless": false,
    "timeout": 30000
}

2. 创建 Excel 测试用例

用例ID 用例名称 描述 关键字 定位方式 定位表达式 操作值
TC001 登录测试
打开网站 driver_get http://localhost
输入用户名 input_text xpath //input[@placeholder='账号'] admin
输入密码 input_text css input[type='password'] 123456
点击登录 click_btn css .el-button--primary
验证登录 text_assert css .user-name admin

3. 运行测试

# 命令行运行
kdtest-pw -c parameters.json

# 或在 Python 中使用
from kdtest_pw.cli import KDTestRunner

runner = KDTestRunner("parameters.json")
runner.setup()
runner.run()
runner.teardown()

配置文件

parameters.json 完整配置

{
    "testCaseFile": [
        {
            "caseFilePath": "testCases.xlsx",
            "caseItem": ["Sheet1", "Sheet2"]
        }
    ],
    "browser": "chromium",
    "url": "http://localhost:8080",
    "headless": false,
    "timeout": 30000,
    "slowMo": 0,
    "viewport": {
        "width": 1920,
        "height": 1080
    },
    "video": false,
    "screenshot": "only-on-failure",
    "trace": false,
    "reportDir": "./reports"
}

配置项说明

配置项 类型 默认值 说明
testCaseFile Array 必填 测试用例文件列表
browser String "chromium" 浏览器类型:chromium/firefox/webkit
url String - 初始 URL
headless Boolean false 无头模式
timeout Number 30000 全局超时时间(ms)
slowMo Number 0 操作延迟(ms),用于调试
viewport Object {1920, 1080} 视口大小
video Boolean false 是否录制视频
screenshot String "only-on-failure" 截图策略
trace Boolean false 是否启用 Trace
reportDir String "./reports" 报告输出目录

测试用例格式

Excel 列定义

列名 说明 示例
用例ID 测试用例唯一标识 TC001
用例名称 测试用例名称 登录测试
描述 步骤描述(可选) 输入用户名
关键字 要执行的关键字 input_text
定位方式 元素定位方式 xpath/css/id/name
定位表达式 元素定位表达式 //input[@id='username']
操作值 关键字参数 admin

定位方式

定位方式 说明 示例
xpath XPath 表达式 //div[@class='btn']
css CSS 选择器 div.btn, #submit
id 元素 ID username
name 元素 name 属性 password
text 文本内容 登录
role ARIA 角色 button

CLI 命令

运行测试

# 基本运行
kdtest-pw -c parameters.json

# 指定浏览器
kdtest-pw -c parameters.json --browser firefox

# 无头模式
kdtest-pw -c parameters.json --headless

# 慢速模式(调试用)
kdtest-pw -c parameters.json --slow-mo 500

插件管理

# 查看已安装插件
kdtest-pw --unit_show

# 创建新插件
kdtest-pw --unit_new MyPlugin

# 安装插件
kdtest-pw --unit_install /path/to/plugin

# 卸载插件
kdtest-pw --unit_uninstall MyPlugin

其他命令

# 查看帮助
kdtest-pw --help

# 查看版本
kdtest-pw --version

核心关键字

浏览器操作

关键字 说明 操作值
driver_get 打开 URL URL 地址
driver_back 后退 -
driver_forward 前进 -
driver_refresh 刷新页面 -
driver_close 关闭页面 -
driver_quit 退出浏览器 -

输入操作

关键字 说明 操作值
input_text 清除并输入文本 要输入的文本
input_append 追加输入文本 要追加的文本
input_clear 清除输入框 -
keyBoard_Events 键盘事件 Keys.ENTER, Keys.TAB 等

点击操作

关键字 说明 操作值
click_btn 点击元素 -
double_click 双击元素 -
right_click 右键点击 -
hover 鼠标悬停 -
force_click 强制点击(跳过可见性检查) -

等待操作

关键字 说明 操作值
sleep 固定等待 秒数
wait_visible 等待元素可见 超时时间(ms)
wait_hidden 等待元素隐藏 超时时间(ms)
wait_enabled 等待元素可用 超时时间(ms)

断言操作

关键字 说明 操作值
text_assert 断言元素文本 预期文本
text_contains_assert 断言文本包含 预期包含的文本
title_assert 断言页面标题 预期标题
url_assert 断言页面 URL 预期 URL
element_visible_assert 断言元素可见 true/false
element_count_assert 断言元素数量 预期数量
attribute_assert 断言元素属性 属性名=预期值

数据操作

关键字 说明 操作值
get_text 获取元素文本并存储 变量名
get_attribute 获取元素属性并存储 属性名,变量名
set_variable 设置变量 变量名=值
cache_data 缓存数据 键=值

Element Plus 组件

关键字 说明 操作值
el_select 下拉选择 选项文本
el_select_multiple 多选下拉 选项1,选项2
el_datepicker 日期选择 2024-01-01
el_daterange 日期范围 2024-01-01,2024-12-31
el_timepicker 时间选择 12:30:00
el_dialog_confirm 对话框确认 -
el_dialog_cancel 对话框取消 -
el_message_close 关闭消息提示 -
el_table_click_row 点击表格行 行索引(从0开始)
el_table_click_cell 点击表格单元格 行索引,列索引
el_table_get_cell 获取单元格文本 行索引,列索引,变量名
el_tree_click_node 点击树节点 节点文本
el_tree_expand 展开树节点 节点文本
el_cascader 级联选择 一级/二级/三级
el_upload 文件上传 文件路径
el_switch 开关切换 on/off
el_checkbox 复选框 check/uncheck
el_radio 单选框 选项文本
el_slider 滑块 数值
el_form_input 表单项输入 label=值
el_form_select 表单项选择 label=选项
el_pagination_goto 分页跳转 页码
el_tab_click 切换标签页 标签名

菜单导航

方式一:基于配置文件(适用于复杂系统)

关键字 说明 操作值
menu_load_data 加载菜单配置 modularInformation.json 路径
menu_navigate 导航到菜单 一级菜单/二级菜单/三级菜单
menu_click_first 点击一级菜单 菜单名称
menu_click_second 点击二级菜单 一级/二级
menu_click_third 点击三级菜单 一级/二级/三级
menu_switch_iframe 切换到 iframe 一级/二级
menu_exit_iframe 退出 iframe -

方式二:基于文本直接定位(适用于 Element Plus 标准菜单)

关键字 说明 操作值
el_menu_navigate 导航到菜单(无需配置) 一级菜单/二级菜单
el_menu_click 点击菜单项 菜单项文本
el_submenu_expand 展开子菜单 子菜单文本
el_submenu_collapse 收起子菜单 子菜单文本
el_tabs_click 点击标签页 标签页文本

示例:

# 方式一:使用配置文件
menu_load_data | | | ./menuConfig.json
menu_navigate | | | 系统管理/用户管理

# 方式二:直接文本定位(推荐用于 Element Plus)
el_menu_navigate | | | 系统管理/用户管理
el_tabs_click | | | 待处理

Frame 操作

关键字 说明 操作值
switch_to_frame 切换到 frame frame 名称/索引/定位表达式
switch_to_parent 切换到父 frame -
switch_to_main 切换到主文档 -

窗口操作

关键字 说明 操作值
switch_to_window 切换窗口 窗口标题或索引
new_tab 新建标签页 URL(可选)
close_tab 关闭当前标签页 -

JavaScript 执行

关键字 说明 操作值
execute_js 执行 JavaScript JS 代码
execute_js_on_element 在元素上执行 JS JS 代码

变量与内置函数

变量引用

${varName}           # 从缓存获取变量
${self.param}        # 从自定义参数获取
${env.NAME}          # 从环境变量获取
${case.field}        # 从当前用例数据获取

内置函数

函数 说明 示例
@today() 今天日期 2024-01-15
@today(+7) 7天后 2024-01-22
@today(-30) 30天前 2023-12-16
@now() 当前时间 2024-01-15 14:30:00
@now(%H:%M) 格式化时间 14:30
@timestamp() 时间戳 1705301400
@random(1,100) 随机整数 42
@random_str(8) 随机字符串 aB3kF9mN
@random_phone() 随机手机号 13812345678
@random_email() 随机邮箱 abc123@test.com
@random_name() 随机姓名 张三
@uuid() UUID 550e8400-e29b...
@uuid_short() 短 UUID 550e8400

使用示例

# 在操作值中使用变量
${username}

# 使用内置函数
@today()
@random(1000,9999)

# 组合使用
用户_@random(100,999)
test_@timestamp()@random_str(4)

插件系统

插件目录结构

kdtest-pw 支持两种插件格式:

1. kdtest-pw 原生格式

my_plugin/
├── __init__.py
├── plugin.py          # 继承 PluginBase
└── elements.yaml      # 元素数据(可选)

2. 原版 kdtest 格式(兼容)

MyPlugin/
├── __init__.py
├── my.ini             # [Information] NAME, DETAILE, STATE
├── MyPlugin.py        # 主模块,类名与 NAME 一致
├── elementData/
│   ├── elementData.yaml
│   └── modularInformation.json
└── utils/
    └── tool.py

创建插件

# 使用 CLI 创建
kdtest-pw --unit_new MyPlugin

生成的结构:

MyPlugin/
├── __init__.py
├── my.ini
├── MyPlugin.py
├── elementData/
│   ├── elementData.yaml
│   └── modularInformation.json
└── utils/
    └── tool.py

my.ini 配置

[Information]
NAME = MyPlugin
DETAILE = "插件描述"
STATE = finish
  • NAME: 插件名称(与主模块类名一致)
  • DETAILE: 插件描述
  • STATE: 状态(finish=启用, disabled=禁用)

插件主模块示例

# MyPlugin.py
class MyPlugin:
    """插件主类"""

    def __init__(self):
        self.page = None  # Playwright Page 将被自动注入

    def my_keyword(self, targeting, element, content=None):
        """自定义关键字

        Args:
            targeting: 定位方式
            element: 定位表达式
            content: 操作值
        """
        if self.page:
            locator = self.page.locator(f'{targeting}={element}')
            locator.click()
            if content:
                locator.fill(content)

    def another_keyword(self, content):
        """另一个关键字"""
        print(f"执行: {content}")
        return content

元素数据格式

# elementData/elementData.yaml
login:
  username:
    - xpath
    - //input[@id='username']
  password:
    - css
    - input[type='password']
  submit:
    - xpath
    - //button[@type='submit']

dashboard:
  menu:
    - css
    - .el-menu
  user_info:
    - id
    - userInfo

插件管理命令

# 查看已安装插件
kdtest-pw --unit_show

# 安装插件(从目录)
kdtest-pw --unit_install /path/to/MyPlugin

# 卸载插件
kdtest-pw --unit_uninstall MyPlugin

# 创建新插件模板
kdtest-pw --unit_new NewPlugin

与原版 kdtest 的兼容性

兼容的导入

原版 kdtest 插件中的以下导入会自动适配:

from kdtest import GSTORE, INFO, reset_implicitlyWait
from kdtest import GSDSTORE, MODULEDATA, PRIVATEDATA, CASESDATA

GSTORE 全局存储

# 获取当前 page
page = GSTORE.get('page')

# 获取关键字对象
keyword = GSTORE.get('keyWord')

# 存储/获取数据
GSTORE['myData'] = value
data = GSTORE.get('myData')

INFO 日志函数

INFO("普通信息")
INFO("警告信息", "WARNING")
INFO("错误信息", "ERROR")

reset_implicitlyWait 装饰器

# 作为装饰器
@reset_implicitlyWait(1)
def my_method(self):
    pass

# 作为函数
reset_implicitlyWait(10)

主要差异

特性 kdtest (Selenium) kdtest-pw (Playwright)
浏览器驱动 需要 WebDriver 内置浏览器
等待机制 显式/隐式等待 自动等待
driver 对象 self.driver self.page
元素定位 find_element() page.locator()
Element Plus 需要额外处理 原生支持
多标签页 需要切换句柄 原生支持
iframe switch_to.frame() frame_locator()
录制回放 支持 Trace
视频录制 原生支持

迁移指南

  1. driver → page

    # Selenium
    self.driver.find_element(By.XPATH, '//button').click()
    
    # Playwright
    self.page.locator('xpath=//button').click()
    
  2. 元素等待

    # Selenium
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located(...))
    
    # Playwright (自动等待,无需显式等待)
    self.page.locator('...').click()
    
  3. iframe 切换

    # Selenium
    driver.switch_to.frame('frameName')
    
    # Playwright
    frame = self.page.frame_locator('#frameName')
    frame.locator('button').click()
    

高级用法

自定义报告

from kdtest_pw.cli import KDTestRunner

runner = KDTestRunner("parameters.json")
runner.setup()
results = runner.run()

# 自定义报告处理
for case_result in results:
    print(f"用例: {case_result['name']}")
    print(f"状态: {case_result['status']}")
    print(f"耗时: {case_result['duration']}ms")

钩子函数

from kdtest_pw.cli import KDTestRunner

class MyRunner(KDTestRunner):
    def on_case_start(self, case_info):
        """用例开始前"""
        print(f"开始执行: {case_info['name']}")

    def on_case_end(self, case_info, result):
        """用例结束后"""
        if result['status'] == 'failed':
            self.page.screenshot(path=f"error_{case_info['id']}.png")

    def on_step_error(self, step_info, error):
        """步骤出错时"""
        print(f"步骤失败: {step_info['keyword']} - {error}")

并行执行

from kdtest_pw.cli import KDTestRunner
from concurrent.futures import ThreadPoolExecutor

def run_case_file(case_file):
    config = {
        "testCaseFile": [{"caseFilePath": case_file, "caseItem": ["Sheet1"]}],
        "browser": "chromium",
        "headless": True
    }
    runner = KDTestRunner(config)
    runner.setup()
    result = runner.run()
    runner.teardown()
    return result

# 并行执行多个用例文件
with ThreadPoolExecutor(max_workers=3) as executor:
    futures = [
        executor.submit(run_case_file, f"cases_{i}.xlsx")
        for i in range(3)
    ]
    results = [f.result() for f in futures]

Trace 调试

{
    "trace": true,
    "traceDir": "./traces"
}

运行后使用 Playwright Trace Viewer 查看:

playwright show-trace traces/trace.zip

视频录制

{
    "video": true,
    "videoDir": "./videos",
    "videoSize": {
        "width": 1280,
        "height": 720
    }
}

项目结构

kdtest_pw/
├── __init__.py
├── cli/
│   └── run.py              # CLI 入口和 KDTestRunner
├── compat/
│   └── kdtest_compat.py    # 原版 kdtest 兼容层
├── keywords/
│   ├── browser.py          # 浏览器操作关键字
│   ├── element.py          # 元素操作关键字
│   ├── assertion.py        # 断言关键字
│   └── element_plus.py     # Element Plus 关键字
├── plugins/
│   ├── plugin_base.py      # 插件基类
│   ├── plugin_loader.py    # 插件加载器
│   ├── legacy_adapter.py   # 原版插件适配器
│   ├── element_plus_plugin/# 内置 Element Plus 插件
│   └── OA_JavaWebUI/       # 用户插件示例
├── reference.py            # 全局引用(GSTORE, INFO 等)
└── utils/
    ├── excel_reader.py     # Excel 读取
    ├── variable_parser.py  # 变量解析
    └── report_generator.py # 报告生成

License

MIT

Project details


Download files

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

Source Distribution

kdtest_playwright-2.0.4.tar.gz (118.4 kB view details)

Uploaded Source

Built Distribution

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

kdtest_playwright-2.0.4-py3-none-any.whl (141.5 kB view details)

Uploaded Python 3

File details

Details for the file kdtest_playwright-2.0.4.tar.gz.

File metadata

  • Download URL: kdtest_playwright-2.0.4.tar.gz
  • Upload date:
  • Size: 118.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for kdtest_playwright-2.0.4.tar.gz
Algorithm Hash digest
SHA256 ea480b7f519ef4def17c241214fc2ff1834f0efa72c75341dff37e19c6edec4d
MD5 cbeb96696aa9d4ab9c94c68be279dca1
BLAKE2b-256 f4277fe0571d072cd858083fd94f4931ca064f82ad4e7618350b2c636be24d71

See more details on using hashes here.

File details

Details for the file kdtest_playwright-2.0.4-py3-none-any.whl.

File metadata

File hashes

Hashes for kdtest_playwright-2.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 97077a5231ad5886c9580b77f6bfff7874277e6286298327be0665351e5d48e3
MD5 775a9b210cb6f53f3e904b4ef2bb1126
BLAKE2b-256 c94e6f9dc413684677771e5dbddc370b5b41b0e188e6d9a5de42fc450da80077

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page