Python自动化测试实战:从Selenium到Pytest的完整框架搭建指南 📅 发布时间:2026/9/4 2:33:42 👁 浏览次数: 在软件研发迭代越来越快的今天手工测试的局限性日益凸显——重复劳动、效率低下、难以覆盖复杂场景。作为一名测试或开发工程师你是否也曾在深夜为回归测试而烦恼Python 凭借其简洁的语法和强大的生态已成为自动化测试领域的首选语言。本文将为你呈现一套从零开始的 Python 自动化测试实战指南内容涵盖基础概念、核心工具链Selenium, Playwright, Pytest的深度使用以及一个完整的 Web 项目实战。无论你是零基础的小白还是希望系统提升的测试工程师都能通过本文构建起从环境搭建、脚本编写到框架设计、项目落地的完整知识体系最终实现测试工作的自动化与智能化。1. 自动化测试基础与 Python 环境搭建1.1 什么是自动化测试自动化测试是指利用软件工具、脚本和框架来执行测试用例替代人工操作并对实际结果与预期结果进行比较的过程。其核心价值在于提升效率将重复、机械的测试任务交给机器释放人力进行更有价值的探索性测试。提高覆盖率可以快速执行海量测试用例覆盖手工测试难以触及的边界场景。保证一致性避免人为疏忽每次执行都严格遵循预设步骤。支持持续集成/持续交付 (CI/CD)是 DevOps 流程中不可或缺的一环确保每次代码提交的质量。根据测试对象的不同自动化测试主要分为UI 自动化测试模拟用户操作浏览器或应用程序界面如 Selenium、Playwright。接口自动化测试直接调用 API 接口进行测试不经过前端界面如 Requests Pytest。单元测试针对代码的最小可测试单元函数、方法进行测试如 Unittest、Pytest。1.2 为什么选择 PythonPython 在自动化测试领域占据主导地位原因如下语法简洁代码可读性高学习曲线平缓适合测试人员快速上手。生态丰富拥有大量成熟、稳定的测试库和框架Selenium, Pytest, Requests, Appium等。跨平台在 Windows、macOS、Linux 上均可运行。社区活跃遇到问题容易找到解决方案和社区支持。1.3 Python 环境搭建与 IDE 配置工欲善其事必先利其器。一个稳定的开发环境是成功的第一步。步骤一安装 Python访问 Python 官方网站下载安装包。对于自动化测试推荐使用 Python 3.8 及以上版本以保证对新库的良好兼容性。安装时务必勾选 “Add Python to PATH” 选项。安装完成后打开命令行CMD 或 Terminal输入以下命令验证python --version # 或 python3 --version应显示类似Python 3.10.6的版本信息。步骤二安装包管理工具 pippip 是 Python 的包安装工具通常随 Python 一起安装。检查 pip 版本pip --version如果提示找不到命令可能需要手动安装或修复 Python 环境变量。步骤三配置虚拟环境 (Virtual Environment)强烈建议为每个项目创建独立的虚拟环境以避免不同项目间的依赖冲突。# 安装虚拟环境工具如果尚未安装 pip install virtualenv # 为你的自动化测试项目创建一个新目录并进入 mkdir python_auto_test cd python_auto_test # 创建虚拟环境环境文件夹名为 venv python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate激活后命令行提示符前会出现(venv)标识。步骤四选择并配置 IDEVSCode轻量、插件丰富是当前非常流行的选择。安装 Python 和 Pytest 相关插件即可。PyCharmJetBrains 出品功能强大对 Python 支持和测试集成非常友好社区版免费。本文后续示例将基于 VSCode 进行。2. 自动化测试核心工具链详解一个高效的自动化测试工作流离不开一系列核心工具的支撑。下面我们介绍最主流的组合。2.1 SeleniumWeb UI 自动化的基石Selenium 是一个用于 Web 应用程序测试的便携式框架。它支持多种浏览器Chrome, Firefox, Edge等和多种编程语言。安装在激活的虚拟环境中运行pip install selenium此外你还需要下载对应浏览器的WebDriver如chromedriver并将其所在目录添加到系统 PATH 环境变量中或者将驱动文件放在项目目录下。这是 Selenium 控制浏览器的桥梁。一个最简单的 Selenium 示例# test_selenium_demo.py from selenium import webdriver from selenium.webdriver.common.by import By import time # 1. 创建 WebDriver 实例启动 Chrome 浏览器 # 确保 chromedriver 在 PATH 或指定路径 driver webdriver.Chrome() try: # 2. 打开网页 driver.get(https://www.baidu.com) time.sleep(2) # 等待页面加载实际项目中应使用更智能的等待 # 3. 定位元素并操作 # 通过元素ID定位搜索框 search_box driver.find_element(By.ID, kw) search_box.send_keys(Python自动化测试) # 输入文本 # 通过元素ID定位“百度一下”按钮并点击 search_button driver.find_element(By.ID, “su”) search_button.click() time.sleep(3) # 等待搜索结果加载 # 4. 断言验证简单示例 assert “Python自动化测试” in driver.title print(“测试通过页面标题包含搜索关键词”) finally: # 5. 关闭浏览器 driver.quit()关键点解析By.ID是定位元素的一种策略其他还有By.NAME,By.CLASS_NAME,By.XPATH,By.CSS_SELECTOR。time.sleep强制等待是一种不推荐的等待方式。在实际项目中应使用显式等待。driver.quit()关闭浏览器并释放 WebDriver 资源必须执行。2.2 Playwright新一代浏览器自动化利器Playwright 由微软开发支持 Chromium、Firefox 和 WebKit一个 API 即可跨浏览器工作。它比 Selenium 更现代提供了自动等待、网络拦截、移动端模拟等强大功能。安装pip install playwright # 安装浏览器Chromium, Firefox, WebKit playwright installPlaywright 快速示例# test_playwright_demo.py import asyncio from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: # 启动浏览器默认无头模式headlessFalse 可看到界面 browser await p.chromium.launch(headlessFalse) page await browser.new_page() # 导航到页面Playwright 会自动等待页面加载到“load”状态 await page.goto(“https://www.baidu.com”) # 定位并操作元素语法更简洁 await page.fill(‘input#kw’, ‘Playwright自动化测试’) await page.click(‘input#su’) # 等待导航完成 await page.wait_for_load_state(‘networkidle’) # 获取页面标题并断言 title await page.title() assert ‘Playwright’ in title print(f“页面标题是{title}”) # 截图非常方便的功能 await page.screenshot(path‘search_result.png’) await browser.close() # 运行异步函数 asyncio.run(main())Playwright 优势自动等待大部分操作如click,fill会自动等待元素可交互无需手动添加等待。强大的选择器支持 CSS、XPath、文本内容等多种定位方式且语法统一。多上下文与设备模拟轻松模拟移动设备、地理位置、权限等。网络拦截与 Mock可以拦截和修改网络请求便于测试。2.3 Pytest强大而灵活的测试框架Pytest 是 Python 社区最主流的测试框架它让编写和运行测试变得简单而有趣。安装与基本使用pip install pytest编写一个简单的 Pytest 测试# test_calculator.py # 文件名需以 test_ 开头或 _test 结尾 # 函数名需以 test_ 开头 def add(a, b): return a b def test_add_positive_numbers(): assert add(2, 3) 5 def test_add_negative_numbers(): assert add(-1, -1) -2 def test_add_with_zero(): assert add(5, 0) 5在命令行中进入该文件所在目录运行pytest test_calculator.py -v-v参数表示输出详细信息。Pytest 会自动发现并运行所有test_开头的函数并用绿色的.或PASSED表示测试通过。Pytest 核心特性Fixture用于提供测试所需的数据、环境或资源实现 setup/teardown 逻辑。import pytest pytest.fixture def sample_data(): data [1, 2, 3, 4, 5] yield data # 测试函数执行前返回data执行后执行清理如果有 print(“测试结束清理数据”) # 可选的清理代码 def test_data_length(sample_data): # 使用 fixture assert len(sample_data) 5参数化测试用一组数据驱动同一个测试逻辑。import pytest pytest.mark.parametrize(“a,b,expected”, [ (1, 2, 3), (4, 5, 9), (10, -5, 5), ]) def test_add_param(a, b, expected): assert add(a, b) expected丰富的插件生态如pytest-html生成HTML报告、pytest-xdist并行测试、pytest-cov覆盖率报告。2.4 Requests接口自动化测试的核心库对于后端 API 测试requests库是事实上的标准。安装与简单示例pip install requests# test_api_demo.py import requests import pytest # 定义一个测试用的 API 端点这里使用免费的公共API BASE_URL “https://jsonplaceholder.typicode.com” def test_get_posts(): response requests.get(f“{BASE_URL}/posts/1”) # 断言状态码 assert response.status_code 200 # 断言响应体结构 data response.json() assert ‘id’ in data assert data[‘id’] 1 assert ‘title’ in data print(f“获取到的文章标题{data[‘title’]}”) def test_create_post(): new_post { “title”: “foo”, “body”: “bar”, “userId”: 1, } headers {‘Content-type’: ‘application/json; charsetUTF-8’} response requests.post(f“{BASE_URL}/posts”, jsonnew_post, headersheaders) assert response.status_code 201 created_data response.json() assert created_data[‘title’] ‘foo’ assert ‘id’ in created_data print(f“创建的文章ID{created_data[‘id’]}”)3. 项目实战搭建一个简易的 Web 自动化测试框架我们将综合运用以上工具为一个假设的在线图书商城我们本地启动一个简易 Flask 应用来模拟搭建一个自动化测试框架。3.1 项目结构与需求分析项目目标测试一个具有登录、浏览图书、搜索功能的 Web 应用。项目结构bookstore_auto_test/ ├── conftest.py # Pytest 共享配置和 Fixture ├── requirements.txt # 项目依赖 ├── pages/ # 页面对象模型 (Page Object Model) │ ├── __init__.py │ ├── base_page.py │ ├── login_page.py │ └── home_page.py ├── tests/ # 测试用例 │ ├── __init__.py │ ├── test_login.py │ └── test_search.py ├── utils/ # 工具类 │ ├── __init__.py │ └── driver_manager.py └── app.py # 模拟的 Web 应用 (Flask)3.2 模拟 Web 应用 (app.py)为了实战我们先创建一个极简的 Flask 应用作为测试目标。# app.py from flask import Flask, render_template_string, request, redirect, url_for, session app Flask(__name__) app.secret_key ‘your_secret_key_here’ # 用于 session # 模拟的图书数据 BOOKS [ {“id”: 1, “title”: “Python编程从入门到实践”, “author”: “Eric Matthes”, “price”: 89.0}, {“id”: 2, “title”: “Selenium自动化测试指南”, “author”: “Unmesh Gundecha”, “price”: 79.0}, {“id”: 3, “title”: “玩转Playwright”, “author”: “微软”, “price”: 69.0}, {“id”: 4, “title”: “Pytest实战”, “author”: “Brian Okken”, “price”: 59.0}, ] app.route(‘/’) def home(): user session.get(‘username’, ‘Guest’) html “”” h1欢迎来到简易图书商城{{ user }}/h1 a href“/login”登录/a | a href“/books”查看所有图书/a form action“/search” method“get” input type“text” name“q” placeholder“搜索图书…” button type“submit”搜索/button /form “”” return render_template_string(html, useruser) app.route(‘/login’, methods[‘GET’, ‘POST’]) def login(): if request.method ‘POST’: username request.form[‘username’] password request.form[‘password’] # 简单验证用户名为 ‘test’密码为 ‘123456’ if username ‘test’ and password ‘123456’: session[‘username’] username return redirect(url_for(‘home’)) else: return “登录失败用户名或密码错误”, 401 # GET 请求返回登录表单 login_form “”” form method“post” 用户名input type“text” name“username”br 密码input type“password” name“password”br button type“submit”登录/button /form “”” return login_form app.route(‘/books’) def list_books(): book_list “h1图书列表/h1ul” for book in BOOKS: book_list f“li{book[‘title’]} - {book[‘author’]} (¥{book[‘price’]})/li” book_list “/ula href‘/’返回首页/a” return book_list app.route(‘/search’) def search(): query request.args.get(‘q’, ‘’).lower() results [b for b in BOOKS if query in b[‘title’].lower()] result_html f“h1搜索 ‘{query}’ 的结果/h1” if results: result_html “ul” for book in results: result_html f“li{book[‘title’]} - {book[‘author’]}/li” result_html “/ul” else: result_html “p未找到相关图书。/p” result_html “a href‘/’返回首页/a” return result_html if __name__ ‘__main__’: app.run(debugTrue, port5000)运行python app.py访问http://127.0.0.1:5000即可看到应用。3.3 核心框架代码实现1. 依赖文件 (requirements.txt)selenium4.10.0 pytest7.3.1 pytest-html3.2.0 webdriver-manager3.8.6 # 自动管理浏览器驱动 Flask2.3.2 # 仅用于运行模拟应用测试代码本身不依赖使用pip install -r requirements.txt安装所有依赖。webdriver-manager可以自动下载和匹配浏览器驱动省去手动管理的麻烦。2. 驱动管理工具 (utils/driver_manager.py)# utils/driver_manager.py from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from webdriver_manager.firefox import GeckoDriverManager class DriverManager: staticmethod def get_chrome_driver(headlessFalse): “”“获取 Chrome WebDriver 实例”“” options webdriver.ChromeOptions() if headless: options.add_argument(‘--headless’) # 无头模式不打开浏览器窗口 options.add_argument(‘--no-sandbox’) options.add_argument(‘--disable-dev-shm-usage’) # 使用 webdriver-manager 自动管理驱动 service Service(ChromeDriverManager().install()) driver webdriver.Chrome(serviceservice, optionsoptions) driver.implicitly_wait(10) # 设置隐式等待全局生效 driver.maximize_window() return driver staticmethod def get_firefox_driver(headlessFalse): “”“获取 Firefox WebDriver 实例”“” options webdriver.FirefoxOptions() if headless: options.add_argument(‘--headless’) service Service(GeckoDriverManager().install()) driver webdriver.Firefox(serviceservice, optionsoptions) driver.implicitly_wait(10) driver.maximize_window() return driver3. 页面对象模型 (Page Object Model, POM)POM 是一种设计模式将页面元素定位和操作封装成类提高代码复用性和可维护性。基础页面类 (pages/base_page.py):# pages/base_page.py from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class BasePage: def __init__(self, driver): self.driver driver self.wait WebDriverWait(driver, 10) # 显式等待最多10秒 def find_element(self, by, locator): “”“查找单个元素使用显式等待”“” return self.wait.until(EC.presence_of_element_located((by, locator))) def find_elements(self, by, locator): “”“查找多个元素”“” return self.driver.find_elements(by, locator) def click(self, by, locator): “”“点击元素”“” element self.find_element(by, locator) element.click() def input_text(self, by, locator, text): “”“向输入框输入文本”“” element self.find_element(by, locator) element.clear() element.send_keys(text) def get_title(self): “”“获取页面标题”“” return self.driver.title登录页面类 (pages/login_page.py):# pages/login_page.py from selenium.webdriver.common.by import By from .base_page import BasePage class LoginPage(BasePage): # 页面元素定位器 USERNAME_INPUT (By.NAME, ‘username’) PASSWORD_INPUT (By.NAME, ‘password’) SUBMIT_BUTTON (By.XPATH, “//button[type‘submit’]”) ERROR_MESSAGE (By.TAG_NAME, ‘body’) # 简化处理错误信息在body中 def __init__(self, driver): super().__init__(driver) self.driver driver def open(self, url): self.driver.get(url) def login(self, username, password): self.input_text(*self.USERNAME_INPUT, username) self.input_text(*self.PASSWORD_INPUT, password) self.click(*self.SUBMIT_BUTTON) def get_error_message(self): # 这是一个简单示例实际中错误信息可能有特定元素 return self.find_element(*self.ERROR_MESSAGE).text首页类 (pages/home_page.py):# pages/home_page.py from selenium.webdriver.common.by import By from .base_page import BasePage class HomePage(BasePage): SEARCH_BOX (By.NAME, ‘q’) SEARCH_BUTTON (By.XPATH, “//button[type‘submit’]”) BOOKS_LINK (By.LINK_TEXT, ‘查看所有图书’) LOGIN_LINK (By.LINK_TEXT, ‘登录’) GREETING_TEXT (By.TAG_NAME, ‘h1’) def search_book(self, keyword): self.input_text(*self.SEARCH_BOX, keyword) self.click(*self.SEARCH_BUTTON) def go_to_books_page(self): self.click(*self.BOOKS_LINK) def go_to_login_page(self): self.click(*self.LINK_LINK)4. Pytest 配置与共享 Fixture (conftest.py)# conftest.py import pytest from utils.driver_manager import DriverManager pytest.fixture(scope“function”) # 每个测试函数执行一次 def driver(): “”“提供 WebDriver 实例”“” driver DriverManager.get_chrome_driver(headlessTrue) # 测试时用无头模式 yield driver driver.quit() # 测试结束后退出浏览器 pytest.fixture def login_page(driver): “”“提供登录页面实例”“” from pages.login_page import LoginPage page LoginPage(driver) page.open(“http://127.0.0.1:5000/login”) return page pytest.fixture def home_page(driver): “”“提供首页实例”“” from pages.home_page import HomePage page HomePage(driver) page.open(“http://127.0.0.1:5000/”) return page3.4 编写并运行测试用例测试登录功能 (tests/test_login.py):# tests/test_login.py import pytest class TestLogin: “”“测试登录功能”“” def test_login_success(self, login_page): “”“测试成功登录”“” login_page.login(‘test’, ‘123456’) # 登录成功后应跳转到首页首页的欢迎语包含用户名 assert ‘test’ in login_page.driver.page_source print(“登录成功测试通过”) def test_login_failure(self, login_page): “”“测试登录失败”“” login_page.login(‘wrong’, ‘password’) error_text login_page.get_error_message() assert ‘登录失败’ in error_text or ‘401’ in error_text print(“登录失败测试通过”)测试搜索功能 (tests/test_search.py):# tests/test_search.py import pytest class TestSearch: “”“测试搜索功能”“” def test_search_existing_book(self, home_page): “”“搜索存在的图书”“” home_page.search_book(‘Python’) assert ‘Python编程从入门到实践’ in home_page.driver.page_source print(“搜索存在的图书测试通过”) def test_search_non_existing_book(self, home_page): “”“搜索不存在的图书”“” home_page.search_book(‘不存在的书’) assert ‘未找到相关图书’ in home_page.driver.page_source print(“搜索不存在的图书测试通过”)运行测试并生成报告在项目根目录下执行以下命令# 1. 首先确保模拟应用在运行 (在另一个终端运行 python app.py) # 2. 运行所有测试 pytest tests/ -v # 3. 运行测试并生成HTML报告 pytest tests/ -v --htmlreport.html --self-contained-html # 4. 只运行某个文件 pytest tests/test_login.py -v # 5. 运行带有特定标记的测试需先使用 pytest.mark.xxx 装饰器标记 # pytest tests/ -m “login” -v运行后会生成一个report.html文件用浏览器打开即可查看详细的测试结果、通过率、失败原因和日志非常适合集成到 CI/CD 流程中。4. 常见问题与排查思路在自动化测试实践中你会遇到各种各样的问题。下面是一些典型问题及其解决方案。问题现象可能原因排查步骤与解决方案WebDriverException: Message: ‘chromedriver’ executable needs to be in PATH1. 未安装 ChromeDriver。2. ChromeDriver 版本与 Chrome 浏览器版本不匹配。3. ChromeDriver 路径未加入系统环境变量。1.最佳方案使用webdriver-manager自动管理驱动如本文示例。2. 手动下载访问 ChromeDriver 官网下载与本地 Chrome 浏览器大版本号一致的驱动。3. 将驱动文件放在项目目录下并在代码中指定路径webdriver.Chrome(executable_path‘./chromedriver’)。NoSuchElementException或元素找不到1. 页面未加载完成就进行元素定位。2. 元素定位器如ID、XPath写错了。3. 元素在 iframe 或 Shadow DOM 内。4. 页面是动态生成的元素属性会变。1.使用智能等待用WebDriverWait配合expected_conditions如presence_of_element_located,element_to_be_clickable。2.检查定位器使用浏览器开发者工具F12的 Console 验证$x(‘your_xpath’)或$(‘your_css’)。3.处理 iframe先用driver.switch_to.frame(frame_element)切换到 iframe。4.使用更稳定的定位器优先使用id,name, 稳定的css selector避免使用绝对 XPath。测试在无头模式下通过但有界面时失败1. 界面加载速度差异导致时机问题。2. 浏览器窗口大小影响元素可见性或布局。1. 增加等待时间或使用更可靠的等待条件。2. 在有界面模式下也使用driver.maximize_window()确保一致性。3. 检查是否有弹窗、通知遮挡了元素。Pytest 找不到测试用例1. 测试文件或函数命名不符合 Pytest 发现规则。2. 未在正确的目录下运行pytest。1. 确保测试文件以test_开头或_test结尾如test_login.py。2. 确保测试函数以test_开头。3. 在项目根目录或包含tests目录的上级目录运行pytest。测试报告report.html为空或样式丢失使用--htmlreport.html时未添加--self-contained-html参数。使用命令pytest --htmlreport.html --self-contained-html。--self-contained-html会将 CSS 和 JS 内嵌到 HTML 中使报告可独立查看。接口测试返回 4xx/5xx 错误1. 请求头如Content-Type,Authorization缺失或错误。2. 请求参数格式错误。3. 接口地址或方法GET/POST错误。4. 需要处理 cookies 或 session。1. 使用抓包工具如浏览器F12的Network面板查看成功请求的详细信息并模仿其请求头和参数。2. 对于 JSON 数据使用requests.post(url, jsondata)而非datadata。3. 使用session requests.Session()来保持会话状态。5. 最佳实践与工程建议掌握了基础工具和框架后要写出健壮、可维护的自动化测试代码还需要遵循以下最佳实践。5.1 测试代码设计原则单一职责每个测试用例只验证一个功能点。一个失败的测试能清晰指出问题所在。独立性测试用例之间不应该有依赖。使用 Fixture 的setup/teardown确保每个测试都在干净的环境中开始。可读性给测试用例和函数起一个描述性的名字如test_login_with_invalid_password_should_fail。在断言失败时信息应清晰明了。稳定性避免使用time.sleep()进行固定等待。务必使用隐式等待 (implicitly_wait) 和显式等待 (WebDriverWait)。可维护性积极采用页面对象模型 (POM)。当页面 UI 变更时你只需要修改对应的 Page 类中的定位器而不需要修改大量测试用例。5.2 数据驱动测试将测试数据与测试逻辑分离。Pytest 的pytest.mark.parametrize是绝佳工具。import pytest login_test_data [ (‘test’, ‘123456’, True, ‘登录成功’), (‘wrong’, ‘123456’, False, ‘用户名错误’), (‘test’, ‘wrong’, False, ‘密码错误’), (‘’, ‘’, False, ‘用户名密码为空’), ] pytest.mark.parametrize(“username, password, expected_success, description”, login_test_data) def test_login_ddt(login_page, username, password, expected_success, description): login_page.login(username, password) if expected_success: assert ‘test’ in login_page.driver.page_source else: assert ‘登录失败’ in login_page.driver.page_source or ‘401’ in login_page.driver.page_source print(f“测试用例 ‘{description}’ 通过”)5.3 配置管理与环境隔离使用配置文件将 URL、用户名、密码、超时时间等配置信息放在配置文件如config.yaml或config.ini或环境变量中不要硬编码在代码里。区分环境为开发、测试、生产环境准备不同的配置文件。使用.gitignore确保配置文件尤其是包含密码的不被提交到版本库。5.4 日志与报告记录详细日志使用 Python 的logging模块记录测试执行的关键步骤和错误信息便于排查。丰富的测试报告除了pytest-html还可以结合allure-pytest生成更美观、交互性更强的 Allure 报告。失败截图在测试失败时自动截图能极大帮助定位 UI 问题。可以在 Pytest 的conftest.py中通过 hook 函数实现。# conftest.py 中添加 import pytest from datetime import datetime pytest.hookimpl(hookwrapperTrue) def pytest_runtest_makereport(item, call): outcome yield report outcome.get_result() if report.when “call” and report.failed: # 假设 driver 是 fixture if ‘driver’ in item.fixturenames: driver item.funcargs[‘driver’] timestamp datetime.now().strftime(“%Y%m%d_%H%M%S”) screenshot_path f“./screenshots/failure_{item.name}_{timestamp}.png” driver.save_screenshot(screenshot_path) print(f“Screenshot saved to: {screenshot_path}”)5.5 集成到 CI/CD 流水线自动化测试的真正价值在于持续集成。你可以将测试套件集成到 Jenkins、GitLab CI、GitHub Actions 等工具中。GitHub Actions 示例在项目根目录创建.github/workflows/test.yml。name: Python Automated Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Set up Python uses: actions/setup-pythonv4 with: python-version: ‘3.10’ - name: Install dependencies run: | pip install -r requirements.txt playwright install chromium - name: Run Flask app in background run: | python app.py sleep 5 # 等待应用启动 - name: Run tests with pytest run: | pytest tests/ -v --htmlreport.html --self-contained-html - name: Upload test report uses: actions/upload-artifactv3 if: always() with: name: test-report path: report.html6. 总结与进阶学习路线通过本文你已经完成了从零到一的 Python 自动化测试入门掌握了环境搭建、Selenium/Playwright 操作、Pytest 框架使用、页面对象模型设计以及一个完整项目的实战。这为你打下了坚实的基础。下一步你可以沿着以下方向深入深入 Playwright学习其高级特性如网络拦截、下载/上传处理、跨浏览器测试、移动端模拟、录制生成代码等。接口自动化测试进阶学习使用pytestrequestsAllure搭建更专业的接口测试框架处理 Token 认证、数据加密、数据库断言等。移动端自动化学习Appium框架进行 Android/iOS 原生应用或混合应用的自动化测试。测试框架设计思考如何设计数据驱动、关键字驱动、行为驱动如behave的测试框架以适应更复杂的业务。持续集成/持续部署 (CI/CD)将你的自动化测试脚本无缝集成到团队的 DevOps 流程中实现代码提交即触发测试。AI 在测试中的应用探索如何利用 AI 进行视觉测试、测试用例生成、缺陷预测等这是当前的前沿方向。自动化测试是一个需要不断实践和总结的领域。从模仿本文的示例开始尝试为你正在参与的项目添加自动化测试从小模块做起逐步构建起守护产品质量的自动化防线。记住好的测试代码和生产代码同等重要。