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

新手自动化测试入门:5个精选练手项目与实战框架搭建指南

1. 项目概述:为什么新手需要从“练手项目”开始?

如果你刚接触自动化测试,面对Selenium、Postman、Appium这些工具,是不是感觉有点无从下手?看了一堆教程,感觉都懂了,但一打开IDE,手就僵住了,不知道从哪里写第一行代码。这太正常了,几乎所有测试工程师的成长路上都会遇到这个阶段。问题的核心在于,你缺少一个“靶子”——一个目标明确、结构清晰、能让你把所有知识点串联起来并动手验证的练习项目。光看理论,就像只学游泳姿势却不下水,永远学不会。

这就是为什么我强烈建议新手,在系统学习自动化测试理论之后,必须立刻、马上找一个合适的项目来练手。一个好的练手项目,能帮你把“定位元素”、“发送请求”、“断言结果”、“组织用例”这些分散的知识点,像拼图一样组合成一个完整的画面。它让你在实践中理解框架设计、数据驱动、报告生成这些概念到底有什么用,而不是停留在抽象的名词解释上。

今天,我就结合自己带新人和多年踩坑的经验,给你推荐几个精心挑选的、非常适合新手入门的接口和Web UI自动化测试练习项目。这些项目有几个共同特点:目标明确(功能不复杂)、环境简单(依赖少,容易搭建)、技术栈主流(用的都是你现在学、未来工作中也会用的工具),而且大部分都有可公开访问的在线演示环境或清晰的部署指南,让你免去搭建复杂后端服务的烦恼,能专注于测试脚本本身。

2. 练手项目核心价值与选型逻辑

在直接抛出项目列表之前,我觉得有必要先聊聊“为什么是这几个项目”。理解背后的选型逻辑,比你机械地照做更重要,这能帮助你在未来为自己或团队挑选、甚至设计测试项目时,拥有清晰的判断标准。

2.1 一个好练手项目的四大黄金准则

我总结了一个好的自动化测试练手项目,至少要满足以下四点:

  1. 功能闭环,场景真实:项目应该具备一个完整的、小规模的核心业务流程。比如一个用户从注册、登录、到完成一个核心操作(如发布内容、下单)的流程。这比单纯测试一个孤立的“登录接口”或“查询按钮”有价值得多,因为它模拟了真实的工作场景,让你思考流程衔接、状态保持(如Cookie/Session/Token)等问题。
  2. 技术栈贴合当前主流:练习使用的工具和框架,应该是行业里广泛应用的。例如,Web UI自动化用Selenium + Python/Java + Pytest/TestNG,接口测试用Postman + Newman 或 Requests库 + Pytest。避免使用过于冷门或已被淘汰的技术,确保你的练习经验能无缝迁移到实际工作中。
  3. 环境依赖少,易于搭建:理想情况是存在稳定的公网测试环境。如果必须本地部署,那么项目应该提供清晰的Docker Compose文件或一键部署脚本。新手最大的拦路虎之一就是环境问题,一个搞不定的环境足以浇灭所有热情。我们的目标是练习“测试”,而不是练习“部署运维”。
  4. 有可供验证的预期结果:你需要清楚地知道,当你执行了某个操作后,系统“应该”返回什么。这意味着项目要么有详细的接口文档,要么前端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/
  • 练习路径建议
    1. 阶段一(Postman探索):打开Swagger UI,用Postman手动调用所有接口。重点练习:参数化(Path Variable, Query Param, Body),授权(它支持API Key,在UI里可以设置),以及针对响应状态码和JSON body的断言。
    2. 阶段二(代码化实践):使用Python的Requests库,将你在Postman中成功的请求用代码实现。组织成Pytest测试用例。这里你会遇到如何管理请求头(如api_key)、如何解析和断言复杂的JSON响应等问题。
    3. 阶段三(流程与数据驱动):设计一个业务流程测试。例如:“新增一个宠物 -> 查询该宠物信息 -> 更新宠物信息 -> 再次查询验证 -> 删除该宠物”。并尝试使用@pytest.mark.parametrize为“新增宠物”测试提供多组不同的测试数据(如不同的宠物ID、名称、状态)。

实操心得:很多新手在测Petstore时,只测“成功流”。一定要刻意去测“异常流”。比如,尝试用一个不存在的宠物ID去查询或删除,看看返回是否符合预期(404)。这才是测试思维和开发思维的区别。

3.2 项目二:OrangeHRM 演示站点 —— 企业级Web应用UI测试沙盒

  • 项目简介:OrangeHRM是一个开源的人力资源管理系统,功能非常丰富。它官方提供了一个功能完整的在线演示站点,账号密码公开,允许你进行全方位的操作,且数据会定期重置。
  • 为什么适合新手
    • 真实复杂的Web应用:它有左侧导航栏、数据表格、表单、弹窗、文件上传等现代Web应用的所有典型元素,练习价值远高于一个简单的登录页面。
    • 稳定的公网环境:无需本地安装,直接访问。
    • 功能模块清晰:从管理员登录、员工信息管理、请假申请、审批流程等,可以设计出非常贴近企业实际业务的端到端(E2E)测试流程。
  • 演示地址https://opensource-demo.orangehrmlive.com/
  • 登录账号:Admin / admin123
  • 练习路径建议
    1. 阶段一(元素定位攻坚):这是UI自动化的基础。练习使用Chrome DevTools的Inspector,尝试用ID、Name、CSS Selector、XPath等多种方式定位关键元素,如登录按钮、用户名输入框、表格中的特定行。记住一个原则:优先级 ID > Name > CSS Selector > XPath。尽量避免使用绝对XPath。
    2. 阶段二(核心流程脚本化):编写脚本完成“管理员登录 -> 在‘PIM’模块添加一个新员工 -> 填写详细信息并保存 -> 在员工列表中搜索并确认该员工添加成功”的完整流程。这会用到输入文本、点击、下拉选择、等待等核心操作。
    3. 阶段三(引入Page Object模式):当你的线性脚本变得冗长时,将其重构。将登录页面、主仪表盘页面、添加员工页面分别封装成Page Class。每个类内部包含该页面的元素定位器和操作方法(如login(username, password),add_employee(first_name, last_name))。测试用例则变成调用这些页面对象方法的清晰流程。这是提升代码可维护性的关键一步。
    4. 阶段四(处理常见难点)
      • 等待:系统反应慢怎么办?系统学习time.sleep(硬等待,尽量避免)、WebDriverWait+expected_conditions(显式等待,推荐)的用法。
      • 文件上传:练习在“添加员工”时上传头像,使用send_keys(file_path)处理<input type="file">元素。
      • iframe/新窗口:尝试在“维护”模块下操作“技能”或“教育”等子功能,可能会遇到iframe,练习如何切换。

3.3 项目三:Sauce Demo —— 专注UI交互与状态的电商演示站

  • 项目简介:一个专门为自动化测试练习设计的电商网站演示前端。它模拟了从登录、浏览商品、加入购物车、结账的完整购物流程。
  • 为什么适合新手
    • 为测试而生:页面元素干净,没有过多干扰,且故意设置了一些“陷阱”和不同状态(如错误登录信息、商品库存状态、订单完成状态),非常适合练习断言和异常处理。
    • 多用户场景:提供标准用户、问题用户、性能问题用户等多种登录账号,可以测试不同场景下的行为。
    • 状态流转清晰:购物车商品数量、价格合计、订单完成页面的信息,都是练习验证点(Assertion)的好材料。
  • 在线地址https://www.saucedemo.com/
  • 练习账号
    • 标准用户:standard_user
    • 锁定用户:locked_out_user
    • 问题用户:problem_user
    • 性能问题用户:performance_glitch_user
    • 密码统一为:secret_sauce
  • 练习路径建议
    1. 基础流程自动化:用标准用户完成一次完整的购物流程。重点验证:登录后页面标题、商品列表加载、加入购物车后右上角购物车图标数字变化、购物车页面商品信息和价格正确、结账信息填写、订单确认页面有“THANK YOU FOR YOUR ORDER”字样。
    2. 数据驱动测试:使用参数化,用上述不同的用户账号登录,测试他们的行为。例如,locked_out_user应该登录失败,并看到特定的错误信息。你的脚本需要能处理这种预期内的“失败”用例。
    3. 复杂断言练习:在商品列表页,练习获取所有商品的价格,计算总和,并与购物车中的合计金额进行对比。这涉及到元素列表查找、文本提取、类型转换和数值计算。
    4. 排序功能测试:页面有商品排序功能(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/
  • 练习路径建议
    1. 基础CRUD请求:对/posts资源完成全套操作:GET获取列表、GET获取单个帖子(如/posts/1)、POST创建新帖子、PUT更新帖子、DELETE删除帖子。虽然创建和更新不会真实生效,但你要练习构建正确的请求体(JSON格式)。
    2. 响应解析与断言:深度练习断言。例如,GET/posts/1后,断言响应状态码是200,断言userId字段等于1,断言title字段不为空且是字符串类型。对于GET/posts?userId=1,断言返回的列表里每个对象的userId都是1。
    3. 关联接口测试:这是一个很好的练习接口间数据关联的场景。例如,先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就能在本地启动一个完整的应用。
  • 练习路径建议
    1. 接口测试先行:在浏览器打开前端前,先用Postman或Requests库,把后端提供的REST API(如GET /api/todos,POST /api/todos,PUT /api/todos/:id,DELETE /api/todos/:id)全部测一遍。确保核心数据逻辑是正确的。
    2. UI测试覆盖核心流:编写UI自动化脚本,测试前端的主要功能:添加一个新待办事项,并在列表中看到它;勾选它标记为完成,并验证其样式变化(如出现删除线);切换到“已完成”筛选器,只看到已完成的项;删除一个事项。
    3. 前后端联合验证:这是高级练习。通过UI操作添加一个事项后,立刻调用后端GET接口,检查数据库(或API返回)中是否确实存在这条数据,且内容一致。这能帮你发现前后端数据同步的问题。
    4. 搭建测试框架:为这个项目建立清晰的目录结构,如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, env='dev'): config_path = os.path.join(os.path.dirname(__file__), '..', 'config', 'config.yaml') with open(config_path, 'r', encoding='utf-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, default=None): # 可以支持点分键,如 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(env='dev') 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_type=allure.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(name='auto_test', log_level=logging.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_ok=True) log_file = os.path.join(log_dir, f'test_{datetime.now().strftime("%Y%m%d")}.log') fh = logging.FileHandler(log_file, encoding='utf-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_info=True)

5. 常见问题与排查技巧实录

在实际练习中,你一定会遇到各种报错和诡异的现象。这里我整理了一些高频问题和解决思路,希望能帮你快速排雷。

5.1 Web UI自动化经典“坑点”与解决方案

问题1:元素定位不到,报 NoSuchElementException

  • 可能原因及排查
    1. 页面未加载完:这是最常见的原因。解决方案:使用显式等待(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")) )
    2. 元素在iframe/frame内:你需要先切换到对应的frame。
      # 通过id或name切换 driver.switch_to.frame("frame_name_or_id") # 操作frame内的元素... # 操作完后切回主文档 driver.switch_to.default_content()
    3. 元素在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')
    4. 定位器写错了/不唯一:用浏览器开发者工具仔细核对。检查是否有重复的id,CSS Selector或XPath是否唯一匹配目标元素。技巧:在Chrome DevTools的Console里,可以用$$("你的css选择器")$x("你的xpath")来验证定位器是否能找到元素。

问题2:脚本在本地运行成功,但在CI服务器(如Jenkins)上失败

  • 可能原因
    1. 无头模式(Headless)差异:CI服务器通常以无头模式运行浏览器。有些元素在无头模式下状态不同(如不可见、尺寸为0)。解决方案:在本地也以无头模式运行测试,复现问题。可以尝试增加等待时间,或设置无头模式下的特定窗口大小。
      from selenium.webdriver.chrome.options import Options options = Options() options.add_argument('--headless') # 启用无头 options.add_argument('--window-size=1920,1080') # 设置窗口大小 driver = webdriver.Chrome(options=options)
    2. 环境依赖缺失:CI服务器可能缺少某些库或浏览器驱动。解决方案:确保CI构建脚本中包含了安装所有依赖(pip install -r requirements.txt)和下载对应版本WebDriver的步骤。
    3. 文件路径问题:脚本中使用了绝对路径或相对于项目根目录的路径。解决方案:使用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:操作速度太快,导致动作被忽略或页面状态错乱

  • 解决方案:在关键操作之间添加适当的等待,但要用“智能”等待。
    1. 对于点击/输入后的页面跳转或重大更新,等待新页面的某个标志性元素出现。
    2. 对于Ajax加载的数据,等待数据加载完成的元素出现(如“加载中”图标消失,或数据表格的行数变化)。
    3. 可以封装一个“安全点击”的方法,在点击后等待一小会儿。
      from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def safe_click(driver, element, timeout=10): """点击元素,并等待页面可能发生的状态变化""" element.click() # 这里可以添加一个通用的等待条件,例如等待某个加载动画消失 # WebDriverWait(driver, timeout).until(EC.invisibility_of_element_located((By.ID, "loading"))) # 或者简单等待一小段时间(慎用) # driver.implicitly_wait(2) # 不推荐,尽量用显式等待

5.2 接口自动化常见问题速查

问题1:接口返回403/401错误

  • 排查步骤
    1. 检查认证信息:是否漏传了Token、API Key、Cookie或Basic Auth头?用Postman对比一下成功和失败的请求头差异。
    2. Token是否过期:很多Token有有效期。实现一个Token管理机制,在发起请求前检查Token是否有效,若过期则自动刷新。
    3. 检查请求头:是否缺少必要的Header,如Content-Type: application/json

问题2:接口响应慢或超时

  • 解决方案
    1. 在Requests库中设置timeout参数,避免脚本无限期等待。
      response = requests.post(url, json=data, timeout=10) # 10秒超时
    2. 考虑实现重试机制,对于偶发的超时或网络波动,可以自动重试几次。可以使用tenacity库优雅地实现。
      from tenacity import retry, stop_after_attempt, wait_fixed import requests @retry(stop=stop_after_attempt(3), wait=wait_fixed(2)) def call_api_with_retry(url): return requests.get(url, timeout=5)

问题3:断言复杂嵌套的JSON响应很麻烦

  • 解决方案:使用jsonpath或深度比较。
    1. 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')
    2. 深度比较:对于需要比较整个响应体结构的场景,可以将预期响应体存为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_order=True) assert diff == {}, f"响应与预期不符,差异为:{diff}"

5.3 框架与执行环境问题

问题:Pytest用例执行顺序不符合预期,用例间有依赖

  • 核心原则:自动化测试用例应该是独立的、无状态的。每个用例都能单独运行,且不依赖其他用例的执行结果。
  • 如果确实需要依赖(如登录):使用Pytest的fixture,并设置scope(如scope="class"scope="module"),让它在多个用例前只执行一次。
    import pytest @pytest.fixture(scope="class") def login_session(request): """登录并返回一个已登录的session对象,供整个测试类使用""" session = requests.Session() # 执行登录逻辑... login_resp = session.post(login_url, data=credentials) 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插件,但请务必注明原因,因为这违反了测试的最佳实践。

最后,也是最重要的心得:自动化测试脚本不是一蹴而就的,而是不断迭代和维护的。当你第一次为一个流程写完脚本并跑通时,那只是“能用”。接下来,你要思考如何让它“健壮”(处理各种异常)、“可读”(良好的命名和结构)、“可维护”(易于修改和扩展)和“高效”(执行速度快)。从这个角度看,练习项目永无止境,每一次重构和优化,都是你能力的又一次提升。现在,就从上面推荐的项目里挑一个,打开你的编辑器,开始写第一行代码吧。

http://www.gsyq.cn/news/1610326.html

相关文章:

  • 如何快速检测微信单向好友:5分钟找出谁删除了你
  • Windows 11终极清理指南:5分钟让电脑重获新生
  • 影刀RPA新手教程:大众点评数据采集完全指南——店铺信息、用户评价与竞争对手分析
  • 影刀RPA新手教程:列表完全指南——什么是列表、怎么往里加东西、怎么取出来
  • 告别CMAC!NIST SP800-108新版密钥派生实战:手把手教你用KMAC128/256
  • 【公共云三十问 之一】什么是公共云?
  • 终极指南:Destiny 2 Solo Enabler端口配置完全掌控
  • 告别LED闪烁:用串口助手和printf()给你的51单片机代码做个“体检”
  • MySQL数据分析入门:从零搭建环境到电商实战案例
  • 保姆级教程:用SigmaStudio配置A2B数字麦克风(AD2428WD-EVB主控,AD2428WC-EVB从板)
  • SENAITE LIMS:实现实验室数字化转型的智能解决方案
  • 从零到一:Hermes Agent私有化部署与自定义技能开发实战
  • 用过 5 个 AI 写论文才发现:笔墨 AI 才是真的适配高校学术规范
  • 影刀RPA新手教程:变量未定义报错完全指南——为什么说变量不存在
  • JPEXS Free Flash Decompiler终极指南:解锁Flash逆向工程的完整工具链
  • 影刀RPA新手教程:子流程复用完全指南——一个子流程在10个地方调用
  • 向量检索 Retrieval:Scoring(打分) + Chunk Overlap(块重叠)完整讲解
  • 深度解析CXPatcher:CrossOver依赖升级与兼容性增强技术
  • YOLOv8性能优化实战:从1.2FPS到35FPS的全链路加速方案
  • 终极BetterJoy使用指南:让Switch手柄在PC上完美运行的3个关键步骤
  • MySQL数据分析实战:从零掌握SQL核心技能,完成电商销售分析
  • 工业LED驱动模块电源技术选型参考:钡特 NCD24-1000 与 KC24H-1000R3 硬件设计适配解析丨-1200丨-700丨国产化丨DC-DC
  • 【2027最新】基于SpringBoot+Vue的全家桶pc端仿淘宝系统管理系统源码+MyBatis+MySQL
  • SRC漏洞挖掘实战指南:从零入门到精通,掌握合法渗透测试核心技能
  • AI模型测试实战指南:从原理到部署的测试工程师视角
  • AI 电动香薰蜡烛智能功率 MOSFET 精准选型方案
  • MediaCrawler:5分钟快速上手多平台数据采集爬虫框架
  • 从零构建AI应用:Dify工作流与智能体实战指南
  • Doris集群Docker部署实战:解决FE/BE节点注册与网络配置难题
  • Vue巨树组件完整解决方案:突破海量数据渲染瓶颈的终极指南