1. TPshop后台管理系统商品管理模块解析
TPshop作为国内主流的开源电商系统,其后台管理模块的商品管理功能是日常运营的核心操作入口。新增商品功能看似简单,实则涉及表单字段联动、分类树加载、图片上传、规格属性设置等多个技术难点,这正是UI自动化测试需要重点覆盖的场景。
商品新增页面通常包含以下关键元素:
- 基础信息区:商品名称、分类选择、品牌选择等必填字段
- 商品价格库存区:市场价、成本价、库存等数值型输入
- 商品详情区:富文本编辑器+多图上传组件
- 商品属性区:动态加载的规格属性复选框组
- 提交按钮组:保存、保存并继续等不同提交方式
提示:在实际测试中,富文本编辑器(如UEditor)和动态加载的分类树是最容易出问题的两个组件,需要特别关注它们的异步加载机制和DOM更新时机。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. UI自动化测试框架选型与搭建
2.1 主流UI测试工具对比
针对TPshop这类传统Web管理系统,我们对比了三种主流方案:
| 工具 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Selenium | 生态成熟、多语言支持 | 需要自行封装页面对象 | 复杂业务流程验证 |
| Cypress | 实时重载、调试方便 | 对iframe支持有限 | 前端主导的现代应用 |
| Playwright | 多浏览器支持、自动等待机制 | 社区资源相对较少 | 跨浏览器兼容性测试 |
基于TPshop的技术栈(jQuery+Bootstrap),我们选择Selenium+Python的组合,原因在于:
- 系统包含大量传统表单提交,需要精细的DOM操作控制
- 测试用例需要与后端数据库联动验证
- 团队已有Python技术积累
2.2 基础环境搭建
python复制# 环境准备(Python 3.8+)
pip install selenium webdriver-manager pytest
# 核心组件封装示例
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
class TPshopAdmin:
def __init__(self):
self.driver = webdriver.Chrome()
self.wait = WebDriverWait(self.driver, 10)
def select_category(self, path):
"""处理级联分类选择"""
for i, name in enumerate(path.split('>')):
locator = (By.XPATH, f"//ul[@class='category-tree']/li[{i+1}]/a[text()='{name}']")
self.wait.until(EC.element_to_be_clickable(locator)).click()
注意:TPshop的分类树采用动态加载,每次点击父分类后会通过AJAX请求子分类数据,必须添加显式等待。
3. 新增商品测试用例设计
3.1 正向用例关键步骤
-
登录验证:管理员cookie持久化处理
python复制def login(self, username, password): self.driver.get(ADMIN_URL) self.driver.add_cookie({'name': 'admin_token', 'value': get_preauth_token()}) -
表单填充策略:采用数据驱动模式
python复制@pytest.mark.parametrize('goods_data', test_data) def test_add_goods(self, goods_data): self.admin.goto_goods_add_page() self.admin.fill_basic_info(goods_data) self.admin.upload_images(goods_data['images']) ... -
富文本编辑器处理:通过JS直接操作iframe
python复制def fill_description(self, content): self.driver.switch_to.frame("ueditor_0") self.driver.execute_script(f"document.body.innerHTML='{content}'") self.driver.switch_to.default_content()
3.2 异常场景覆盖
针对TPshop的特殊逻辑,需要额外验证:
- 分类未选择时提交表单的提示方式
- 图片未上传时的前端校验逻辑
- 商品编号重复时的AJAX验证反馈
- 价格字段输入非数字时的处理机制
python复制def test_empty_category_submit():
"""测试未选择分类时的错误提示"""
page.submit_form()
alert = page.get_alert_message()
assert '请选择商品分类' in alert.text
4. 测试结果验证体系
4.1 前端验证点
- 成功提示框出现(XPath定位)
- 页面跳转到商品列表页
- 列表页第一条数据为新添加商品
4.2 后端数据库验证
通过封装ORM工具直接验证数据一致性:
python复制def verify_goods_in_db(goods_id, expected_data):
actual = Goods.query.get(goods_id)
assert actual.name == expected_data['name']
assert actual.category_path == expected_data['category']
assert len(actual.images) == len(expected_data['images'])
4.3 可视化日志增强
使用Allure报告展示关键操作截图:
python复制import allure
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
if call.when == 'call' and hasattr(item, 'admin'):
allure.attach(
item.admin.driver.get_screenshot_as_png(),
name='final_state',
attachment_type=allure.attachment_type.PNG
)
5. 实战中的典型问题解决方案
5.1 动态元素定位失效
TPshop的分类树采用动态ID,解决方案:
python复制def get_category_locator(self, name):
return (By.XPATH, f"//a[contains(@onclick,'loadCategory') and text()='{name}']")
5.2 文件上传处理
针对TPshop的多图上传组件:
python复制def upload_images(self, paths):
for path in paths:
input = self.driver.find_element(By.CSS_SELECTOR, "input[type='file']")
input.send_keys(os.path.abspath(path))
self.wait.until(lambda d: 'upload-success' in d.find_element(...).get_attribute('class'))
5.3 验证码绕过方案
在测试环境可配置关闭验证码:
python复制# 在TPshop的config/test_config.php中
$config['captcha_off'] = true;
6. 测试套件优化策略
6.1 页面对象模式改造
将重复操作抽象为Page Object:
python复制class GoodsAddPage:
def __init__(self, driver):
self.driver = driver
self.name_input = (By.ID, 'goods_name')
self.price_input = (By.NAME, 'shop_price')
def fill_price(self, value):
self.driver.find_element(*self.price_input).clear()
self.driver.find_element(*self.price_input).send_keys(str(value))
6.2 自动重试机制
对不稳定操作添加重试:
python复制@retry(stop_max_attempt_number=3)
def select_spec_item(self, spec_name, item_name):
self.driver.find_element_by_xpath(f"//label[contains(.,'{spec_name}')]/..//input[@value='{item_name}']").click()
6.3 并行测试配置
使用pytest-xdist实现并行:
ini复制# pytest.ini
[pytest]
addopts = -n auto
7. 持续集成实践
7.1 Jenkins流水线配置
groovy复制pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'python -m pytest tests/ --alluredir=./allure-results'
}
}
stage('Report') {
steps {
allure includeProperties: false, jdk: '', results: [[path: 'allure-results']]
}
}
}
}
7.2 测试数据管理
采用Faker生成测试数据:
python复制from faker import Faker
fake = Faker('zh_CN')
def generate_goods_data():
return {
'name': f"测试商品_{fake.word()}",
'price': fake.random_number(digits=3),
'category': '手机>智能手机'
}
8. 性能优化技巧
-
浏览器复用:通过remote模式连接已打开的浏览器实例
python复制options = webdriver.ChromeOptions() options.debugger_address = "127.0.0.1:9222" driver = webdriver.Chrome(options=options) -
请求拦截:使用DevTools Protocol屏蔽非必要资源
python复制driver.execute_cdp_cmd('Network.setBlockedURLs', {'urls': ['*.css', '*.png']}) -
DOM快照:在元素定位前先获取页面静态副本
python复制html = driver.execute_script("return document.documentElement.outerHTML")
经过完整的测试实践,我们发现TPshop的后台商品管理模块虽然界面传统,但通过合理的元素定位策略和等待机制,完全可以实现稳定的UI自动化测试。特别是在处理动态分类树和富文本编辑器时,需要特别注意DOM的实时状态检测。
