当前位置: 首页 > news >正文

Python + Selenium 4.0 自动化测试框架搭建:集成 Pytest 与 Allure 生成 3 类可视化报告

Python + Selenium 4.0 自动化测试框架搭建:集成 Pytest 与 Allure 生成 3 类可视化报告

在当今快速迭代的软件开发周期中,UI自动化测试已成为保障产品质量的重要防线。本文将深入探讨如何基于Python和Selenium 4.0构建一个企业级的自动化测试框架,通过Pytest进行高效的用例管理,并利用Allure生成专业级的可视化测试报告。

1. 框架设计与工程化实践

一个成熟的自动化测试框架需要解决脚本可维护性、执行效率和结果可视化三大核心问题。我们采用分层架构设计,将框架划分为以下核心模块:

  • 驱动层:封装Selenium WebDriver的基础操作
  • 页面对象层:实现Page Object Model (POM)设计模式
  • 测试用例层:组织测试逻辑与断言
  • 报告层:集成Allure生成可视化报告

1.1 项目目录结构规范

project_root/ ├── config/ │ ├── __init__.py │ ├── config.py # 全局配置 │ └── paths.py # 路径管理 ├── drivers/ # 浏览器驱动 ├── pages/ │ ├── __init__.py │ ├── base_page.py # 基础页面类 │ └── login_page.py # 示例页面对象 ├── tests/ │ ├── __init__.py │ ├── conftest.py # Pytest配置 │ └── test_login.py # 测试用例 ├── utils/ │ ├── __init__.py │ ├── logger.py # 日志工具 │ └── report_utils.py # 报告工具 ├── requirements.txt # 依赖清单 └── pytest.ini # Pytest配置

1.2 核心依赖版本选择

# requirements.txt selenium==4.0.0 pytest==7.0.1 pytest-xdist==2.5.0 # 分布式测试 allure-pytest==2.9.45 webdriver-manager==3.8.5 # 自动管理浏览器驱动

2. Selenium 4.0 新特性深度应用

Selenium 4.0引入了多项重要改进,我们需要在框架中充分利用这些特性:

2.1 相对定位器(Relative Locators)

from selenium.webdriver.common.by import By from selenium.webdriver.support.relative_locator import locate_with # 传统定位方式 username = driver.find_element(By.ID, "username") # 使用相对定位器 - 找到username下方的元素 password = driver.find_element( locate_with(By.TAG_NAME, "input").below(username) )

2.2 改进的窗口与标签页管理

# 获取所有窗口句柄 handles = driver.window_handles # 切换到新标签页 driver.switch_to.new_window('tab') # 切换到新窗口 driver.switch_to.new_window('window') # 获取当前窗口大小和位置 rect = driver.get_window_rect()

2.3 Chrome DevTools协议集成

from selenium.webdriver import Chrome from selenium.webdriver.common.devtools.v85 import devtools driver = Chrome() dev_tools = driver.get_devtools() dev_tools.create_session() # 模拟网络条件 dev_tools.send(devtools.network.emulate_network_conditions( offline=False, latency=100, # 毫秒 download_throughput=500*1024, # 500kb/s upload_throughput=500*1024 ))

3. Pytest集成与高级用法

Pytest作为测试框架提供了强大的功能扩展能力,我们需要合理配置以支持自动化测试需求。

3.1 基础配置(pytest.ini)

[pytest] addopts = -v --alluredir=./allure-results --clean-alluredir testpaths = tests python_files = test_*.py python_classes = Test* python_functions = test_* markers = smoke: 冒烟测试 regression: 回归测试

3.2 固件(Fixture)设计

# conftest.py import pytest from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager @pytest.fixture(scope="session") def driver(): # Selenium 4.0推荐的服务管理方式 service = Service(ChromeDriverManager().install()) options = webdriver.ChromeOptions() options.add_argument("--headless") # 无头模式 options.add_argument("--window-size=1920,1080") driver = webdriver.Chrome(service=service, options=options) driver.implicitly_wait(10) # 全局隐式等待 yield driver driver.quit() @pytest.fixture def login(driver): """登录系统固件""" driver.get("https://example.com/login") # 执行登录操作 yield # 测试结束后保持登录状态

3.3 参数化测试与标记

import pytest @pytest.mark.parametrize("username,password,expected", [ ("admin", "correct_pwd", True), ("user", "wrong_pwd", False), ("", "", False) ]) @pytest.mark.regression def test_login(driver, login, username, password, expected): """测试不同登录场景""" login_page = LoginPage(driver) result = login_page.login(username, password) assert result == expected

4. Allure报告系统深度集成

Allure报告系统提供了丰富的可视化功能,我们需要全面配置以生成专业级测试报告。

4.1 基础报告生成配置

# conftest.py import allure @pytest.hookimpl(tryfirst=True, hookwrapper=True) def pytest_runtest_makereport(item, call): """处理测试结果并附加到Allure报告""" outcome = yield rep = outcome.get_result() if rep.when == "call" and rep.failed: # 失败时截图 driver = item.funcargs.get("driver") if driver: allure.attach( driver.get_screenshot_as_png(), name="screenshot", attachment_type=allure.attachment_type.PNG )

4.2 生成三类核心报告

4.2.1 趋势分析报告
# 在pytest钩子中添加历史趋势数据 def pytest_sessionfinish(session): """测试会话结束时收集历史数据""" history_path = "./allure-results/history" if os.path.exists(history_path): shutil.copytree(history_path, "./allure-report/history")
4.2.2 用例详情报告
import allure @allure.feature("登录模块") class TestLogin: @allure.story("用户登录") @allure.title("测试管理员登录") @allure.severity(allure.severity_level.CRITICAL) def test_admin_login(self, driver, login): """测试管理员登录功能""" with allure.step("输入用户名密码"): login_page = LoginPage(driver) login_page.enter_username("admin") login_page.enter_password("admin123") with allure.step("点击登录按钮"): login_page.click_login() with allure.step("验证登录结果"): assert driver.current_url == "https://example.com/dashboard"
4.2.3 失败分析报告
# 在conftest.py中添加失败分析 @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): outcome = yield report = outcome.get_result() if report.when == "call": xfail = hasattr(report, "wasxfail") if (report.skipped and xfail) or (report.failed and not xfail): # 收集失败时的页面源码 driver = item.funcargs.get("driver") if driver: allure.attach( driver.page_source, name="page_source", attachment_type=allure.attachment_type.HTML )

4.3 报告生成与查看

# 生成Allure报告 allure generate ./allure-results -o ./allure-report --clean # 本地查看报告 allure open ./allure-report

5. 企业级最佳实践与优化策略

5.1 并行测试执行

# pytest.ini配置并行执行 [pytest] addopts = -n auto # 自动检测CPU核心数

5.2 智能等待策略

from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def wait_for_element(driver, locator, timeout=10): """自定义等待函数""" return WebDriverWait(driver, timeout).until( EC.presence_of_element_located(locator), message=f"元素 {locator} 未在 {timeout} 秒内出现" )

5.3 日志系统集成

# utils/logger.py import logging from logging.handlers import RotatingFileHandler def setup_logger(name): logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) # 文件处理器 file_handler = RotatingFileHandler( "automation.log", maxBytes=1024*1024, backupCount=5 ) file_formatter = logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) file_handler.setFormatter(file_formatter) # 控制台处理器 console_handler = logging.StreamHandler() console_formatter = logging.Formatter("%(levelname)s - %(message)s") console_handler.setFormatter(console_formatter) logger.addHandler(file_handler) logger.addHandler(console_handler) return logger

5.4 CI/CD集成示例

# .github/workflows/test.yml name: UI Automation Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: '3.9' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run tests run: | pytest tests/ --alluredir=./allure-results - name: Generate Allure report if: always() uses: simple-elf/allure-report-action@v1 with: allure_results: allure-results

6. 常见问题与解决方案

6.1 元素定位失败处理

from selenium.common.exceptions import NoSuchElementException def safe_find_element(driver, by, value): """安全查找元素,避免抛出异常""" try: return driver.find_element(by, value) except NoSuchElementException: logger.warning(f"未找到元素: {by}={value}") return None

6.2 动态元素处理策略

# 使用CSS选择器处理动态ID dynamic_element = driver.find_element( By.CSS_SELECTOR, "div[id^='dynamic_'][id$='_container']" ) # 使用XPath处理动态class dynamic_element = driver.find_element( By.XPATH, "//div[contains(@class, 'dynamic-')]" )

6.3 测试数据管理

import json from dataclasses import dataclass @dataclass class TestData: username: str password: str expected: bool def load_test_data(file_path): """从JSON文件加载测试数据""" with open(file_path) as f: data = json.load(f) return [TestData(**item) for item in data]

通过以上系统化的框架搭建和实践,我们能够构建一个高效、可维护的UI自动化测试体系。在实际项目中,建议根据具体需求调整框架细节,并持续优化测试用例的设计与执行策略。

http://www.jsqmd.com/news/1177644/

相关文章:

  • SQL Server (SMSS) 表与列增删查改基础
  • 技术成长路径规划:从目标分解到持续积累的实战策略
  • PlayCover深度解析:Apple Silicon上的iOS应用沙盒化与输入重映射核心技术
  • SSH 密钥管理与 ssh-agent 配置:解决多密钥与免密登录的 5 个核心场景
  • 一套平台覆盖全流程:Visual RM六大核心功能适配电网需求管控全链路
  • 用PowerPoint+Paint打造可呼吸的数字黑板
  • 从零实现C++ HTTP服务器:Epoll、Reactor与协议解析实战
  • 【共创季稿事节】HarmonyOS 6.1 安全加固实战:从代码防篡改到数据加密的全链路防护
  • 2026年FFU厂家的价格参考与比较 - 品牌排行榜
  • 鸿蒙ArkUI实战:让优先级和到期时间成为可读的视觉标签
  • Visual Studio 2022 配置 LVGL 9.2.2 模拟器:3个关键依赖库与子模块更新详解
  • PIC18LF46K80上拉下拉配置与DTH-08通信优化
  • AI Agent 全貌概览
  • 告别用第三方配音!2026 年支持多语种创作的AI视频生成工具6款综合测评
  • MetaWRAP 模块化安装:3种 Conda 策略与 140+ 依赖管理实战
  • A3908与PIC18F97J60构建的高精度网络化电机控制系统
  • CTFShow 萌新区 Web 17-21 通解:Nginx 日志包含漏洞利用与 3 步 Getshell
  • 从零开始:大气层整合包系统如何让Switch破解变得简单又安全
  • Elasticsearch 8.11.1 + Kibana 8.11.1 双组件Windows联调:解决3类常见连接失败问题
  • TK1手动刷机实战:从启动链到eMMC分区的嵌入式系统重装指南
  • Canal 1.1.5 数据同步性能调优:解析并行度与MQ参数配置实测
  • Mapbox Unity SDK实战:AR地图与位置服务开发全攻略
  • 免费开源虚拟桌面伴侣Mate Engine:打造专属二次元桌宠的终极指南
  • 群晖NAS网络性能飞跃:3步实现USB 2.5G网卡驱动完整安装方案
  • 多平台都要过 AIGC 检测,选哪种降 AIGC 工具最省事?
  • C++项目集成脚本引擎:从Lua到Python的七种方案与实战解析
  • 2026年7月最新重庆伯爵官方售后客户服务电话及线下网点地址 - 亨得利钟表维修中心
  • 如何在30分钟内构建企业级GB28181视频监控平台:wvp-GB28181-pro容器化部署完整指南
  • HarmonyOS 6.1 元服务实战:把电商卡片装进系统“负一屏”
  • Git仓库基础用法