08ea5fbe98
添加用户管理视图、API和状态管理文件
361 lines
10 KiB
Python
361 lines
10 KiB
Python
"""
|
|
全局测试夹具
|
|
|
|
提供pytest全局夹具和钩子函数。
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import pytest
|
|
from pathlib import Path
|
|
from typing import Generator
|
|
|
|
# 添加项目根目录到Python路径
|
|
project_root = Path(__file__).parent
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
from playwright.sync_api import Page, Browser, BrowserContext
|
|
from core.config_manager import config_manager
|
|
from core.logger import get_logger
|
|
from core.reporter import TestReporter, TestResult
|
|
from pages.web import LoginPage, DashboardPage, UserManagementPage, RoleManagementPage, MenuManagementPage
|
|
from pages.uniapp import AlmanacPage, CalendarPage, UserPage
|
|
|
|
|
|
# 配置管理器
|
|
@pytest.fixture(scope="session")
|
|
def test_config():
|
|
"""测试配置夹具"""
|
|
return config_manager.get_config()
|
|
|
|
|
|
# 日志记录器
|
|
@pytest.fixture(scope="session")
|
|
def logger():
|
|
"""日志记录器夹具"""
|
|
return get_logger()
|
|
|
|
|
|
# 测试报告
|
|
@pytest.fixture(scope="session")
|
|
def test_reporter():
|
|
"""测试报告夹具"""
|
|
reporter = TestReporter()
|
|
reporter.start_report()
|
|
yield reporter
|
|
reporter.end_report()
|
|
reporter.generate_all_reports()
|
|
|
|
|
|
# Admin端页面对象
|
|
@pytest.fixture
|
|
def login_page(page: Page, test_config):
|
|
"""登录页面对象"""
|
|
return LoginPage(page, test_config.base_url)
|
|
|
|
|
|
@pytest.fixture
|
|
def dashboard_page(page: Page, test_config):
|
|
"""仪表盘页面对象"""
|
|
return DashboardPage(page, test_config.base_url)
|
|
|
|
|
|
@pytest.fixture
|
|
def user_management_page(page: Page, test_config):
|
|
"""用户管理页面对象"""
|
|
return UserManagementPage(page, test_config.base_url)
|
|
|
|
|
|
@pytest.fixture
|
|
def role_management_page(page: Page, test_config):
|
|
"""角色管理页面对象"""
|
|
return RoleManagementPage(page, test_config.base_url)
|
|
|
|
|
|
@pytest.fixture
|
|
def menu_management_page(page: Page, test_config):
|
|
"""菜单管理页面对象"""
|
|
return MenuManagementPage(page, test_config.base_url)
|
|
|
|
|
|
# Uniapp端页面对象
|
|
@pytest.fixture
|
|
def almanac_page(page: Page, test_config):
|
|
"""黄历页面对象"""
|
|
# 使用uniapp的base_url
|
|
import yaml
|
|
from pathlib import Path
|
|
config_path = Path(__file__).parent / "config" / "config.yaml"
|
|
with open(config_path, "r", encoding="utf-8") as f:
|
|
data = yaml.safe_load(f)
|
|
env = os.getenv("TEST_ENV", "dev")
|
|
uniapp_base_url = data["environments"][env]["uniapp"]["base_url"]
|
|
return AlmanacPage(page, uniapp_base_url)
|
|
|
|
|
|
@pytest.fixture
|
|
def calendar_page(page: Page, test_config):
|
|
"""日历页面对象"""
|
|
# 使用uniapp的base_url
|
|
import yaml
|
|
from pathlib import Path
|
|
config_path = Path(__file__).parent / "config" / "config.yaml"
|
|
with open(config_path, "r", encoding="utf-8") as f:
|
|
data = yaml.safe_load(f)
|
|
env = os.getenv("TEST_ENV", "dev")
|
|
uniapp_base_url = data["environments"][env]["uniapp"]["base_url"]
|
|
return CalendarPage(page, uniapp_base_url)
|
|
|
|
|
|
@pytest.fixture
|
|
def user_page(page: Page, test_config):
|
|
"""用户页面对象"""
|
|
# 使用uniapp的base_url
|
|
import yaml
|
|
from pathlib import Path
|
|
config_path = Path(__file__).parent / "config" / "config.yaml"
|
|
with open(config_path, "r", encoding="utf-8") as f:
|
|
data = yaml.safe_load(f)
|
|
env = os.getenv("TEST_ENV", "dev")
|
|
uniapp_base_url = data["environments"][env]["uniapp"]["base_url"]
|
|
return UserPage(page, uniapp_base_url)
|
|
|
|
|
|
# 认证夹具
|
|
@pytest.fixture
|
|
def authenticated_page(page: Page, test_config):
|
|
"""已认证页面夹具"""
|
|
login_page = LoginPage(page, test_config.base_url)
|
|
login_page.navigate()
|
|
|
|
# 使用配置中的用户登录
|
|
users = test_config.users
|
|
if "admin" in users:
|
|
login_page.login(
|
|
users["admin"]["username"],
|
|
users["admin"]["password"]
|
|
)
|
|
else:
|
|
login_page.login("admin", "admin123")
|
|
|
|
# 等待跳转到仪表盘
|
|
login_page.wait_for_redirect()
|
|
|
|
return page
|
|
|
|
|
|
@pytest.fixture
|
|
def web_page(page: Page, test_config):
|
|
"""Web页面夹具(已认证)"""
|
|
login_page = LoginPage(page, test_config.base_url)
|
|
login_page.navigate()
|
|
|
|
# 使用配置中的用户登录
|
|
users = test_config.users
|
|
if "admin" in users:
|
|
login_page.login(
|
|
users["admin"]["username"],
|
|
users["admin"]["password"]
|
|
)
|
|
else:
|
|
login_page.login("admin", "admin123")
|
|
|
|
# 等待跳转到仪表盘
|
|
login_page.wait_for_redirect()
|
|
|
|
return page
|
|
|
|
|
|
@pytest.fixture
|
|
def integration_test_data(page: Page, test_config, user_management_page, role_management_page):
|
|
"""
|
|
集成测试数据准备fixture
|
|
|
|
为集成测试准备必要的测试数据,包括:
|
|
- 测试角色
|
|
- 测试用户
|
|
- 测试菜单
|
|
"""
|
|
import uuid
|
|
|
|
# 生成唯一标识
|
|
unique_id = str(uuid.uuid4())[:8]
|
|
|
|
# 准备测试角色
|
|
role_name = f"集成测试角色_{unique_id}"
|
|
role_code = f"integration_role_{unique_id}"
|
|
|
|
try:
|
|
role_management_page.navigate()
|
|
role_management_page.wait_for_load()
|
|
|
|
# 创建测试角色
|
|
role_management_page.click_create_button()
|
|
role_management_page.fill_form_name(role_name)
|
|
role_management_page.fill_form_code(role_code)
|
|
role_management_page.fill_form_description("集成测试专用角色")
|
|
role_management_page.click_form_submit()
|
|
|
|
# 等待创建完成
|
|
try:
|
|
role_management_page.wait_for_success_message()
|
|
except:
|
|
pass
|
|
except Exception as e:
|
|
print(f"创建测试角色失败: {e}")
|
|
|
|
# 准备测试用户
|
|
username = f"集成测试用户_{unique_id}"
|
|
email = f"integration_{unique_id}@example.com"
|
|
|
|
try:
|
|
user_management_page.navigate()
|
|
user_management_page.wait_for_load()
|
|
|
|
# 创建测试用户
|
|
user_management_page.click_create_button()
|
|
user_management_page.fill_form_username(username)
|
|
user_management_page.fill_form_nickname("集成测试用户")
|
|
user_management_page.fill_form_email(email)
|
|
user_management_page.fill_form_phone("13800138000")
|
|
user_management_page.click_form_submit()
|
|
|
|
# 等待创建完成
|
|
try:
|
|
user_management_page.wait_for_success_message()
|
|
except:
|
|
pass
|
|
except Exception as e:
|
|
print(f"创建测试用户失败: {e}")
|
|
|
|
# 返回测试数据
|
|
return {
|
|
"role": {
|
|
"name": role_name,
|
|
"code": role_code
|
|
},
|
|
"user": {
|
|
"username": username,
|
|
"email": email
|
|
},
|
|
"unique_id": unique_id
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def cleanup_test_data(page: Page, test_config, user_management_page, role_management_page):
|
|
"""
|
|
集成测试数据清理fixture
|
|
|
|
清理集成测试创建的测试数据
|
|
"""
|
|
yield
|
|
|
|
# 测试结束后清理数据
|
|
try:
|
|
# 删除测试角色
|
|
role_management_page.navigate()
|
|
role_management_page.wait_for_load()
|
|
|
|
# 搜索测试角色
|
|
role_management_page.fill_search("集成测试角色_")
|
|
role_management_page.click_search()
|
|
role_management_page.wait_for_table_load()
|
|
|
|
# 删除找到的测试角色
|
|
rows = role_management_page.get_table_rows_count()
|
|
for i in range(rows):
|
|
try:
|
|
role_management_page.click_row_delete(0)
|
|
role_management_page.confirm_delete()
|
|
role_management_page.wait_for_success_message()
|
|
except:
|
|
pass
|
|
except Exception as e:
|
|
print(f"清理测试角色失败: {e}")
|
|
|
|
try:
|
|
# 删除测试用户
|
|
user_management_page.navigate()
|
|
user_management_page.wait_for_load()
|
|
|
|
# 搜索测试用户
|
|
user_management_page.fill_search("集成测试用户_")
|
|
user_management_page.click_search()
|
|
user_management_page.wait_for_table_load()
|
|
|
|
# 删除找到的测试用户
|
|
rows = user_management_page.get_table_rows_count()
|
|
for i in range(rows):
|
|
try:
|
|
user_management_page.click_row_delete(0)
|
|
user_management_page.confirm_delete()
|
|
user_management_page.wait_for_success_message()
|
|
except:
|
|
pass
|
|
except Exception as e:
|
|
print(f"清理测试用户失败: {e}")
|
|
|
|
|
|
# pytest钩子函数
|
|
def pytest_configure(config):
|
|
"""pytest配置钩子"""
|
|
# 添加自定义标记
|
|
config.addinivalue_line("markers", "smoke: 冒烟测试")
|
|
config.addinivalue_line("markers", "regression: 回归测试")
|
|
config.addinivalue_line("markers", "admin: Admin端测试")
|
|
config.addinivalue_line("markers", "uniapp: Uniapp端测试")
|
|
config.addinivalue_line("markers", "slow: 慢速测试")
|
|
|
|
|
|
def pytest_collection_modifyitems(config, items):
|
|
"""测试收集修改钩子"""
|
|
# 自动添加标记
|
|
for item in items:
|
|
# 根据测试名称自动添加标记
|
|
if "admin" in item.nodeid.lower():
|
|
item.add_marker(pytest.mark.admin)
|
|
if "uniapp" in item.nodeid.lower():
|
|
item.add_marker(pytest.mark.uniapp)
|
|
|
|
|
|
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
|
|
def pytest_runtest_makereport(item, call):
|
|
"""测试结果报告钩子"""
|
|
outcome = yield
|
|
report = outcome.get_result()
|
|
|
|
# 获取测试名称
|
|
test_name = item.nodeid
|
|
|
|
# 记录测试结果
|
|
if report.when == "call":
|
|
status = report.outcome
|
|
|
|
# 获取page对象(如果存在)
|
|
page = None
|
|
for fixture_name in item.fixturenames:
|
|
if fixture_name == "page":
|
|
try:
|
|
page = item.funcargs.get("page")
|
|
except:
|
|
pass
|
|
break
|
|
|
|
# 截图(如果失败)
|
|
if status == "failed" and page:
|
|
try:
|
|
from core.screenshot_helper import ScreenshotHelper
|
|
screenshot_helper = ScreenshotHelper()
|
|
screenshot_helper.take_screenshot_on_failure(page, test_name)
|
|
except:
|
|
pass
|
|
|
|
|
|
def pytest_sessionfinish(session, exitstatus):
|
|
"""测试会话结束钩子"""
|
|
print("\n" + "="*60)
|
|
print("测试执行完成")
|
|
print(f"退出状态: {exitstatus}")
|
|
print("="*60)
|