ERPNext系统Web自动化测试¶
1. Web自动化测试概述¶
1.1 测试目标¶
验证ERPNext系统的Web界面功能,确保用户界面操作的正确性、稳定性和用户体验质量。
1.2 测试范围¶
- 客户管理界面测试
- 销售订单界面测试
- 采购订单界面测试
- 库存管理界面测试
- 财务管理界面测试
- 权限管理界面测试
- 报表界面测试
1.3 技术栈¶
- 测试框架:Selenium WebDriver + Python
- 页面对象模型:Page Object Pattern
- 测试报告:Allure
- 持续集成:Jenkins
2. 测试环境配置¶
2.1 环境要求¶
- Python 3.8+
- Chrome浏览器
- ChromeDriver
- Selenium WebDriver
2.2 项目结构¶
ERPNextWebTest/
├── pages/ # 页面对象
├── tests/ # 测试用例
├── utils/ # 工具类
├── config/ # 配置文件
├── reports/ # 测试报告
└── requirements.txt # 依赖包
3. 页面对象设计¶
3.1 登录页面¶
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.username_input = "//input[@name='login']"
self.password_input = "//input[@name='password']"
self.login_button = "//button[@type='submit']"
self.error_message = "//div[@class='alert alert-danger']"
def login(self, username, password):
"""执行登录操作"""
self.driver.find_element(By.XPATH, self.username_input).send_keys(username)
self.driver.find_element(By.XPATH, self.password_input).send_keys(password)
self.driver.find_element(By.XPATH, self.login_button).click()
def get_error_message(self):
"""获取错误信息"""
return self.driver.find_element(By.XPATH, self.error_message).text
3.2 客户管理页面¶
class CustomerPage:
def __init__(self, driver):
self.driver = driver
self.add_customer_btn = "//button[contains(text(),'新增客户')]"
self.customer_name_input = "//input[@data-fieldname='customer_name']"
self.customer_type_select = "//select[@data-fieldname='customer_type']"
self.save_button = "//button[contains(text(),'保存')]"
self.customer_list = "//div[@class='list-row']"
def add_customer(self, name, customer_type):
"""添加新客户"""
self.driver.find_element(By.XPATH, self.add_customer_btn).click()
self.driver.find_element(By.XPATH, self.customer_name_input).send_keys(name)
self.driver.find_element(By.XPATH, self.customer_type_select).send_keys(customer_type)
self.driver.find_element(By.XPATH, self.save_button).click()
def search_customer(self, name):
"""搜索客户"""
search_input = "//input[@placeholder='搜索客户']"
self.driver.find_element(By.XPATH, search_input).send_keys(name)
self.driver.find_element(By.XPATH, search_input).send_keys(Keys.ENTER)
3.3 销售订单页面¶
class SalesOrderPage:
def __init__(self, driver):
self.driver = driver
self.new_order_btn = "//button[contains(text(),'新建销售订单')]"
self.customer_select = "//input[@data-fieldname='customer']"
self.item_table = "//div[@class='grid-row']"
self.add_item_btn = "//button[contains(text(),'添加项目')]"
self.submit_button = "//button[contains(text(),'提交')]"
def create_sales_order(self, customer, items):
"""创建销售订单"""
self.driver.find_element(By.XPATH, self.new_order_btn).click()
self.driver.find_element(By.XPATH, self.customer_select).send_keys(customer)
for item in items:
self.driver.find_element(By.XPATH, self.add_item_btn).click()
# 添加商品信息
self.driver.find_element(By.XPATH, self.submit_button).click()
4. 测试用例设计¶
4.1 登录功能测试¶
class TestLogin:
def test_valid_login(self):
"""测试有效用户登录"""
login_page = LoginPage(self.driver)
login_page.login("test@example.com", "password123")
assert "仪表板" in self.driver.page_source
def test_invalid_login(self):
"""测试无效用户登录"""
login_page = LoginPage(self.driver)
login_page.login("invalid@example.com", "wrongpassword")
assert "用户名或密码错误" in login_page.get_error_message()
4.2 客户管理测试¶
class TestCustomerManagement:
def test_add_customer(self):
"""测试添加客户"""
customer_page = CustomerPage(self.driver)
customer_page.add_customer("测试客户", "个人")
assert "测试客户" in self.driver.page_source
def test_search_customer(self):
"""测试搜索客户"""
customer_page = CustomerPage(self.driver)
customer_page.search_customer("测试客户")
assert len(customer_page.get_customer_list()) > 0
4.3 销售订单测试¶
class TestSalesOrder:
def test_create_sales_order(self):
"""测试创建销售订单"""
sales_order_page = SalesOrderPage(self.driver)
items = [{"name": "商品A", "qty": 2, "price": 100}]
sales_order_page.create_sales_order("测试客户", items)
assert "销售订单已创建" in self.driver.page_source
5. 测试数据管理¶
5.1 测试数据文件¶
{
"test_users": [
{
"username": "admin@example.com",
"password": "admin123",
"role": "管理员"
},
{
"username": "sales@example.com",
"password": "sales123",
"role": "销售员"
}
],
"test_customers": [
{
"name": "测试客户A",
"type": "个人",
"email": "customerA@example.com"
},
{
"name": "测试客户B",
"type": "企业",
"email": "customerB@example.com"
}
]
}
5.2 数据管理工具类¶
class DataManager:
def __init__(self):
self.test_data = self.load_test_data()
def load_test_data(self):
"""加载测试数据"""
with open('test_data.json', 'r', encoding='utf-8') as f:
return json.load(f)
def get_test_user(self, role):
"""获取测试用户"""
for user in self.test_data['test_users']:
if user['role'] == role:
return user
return None
def get_test_customer(self, name):
"""获取测试客户"""
for customer in self.test_data['test_customers']:
if customer['name'] == name:
return customer
return None
6. 测试执行和报告¶
6.1 测试执行脚本¶
import pytest
from selenium import webdriver
from pages.login_page import LoginPage
from utils.data_manager import DataManager
class TestExecution:
def setup_method(self):
"""测试前置条件"""
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.data_manager = DataManager()
def teardown_method(self):
"""测试后置条件"""
self.driver.quit()
def test_complete_workflow(self):
"""测试完整业务流程"""
# 登录
login_page = LoginPage(self.driver)
user = self.data_manager.get_test_user("销售员")
login_page.login(user['username'], user['password'])
# 添加客户
customer_page = CustomerPage(self.driver)
customer = self.data_manager.get_test_customer("测试客户A")
customer_page.add_customer(customer['name'], customer['type'])
# 创建销售订单
sales_order_page = SalesOrderPage(self.driver)
items = [{"name": "商品A", "qty": 1, "price": 100}]
sales_order_page.create_sales_order(customer['name'], items)
# 验证结果
assert "订单创建成功" in self.driver.page_source
6.2 Allure报告配置¶
import allure
@allure.feature("ERPNext系统测试")
@allure.story("客户管理")
class TestCustomerManagement:
@allure.title("添加新客户")
@allure.description("测试添加新客户功能")
def test_add_customer(self):
with allure.step("打开客户管理页面"):
customer_page = CustomerPage(self.driver)
with allure.step("填写客户信息"):
customer_page.add_customer("测试客户", "个人")
with allure.step("验证客户添加成功"):
assert "测试客户" in self.driver.page_source
7. 持续集成配置¶
7.1 Jenkins Pipeline¶
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: 'main', url: 'https://github.com/example/erpnext-web-test.git'
}
}
stage('Setup Environment') {
steps {
sh 'pip install -r requirements.txt'
sh 'python -m pytest --version'
}
}
stage('Run Tests') {
steps {
sh 'python -m pytest tests/ --allure-results-dir=allure-results'
}
}
stage('Generate Report') {
steps {
allure includeProperties: false, jdk: '', results: [[path: 'allure-results']]
}
}
}
post {
always {
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'allure-results',
reportFiles: 'index.html',
reportName: 'Allure Report'
])
}
}
}
8. 最佳实践¶
8.1 页面对象模式¶
- 每个页面创建独立的页面对象类
- 使用显式等待替代隐式等待
- 封装常用的页面操作方法
8.2 测试数据管理¶
- 使用外部文件管理测试数据
- 支持多环境数据配置
- 实现数据清理和恢复机制
8.3 异常处理¶
- 添加截图功能用于失败分析
- 实现重试机制处理不稳定元素
- 记录详细的测试日志
8.4 性能优化¶
- 使用无头浏览器进行快速测试
- 并行执行测试用例
- 优化测试数据准备时间
9. 故障排除¶
9.1 常见问题¶
- 元素定位失败:检查页面结构变化,更新定位器
- 测试不稳定:增加等待时间,使用显式等待
- 数据冲突:实现测试数据隔离和清理
9.2 调试技巧¶
- 使用浏览器开发者工具分析页面结构
- 添加详细的日志输出
- 使用截图功能记录测试状态
10. 总结¶
ERPNext系统Web自动化测试框架提供了完整的测试解决方案,包括页面对象设计、测试用例管理、数据管理、报告生成等功能。通过持续集成和最佳实践,确保测试的稳定性和可维护性。