新手自动化测试入门:5个精选练手项目与实战框架搭建指南 1. 项目概述为什么新手需要从“练手项目”开始如果你刚接触自动化测试面对Selenium、Postman、Appium这些工具是不是感觉有点无从下手看了一堆教程感觉都懂了但一打开IDE手就僵住了不知道从哪里写第一行代码。这太正常了几乎所有测试工程师的成长路上都会遇到这个阶段。问题的核心在于你缺少一个“靶子”——一个目标明确、结构清晰、能让你把所有知识点串联起来并动手验证的练习项目。光看理论就像只学游泳姿势却不下水永远学不会。这就是为什么我强烈建议新手在系统学习自动化测试理论之后必须立刻、马上找一个合适的项目来练手。一个好的练手项目能帮你把“定位元素”、“发送请求”、“断言结果”、“组织用例”这些分散的知识点像拼图一样组合成一个完整的画面。它让你在实践中理解框架设计、数据驱动、报告生成这些概念到底有什么用而不是停留在抽象的名词解释上。今天我就结合自己带新人和多年踩坑的经验给你推荐几个精心挑选的、非常适合新手入门的接口和Web UI自动化测试练习项目。这些项目有几个共同特点目标明确功能不复杂、环境简单依赖少容易搭建、技术栈主流用的都是你现在学、未来工作中也会用的工具而且大部分都有可公开访问的在线演示环境或清晰的部署指南让你免去搭建复杂后端服务的烦恼能专注于测试脚本本身。2. 练手项目核心价值与选型逻辑在直接抛出项目列表之前我觉得有必要先聊聊“为什么是这几个项目”。理解背后的选型逻辑比你机械地照做更重要这能帮助你在未来为自己或团队挑选、甚至设计测试项目时拥有清晰的判断标准。2.1 一个好练手项目的四大黄金准则我总结了一个好的自动化测试练手项目至少要满足以下四点功能闭环场景真实项目应该具备一个完整的、小规模的核心业务流程。比如一个用户从注册、登录、到完成一个核心操作如发布内容、下单的流程。这比单纯测试一个孤立的“登录接口”或“查询按钮”有价值得多因为它模拟了真实的工作场景让你思考流程衔接、状态保持如Cookie/Session/Token等问题。技术栈贴合当前主流练习使用的工具和框架应该是行业里广泛应用的。例如Web UI自动化用Selenium Python/Java Pytest/TestNG接口测试用Postman Newman 或 Requests库 Pytest。避免使用过于冷门或已被淘汰的技术确保你的练习经验能无缝迁移到实际工作中。环境依赖少易于搭建理想情况是存在稳定的公网测试环境。如果必须本地部署那么项目应该提供清晰的Docker Compose文件或一键部署脚本。新手最大的拦路虎之一就是环境问题一个搞不定的环境足以浇灭所有热情。我们的目标是练习“测试”而不是练习“部署运维”。有可供验证的预期结果你需要清楚地知道当你执行了某个操作后系统“应该”返回什么。这意味着项目要么有详细的接口文档要么前端UI交互明确。最好这个项目本身是你相对熟悉的领域比如一个TODO列表、一个博客系统这样你更容易设计出有效的测试用例。基于以上准则我过滤掉了那些需要复杂中间件、数据库配置繁琐、或者业务逻辑过于晦涩的项目。下面推荐的项目都是“开箱即用”或“稍作配置即可用”的精品。2.2 工具选型为什么是它们这里简单提一下配套工具的选择这也是你开始练习前需要明确的Web UI自动化Python Selenium Pytest是首选组合。Python语法简洁上手快Selenium是行业标准Pytest框架功能强大夹具fixture和参数化非常友好。对于纯新手我不建议一开始就上Page Object模式PO可以先从线性脚本开始等熟悉了再重构为PO理解会更深刻。接口自动化Postman入门和Python Requests Pytest进阶双线进行。Postman图形化界面友好适合理解HTTP请求、参数、断言的基本概念。而用代码Requests库实现则是走向框架化、持续集成的必经之路。测试报告Allure。这是目前最主流的测试报告框架之一美观且信息丰富。Pytest可以很好集成Allure生成包含步骤、截图、附件的详细报告让你的练习成果看起来非常专业。明确了“练什么”和“用什么练”接下来我们就进入正题。3. 五大精选新手友好型练习项目详解我将项目分为“接口为主”和“Web UI为主”两类但很多项目是两者兼备的你可以由浅入深逐步挑战。3.1 项目一宠物商店 (Swagger Petstore) —— 接口测试入门神器项目简介这不是一个需要你部署的项目而是由Swagger官方提供的一个完全模拟的REST API服务。它模拟了一个在线宠物商店的后台接口涵盖了宠物的增删改查、订单管理等完整CRUD操作。为什么适合新手零部署直接访问在线地址即可完全不用操心服务器。文档极其完善每个接口都有清晰的Swagger UI界面参数、响应体结构一目了然是学习阅读和理解API文档的最佳教材。接口覆盖全面包含了GET、POST、PUT、DELETE等各种HTTP方法以及路径参数、查询参数、请求体等多种参数传递方式。状态码丰富你可以轻松测试到200成功、404未找到、405方法不允许、500服务器错误等常见状态码。在线地址https://petstore.swagger.io/练习路径建议阶段一Postman探索打开Swagger UI用Postman手动调用所有接口。重点练习参数化Path Variable, Query Param, Body授权它支持API Key在UI里可以设置以及针对响应状态码和JSON body的断言。阶段二代码化实践使用Python的Requests库将你在Postman中成功的请求用代码实现。组织成Pytest测试用例。这里你会遇到如何管理请求头如api_key、如何解析和断言复杂的JSON响应等问题。阶段三流程与数据驱动设计一个业务流程测试。例如“新增一个宠物 - 查询该宠物信息 - 更新宠物信息 - 再次查询验证 - 删除该宠物”。并尝试使用pytest.mark.parametrize为“新增宠物”测试提供多组不同的测试数据如不同的宠物ID、名称、状态。实操心得很多新手在测Petstore时只测“成功流”。一定要刻意去测“异常流”。比如尝试用一个不存在的宠物ID去查询或删除看看返回是否符合预期404。这才是测试思维和开发思维的区别。3.2 项目二OrangeHRM 演示站点 —— 企业级Web应用UI测试沙盒项目简介OrangeHRM是一个开源的人力资源管理系统功能非常丰富。它官方提供了一个功能完整的在线演示站点账号密码公开允许你进行全方位的操作且数据会定期重置。为什么适合新手真实复杂的Web应用它有左侧导航栏、数据表格、表单、弹窗、文件上传等现代Web应用的所有典型元素练习价值远高于一个简单的登录页面。稳定的公网环境无需本地安装直接访问。功能模块清晰从管理员登录、员工信息管理、请假申请、审批流程等可以设计出非常贴近企业实际业务的端到端E2E测试流程。演示地址https://opensource-demo.orangehrmlive.com/登录账号Admin / admin123练习路径建议阶段一元素定位攻坚这是UI自动化的基础。练习使用Chrome DevTools的Inspector尝试用ID、Name、CSS Selector、XPath等多种方式定位关键元素如登录按钮、用户名输入框、表格中的特定行。记住一个原则优先级 ID Name CSS Selector XPath。尽量避免使用绝对XPath。阶段二核心流程脚本化编写脚本完成“管理员登录 - 在‘PIM’模块添加一个新员工 - 填写详细信息并保存 - 在员工列表中搜索并确认该员工添加成功”的完整流程。这会用到输入文本、点击、下拉选择、等待等核心操作。阶段三引入Page Object模式当你的线性脚本变得冗长时将其重构。将登录页面、主仪表盘页面、添加员工页面分别封装成Page Class。每个类内部包含该页面的元素定位器和操作方法如login(username, password),add_employee(first_name, last_name)。测试用例则变成调用这些页面对象方法的清晰流程。这是提升代码可维护性的关键一步。阶段四处理常见难点等待系统反应慢怎么办系统学习time.sleep硬等待尽量避免、WebDriverWaitexpected_conditions显式等待推荐的用法。文件上传练习在“添加员工”时上传头像使用send_keys(file_path)处理input typefile元素。iframe/新窗口尝试在“维护”模块下操作“技能”或“教育”等子功能可能会遇到iframe练习如何切换。3.3 项目三Sauce Demo —— 专注UI交互与状态的电商演示站项目简介一个专门为自动化测试练习设计的电商网站演示前端。它模拟了从登录、浏览商品、加入购物车、结账的完整购物流程。为什么适合新手为测试而生页面元素干净没有过多干扰且故意设置了一些“陷阱”和不同状态如错误登录信息、商品库存状态、订单完成状态非常适合练习断言和异常处理。多用户场景提供标准用户、问题用户、性能问题用户等多种登录账号可以测试不同场景下的行为。状态流转清晰购物车商品数量、价格合计、订单完成页面的信息都是练习验证点Assertion的好材料。在线地址https://www.saucedemo.com/练习账号标准用户standard_user锁定用户locked_out_user问题用户problem_user性能问题用户performance_glitch_user密码统一为secret_sauce练习路径建议基础流程自动化用标准用户完成一次完整的购物流程。重点验证登录后页面标题、商品列表加载、加入购物车后右上角购物车图标数字变化、购物车页面商品信息和价格正确、结账信息填写、订单确认页面有“THANK YOU FOR YOUR ORDER”字样。数据驱动测试使用参数化用上述不同的用户账号登录测试他们的行为。例如locked_out_user应该登录失败并看到特定的错误信息。你的脚本需要能处理这种预期内的“失败”用例。复杂断言练习在商品列表页练习获取所有商品的价格计算总和并与购物车中的合计金额进行对比。这涉及到元素列表查找、文本提取、类型转换和数值计算。排序功能测试页面有商品排序功能A to Z, Z to A, Price low to high, Price high to low。编写测试用例点击不同排序选项后验证商品列表的顺序是否符合预期。这需要你获取排序后的商品名称或价格列表并与一个预先排序好的预期列表进行比较。3.4 项目四JSONPlaceholder —— 极简的伪REST API项目简介一个免费的在线伪REST API专门用于原型设计和测试。它提供了一些常见的资源端点如/posts, /comments, /albums等。虽然它不会真正持久化你的数据POST/PUT/DELETE操作只会模拟成功返回一个假数据但响应格式和状态码是完全符合REST规范的。为什么适合新手极简没有任何认证、授权纯粹练习HTTP请求和响应处理。响应结构固定非常适合练习如何用代码如Python的json()方法解析响应JSON并提取嵌套字段进行断言。快速验证想法当你只是想测试一段请求代码或一个断言逻辑时它是完美的沙盒。在线地址https://jsonplaceholder.typicode.com/练习路径建议基础CRUD请求对/posts资源完成全套操作GET获取列表、GET获取单个帖子如/posts/1、POST创建新帖子、PUT更新帖子、DELETE删除帖子。虽然创建和更新不会真实生效但你要练习构建正确的请求体JSON格式。响应解析与断言深度练习断言。例如GET/posts/1后断言响应状态码是200断言userId字段等于1断言title字段不为空且是字符串类型。对于GET/posts?userId1断言返回的列表里每个对象的userId都是1。关联接口测试这是一个很好的练习接口间数据关联的场景。例如先GET/posts拿到第一个帖子的id然后用这个id去GET/comments?postId{id}断言获取到的评论都是属于这个帖子的。这模拟了实际业务中常见的“先查A再用A的ID查B”的场景。3.5 项目五本地部署的“待办事项”(Todo List)应用 —— 全栈练习项目简介这是一个经典的练手项目你可以找到无数前端React/Vue和后端Node.js/Python Flask/Spring Boot的实现版本。我建议你找一个技术栈简单的、能一键用Docker跑起来的全栈Todo应用。为什么适合新手环境完全可控本地部署你可以同时测试前端UI和后端接口甚至直接查看和操作数据库对理解整个应用的数据流非常有帮助。业务极其简单就是添加待办项、标记完成、删除、筛选全部/活跃/已完成。逻辑简单让你能专注于测试技术本身而不是理解复杂业务。适合搭建完整自动化测试框架你可以以此为基地搭建一个包含API测试、UI测试、并集成Allure报告、配置持续集成如GitHub Actions的“迷你”但“五脏俱全”的测试项目。如何获取在GitHub上搜索“todo app docker full stack”选择Star数多、文档清晰的。例如一些包含docker-compose.yml的项目通常只需docker-compose up -d就能在本地启动一个完整的应用。练习路径建议接口测试先行在浏览器打开前端前先用Postman或Requests库把后端提供的REST API如GET /api/todos,POST /api/todos,PUT /api/todos/:id,DELETE /api/todos/:id全部测一遍。确保核心数据逻辑是正确的。UI测试覆盖核心流编写UI自动化脚本测试前端的主要功能添加一个新待办事项并在列表中看到它勾选它标记为完成并验证其样式变化如出现删除线切换到“已完成”筛选器只看到已完成的项删除一个事项。前后端联合验证这是高级练习。通过UI操作添加一个事项后立刻调用后端GET接口检查数据库或API返回中是否确实存在这条数据且内容一致。这能帮你发现前后端数据同步的问题。搭建测试框架为这个项目建立清晰的目录结构如pages/页面对象、tests/测试用例、common/公共方法、reports/测试报告、data/测试数据。配置pytest.ini集成Allure并写一个简单的GitHub Actions工作流实现代码推送后自动运行测试并生成报告。4. 从练习到实战构建你的自动化测试脚手架完成了以上项目的练习你应该已经积累了相当的代码和信心。但单个项目的脚本是分散的接下来我们要思考如何将这些经验沉淀为一套可复用的方法论和脚手架为真正的项目做准备。4.1 设计一个可维护的测试框架结构无论项目大小一个清晰的结构是长期维护的基石。我推荐一个适用于中小型项目的目录结构your_auto_test_project/ ├── config/ # 配置文件 │ ├── __init__.py │ └── config.yaml # 存放环境URL、数据库连接、账号密码等 ├── common/ # 公共模块 │ ├── __init__.py │ ├── logger.py # 日志模块 │ ├── webdriver_helper.py # WebDriver初始化、关闭等封装 │ └── request_helper.py # 对Requests库的二次封装加日志、重试等 ├── pages/ # Page Object 目录 (UI测试) │ ├── __init__.py │ ├── base_page.py # 所有页面对象的基类封装公共方法 │ ├── login_page.py │ └── home_page.py ├── api/ # 接口层封装 (API测试) │ ├── __init__.py │ └── todo_api.py # 封装所有Todo相关的接口调用方法 ├── tests/ # 测试用例目录 │ ├── __init__.py │ ├── conftest.py # Pytest的fixture集中管理地 │ ├── test_ui/ # UI测试用例 │ │ ├── __init__.py │ │ └── test_login.py │ └── test_api/ # API测试用例 │ ├── __init__.py │ └── test_todo_crud.py ├── data/ # 测试数据 │ ├── test_data.yaml │ └── users.json ├── reports/ # 测试报告输出目录由Allure生成 ├── logs/ # 日志文件输出目录 ├── requirements.txt # Python依赖包列表 ├── pytest.ini # Pytest配置文件 └── README.md # 项目说明关键文件解释conftest.py这是Pytest的魔力所在。你可以在这里定义全局的fixture比如初始化WebDriver、登录获取Token、连接数据库等。这些fixture可以被任何测试文件使用实现资源共享和前置后置逻辑的复用。base_page.py所有页面对象的父类。里面可以封装一些每个页面都可能用到的方法比如查找元素的通用等待、截图、滚动等。子页面类继承它代码会更简洁。config.yaml使用YAML或JSON管理配置将环境信息、账号密码与代码分离。通过读取不同的配置文件如config_dev.yaml,config_prod.yaml来轻松切换测试环境。4.2 配置管理与数据驱动实践1. 配置管理不要在代码里硬编码URL和密码使用pyyaml库来读取配置文件。# config/config.yaml base: project_name: My Auto Test log_level: INFO environments: dev: base_url: https://petstore.swagger.io/v2 web_url: https://www.saucedemo.com db_host: localhost test: base_url: http://test-api.example.com web_url: http://test-ui.example.com db_host: test-db-host users: admin: username: Admin password: admin123 standard_user: username: standard_user password: secret_sauce然后在代码中通过一个配置类来加载# common/config_loader.py import yaml import os class Config: def __init__(self, envdev): config_path os.path.join(os.path.dirname(__file__), .., config, config.yaml) with open(config_path, r, encodingutf-8) as f: self.all_config yaml.safe_load(f) self.env_config self.all_config[environments][env] self.base_config self.all_config[base] def get(self, key, defaultNone): # 可以支持点分键如 get(users.admin.username) keys key.split(.) value self.all_config for k in keys: value value.get(k) if value is None: return default return value # 使用 config Config(envdev) api_url config.env_config[base_url] admin_user config.get(users.admin.username)2. 数据驱动测试使用Pytest的pytest.mark.parametrize装饰器将测试数据与测试逻辑分离。import pytest # 测试数据可以放在装饰器里 pytest.mark.parametrize(username, password, expected, [ (standard_user, secret_sauce, True), # 成功登录 (locked_out_user, secret_sauce, False), # 失败登录 (, secret_sauce, False), # 用户名为空 (standard_user, , False), # 密码为空 ]) def test_login_with_different_users(login_page, username, password, expected): login_page.login(username, password) if expected: assert login_page.is_login_successful() is True else: # 验证出现了错误提示 assert login_page.get_error_message() is not None # 或者从外部文件如JSON/YAML加载测试数据更适合大量数据 import json def load_test_data(file_path): with open(file_path, r) as f: return json.load(f) test_data load_test_data(./data/login_cases.json) pytest.mark.parametrize(case, test_data) def test_login_from_file(login_page, case): login_page.login(case[username], case[password]) # ... 根据case中的expected_result进行断言4.3 测试报告与日志让你的成果可视化1. 集成Allure生成炫酷报告首先安装Allure命令行工具和Pytest插件pip install allure-pytest。 在pytest.ini中配置[pytest] addopts -v -s --alluredir./reports/allure-results testpaths ./tests python_files test_*.py python_classes Test* python_functions test_*在测试用例中可以使用Allure装饰器添加更丰富的信息import allure import pytest allure.feature(登录模块) class TestLogin: allure.story(用户使用有效凭证登录成功) allure.title(正向用例标准用户登录) allure.severity(allure.severity_level.CRITICAL) def test_login_success(self, login_page): with allure.step(1. 打开登录页面): login_page.open() with allure.step(2. 输入用户名和密码): login_page.enter_username(standard_user) login_page.enter_password(secret_sauce) with allure.step(3. 点击登录按钮): login_page.click_login() with allure.step(4. 验证登录成功跳转到首页): assert login_page.is_login_successful() is True # 可以附加截图到报告中 allure.attach(login_page.driver.get_screenshot_as_png(), name登录成功首页截图, attachment_typeallure.attachment_type.PNG)运行测试后生成报告allure serve ./reports/allure-results。你会看到一个包含用例层级、步骤详情、截图、严重等级的HTML报告。2. 添加日志记录方便调试使用Python内置的logging模块在common/logger.py中配置import logging import os from datetime import datetime def setup_logger(nameauto_test, log_levellogging.INFO): 配置并返回一个logger实例 logger logging.getLogger(name) logger.setLevel(log_level) # 避免重复添加handler if not logger.handlers: # 控制台Handler ch logging.StreamHandler() ch.setLevel(log_level) # 文件Handler log_dir ./logs os.makedirs(log_dir, exist_okTrue) log_file os.path.join(log_dir, ftest_{datetime.now().strftime(%Y%m%d)}.log) fh logging.FileHandler(log_file, encodingutf-8) fh.setLevel(log_level) # 定义格式 formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) ch.setFormatter(formatter) fh.setFormatter(formatter) logger.addHandler(ch) logger.addHandler(fh) return logger # 在其他模块中使用 logger setup_logger() logger.info(开始执行登录测试...) try: # 一些操作 logger.debug(定位到用户名输入框) except Exception as e: logger.error(f操作发生异常: {e}, exc_infoTrue)5. 常见问题与排查技巧实录在实际练习中你一定会遇到各种报错和诡异的现象。这里我整理了一些高频问题和解决思路希望能帮你快速排雷。5.1 Web UI自动化经典“坑点”与解决方案问题1元素定位不到报 NoSuchElementException可能原因及排查页面未加载完这是最常见的原因。解决方案使用显式等待WebDriverWait。绝对避免使用time.sleep(固定秒数)。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 等待最多10秒直到元素可见 element WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.ID, username)) )元素在iframe/frame内你需要先切换到对应的frame。# 通过id或name切换 driver.switch_to.frame(frame_name_or_id) # 操作frame内的元素... # 操作完后切回主文档 driver.switch_to.default_content()元素在Shadow DOM内某些现代前端框架如某些Vue/React组件会使用Shadow DOM。Selenium需要通过execute_script来穿透。# 假设 shadow host 的id是 host1 shadow_host driver.find_element(By.ID, host1) shadow_root driver.execute_script(return arguments[0].shadowRoot, shadow_host) inner_element shadow_root.find_element(By.CSS_SELECTOR, button)定位器写错了/不唯一用浏览器开发者工具仔细核对。检查是否有重复的idCSS Selector或XPath是否唯一匹配目标元素。技巧在Chrome DevTools的Console里可以用$$(你的css选择器)或$x(你的xpath)来验证定位器是否能找到元素。问题2脚本在本地运行成功但在CI服务器如Jenkins上失败可能原因无头模式(Headless)差异CI服务器通常以无头模式运行浏览器。有些元素在无头模式下状态不同如不可见、尺寸为0。解决方案在本地也以无头模式运行测试复现问题。可以尝试增加等待时间或设置无头模式下的特定窗口大小。from selenium.webdriver.chrome.options import Options options Options() options.add_argument(--headless) # 启用无头 options.add_argument(--window-size1920,1080) # 设置窗口大小 driver webdriver.Chrome(optionsoptions)环境依赖缺失CI服务器可能缺少某些库或浏览器驱动。解决方案确保CI构建脚本中包含了安装所有依赖pip install -r requirements.txt和下载对应版本WebDriver的步骤。文件路径问题脚本中使用了绝对路径或相对于项目根目录的路径。解决方案使用os.path模块动态构建路径确保路径在任何环境下都有效。import os project_root os.path.dirname(os.path.dirname(os.path.abspath(__file__))) screenshot_path os.path.join(project_root, reports, screenshot.png)问题3操作速度太快导致动作被忽略或页面状态错乱解决方案在关键操作之间添加适当的等待但要用“智能”等待。对于点击/输入后的页面跳转或重大更新等待新页面的某个标志性元素出现。对于Ajax加载的数据等待数据加载完成的元素出现如“加载中”图标消失或数据表格的行数变化。可以封装一个“安全点击”的方法在点击后等待一小会儿。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def safe_click(driver, element, timeout10): 点击元素并等待页面可能发生的状态变化 element.click() # 这里可以添加一个通用的等待条件例如等待某个加载动画消失 # WebDriverWait(driver, timeout).until(EC.invisibility_of_element_located((By.ID, loading))) # 或者简单等待一小段时间慎用 # driver.implicitly_wait(2) # 不推荐尽量用显式等待5.2 接口自动化常见问题速查问题1接口返回403/401错误排查步骤检查认证信息是否漏传了Token、API Key、Cookie或Basic Auth头用Postman对比一下成功和失败的请求头差异。Token是否过期很多Token有有效期。实现一个Token管理机制在发起请求前检查Token是否有效若过期则自动刷新。检查请求头是否缺少必要的Header如Content-Type: application/json问题2接口响应慢或超时解决方案在Requests库中设置timeout参数避免脚本无限期等待。response requests.post(url, jsondata, timeout10) # 10秒超时考虑实现重试机制对于偶发的超时或网络波动可以自动重试几次。可以使用tenacity库优雅地实现。from tenacity import retry, stop_after_attempt, wait_fixed import requests retry(stopstop_after_attempt(3), waitwait_fixed(2)) def call_api_with_retry(url): return requests.get(url, timeout5)问题3断言复杂嵌套的JSON响应很麻烦解决方案使用jsonpath或深度比较。jsonpath像XPath定位XML一样定位JSON节点非常直观。import jsonpath response_json response.json() # 提取所有用户的姓名 usernames jsonpath.jsonpath(response_json, $..users[*].name) # 提取第一个订单的ID first_order_id jsonpath.jsonpath(response_json, $.orders[0].id)深度比较对于需要比较整个响应体结构的场景可以将预期响应体存为JSON文件然后与实际的响应体进行深度比较。import json def load_expected_json(file_path): with open(file_path, r) as f: return json.load(f) expected load_expected_json(./data/expected_order.json) actual response.json() # 使用递归或现成库如 deepdiff 进行比较 from deepdiff import DeepDiff diff DeepDiff(expected, actual, ignore_orderTrue) assert diff {}, f响应与预期不符差异为{diff}5.3 框架与执行环境问题问题Pytest用例执行顺序不符合预期用例间有依赖核心原则自动化测试用例应该是独立的、无状态的。每个用例都能单独运行且不依赖其他用例的执行结果。如果确实需要依赖如登录使用Pytest的fixture并设置scope如scopeclass或scopemodule让它在多个用例前只执行一次。import pytest pytest.fixture(scopeclass) def login_session(request): 登录并返回一个已登录的session对象供整个测试类使用 session requests.Session() # 执行登录逻辑... login_resp session.post(login_url, datacredentials) assert login_resp.status_code 200 # 将session存储在测试类中方便其他用例使用 request.cls.session session yield session # 测试类结束后可以执行登出清理 session.post(logout_url) pytest.mark.usefixtures(login_session) class TestUserProfile: # 这个类里的所有测试方法都可以使用 self.session def test_get_profile(self): resp self.session.get(profile_url) assert resp.status_code 200强制顺序不推荐万不得已可以使用pytest-ordering插件但请务必注明原因因为这违反了测试的最佳实践。最后也是最重要的心得自动化测试脚本不是一蹴而就的而是不断迭代和维护的。当你第一次为一个流程写完脚本并跑通时那只是“能用”。接下来你要思考如何让它“健壮”处理各种异常、“可读”良好的命名和结构、“可维护”易于修改和扩展和“高效”执行速度快。从这个角度看练习项目永无止境每一次重构和优化都是你能力的又一次提升。现在就从上面推荐的项目里挑一个打开你的编辑器开始写第一行代码吧。