做测试这些年,我前后经手过不下十个系统的登录功能测试,每次都会踩到新坑。很多人以为登录无非就是填用户名密码、点登录、看是否跳转,可真做起来才知道,里面有参数校验、密码加密、验证码策略、token 有效期、多端互踢、第三方授权这一堆细节。Trae 这类 AI 辅助编程工具出来之后,我最直观的感受是:自动化测试的入门门槛确实被拉低了,但对工程化的要求反而更高了。这篇文章围绕“Trae 助力自动化测试:登录功能实现全攻略”展开,分享我如何用 Trae 辅助搭建 pytest 登录自动化测试,覆盖接口层和 UI 层,连带把这些年积累的坑一起抖出来。
不管你是准备从功能测试转自动化的新手,还是已经写了多年脚本想提效的老手,这篇文章的目标都一样:让你能从零搭出一套能跑、能报、能回归的登录测试工程。我不打算堆理论,只讲怎么做、为什么这么做、哪里容易翻车。我自己日常就是 Trae 的深度用户,它的对话生成、行内补全和报错解释能力确实帮我省了大量体力活,但它同样也给我埋过雷。下面这些内容,全部来自实际项目里的真实操作,不是教科书式的流程。
1. 登录测试这个“熟面孔”,为什么值得重新用 Trae 做一遍
1.1 简单功能背后的复杂测点
登录功能往往是新项目自动化测试的第一个练兵场,原因很简单:它是所有业务系统的入口,覆盖面广,影响面大。但恰恰是这个看似简单的模块,测试点密集得惊人。我给自己带的测试同学列过一份登录功能测点清单,基本每次评审都能再补充几条。
| 测点 | 对应风险 | 测试方式 |
|---|---|---|
| 用户名密码正确性 | 核心登录链路,全部业务的基础 | 接口参数化正向用例 |
| 密码错误、空密码、超长密码 | 校验逻辑是否严谨 | 接口反例断言 |
| 验证码策略 | 不同环境差异大,测试环境最易阻塞 | 测试环境屏蔽或万能验证码 |
| token / session 有效期 | 依赖关系复杂,影响后续用例 | fixture 统一生成登录态 |
| 账号锁定、禁用、不存在 | 账号状态分支多 | 状态维度参数化 |
| 多端登录互踢 | 并发与会话覆盖逻辑 | 模拟两次登录,断言前置会话失效 |
| 第三方 OAuth 登录 | 回调地址、授权码流程繁琐 | 单独模块维护,接口打桩 |
这些测点不会均匀分布在同一个测试层级。接口层要保证后端逻辑正确,UI 层要保证真实用户操作路径能走通,两者的用例设计思路完全不同。很多团队一上来就写 UI 脚本,把每个分支都点一遍,结果浏览器一升级就全部红掉,维护成本远高于收益。所以我后来带项目,一定先压着团队把接口层的登录用例做厚,UI 层只保留冒烟用例。Trae 在这个过程中最大的价值,就是能把我脑中的用例设计快速转换成可运行的代码骨架,让我把时间留给业务判断。
1.2 Trae 在测试开发中的真实定位
Trae 是什么?简单说,它是一个懂上下文的 AI 辅助编程工具,可以对话、补全代码、解释报错,还能跨文件帮你重构。很多初次接触的同学会误以为它是“自动写测试平台”,丢一个需求进去就等着全部生成。我在实际使用三个月后,更愿意把它定位成“一个随叫随到、记性极好、但需要你审核的结对同事”。
我用 Trae 做登录测试时,最常见的三个操作习惯是:
- 把接口文档或真实抓包数据贴给 Trae,让它先生成一个可运行的请求模板,我再手动校正路径和参数。
- 让它按照 pytest 风格生成 fixture 和参数化用例骨架,然后把冗余代码删掉,只保留与业务强相关的那部分。
- 遇到 traceback 直接丢给它,请它解释报错的根因,并给出修改建议。这一步节省的时间最明显,尤其是那些网上搜不到的小众环境问题。
但注意,Trae 生成代码时有一个天然倾向:它会尽量让代码看起来完整。完整往往意味着过度设计,比如给你的函数加上不必要的一些兜底逻辑,或者顺手 mock 掉真实请求。后面我会专门讲这类问题,这里先记住一个原则:AI 生成的东西,只有经过人工理解并改造,才真正属于你的测试资产。
2. 用 Trae 搭出 pytest 登录测试工程,半天时间从零到跑通
2.1 环境准备:虚拟环境与依赖清单
先做环境。我推荐在任何项目开始之前都建独立的虚拟环境,这一步能避免很多“在我机器上能跑”的尴尬。命令非常固定,直接照抄即可。
mkdir login_test && cd login_test python -m venv venv source venv/bin/activate # Windows 用户执行 venv\Scripts\activate接下来安装依赖。登录功能自动化测试用到的库不多,我一般固定装这几个:
pip install pytest requests pytest-html pytest-ordering pyyamlpytest:测试框架,写用例和执行都用它。requests:接口层调用,登录请求就是靠它发出的。pytest-html:生成 HTML 测试报告,给团队看结果比较直观。pytest-ordering:控制用例执行顺序,UI 冒烟场景偶尔会用。pyyaml:解析 yaml 格式测试数据,方便把用例数据从代码里拆出去。
你可以把这段安装命令直接丢给 Trae,它会进一步解释每个依赖的用途,甚至帮你生成一份requirements.txt。不过我自己更习惯先装完再统一导出:
pip freeze > requirements.txt注意,如果是 Python 3.10 以下版本,requests 一般已经预装,但显式写上能让新同事克隆项目后一次装全,避免缺依赖。
2.2 目录结构:不复杂但要有边界
自动化测试工程最怕的就是所有脚本堆在同一个文件夹里。登录测试看起来只有一条路径,但后续会衍生出验证码接口、账号管理、token 刷新等功能,目录不乱,后面才加得进去。这是我比较推荐的最小可用结构:
login_test/ ├── conftest.py # 全局 fixture:登录 token、浏览器驱动 ├── pytest.ini # 配置测试路径、日志级别 ├── requirements.txt ├── common/ │ ├── __init__.py │ ├── api_client.py # 封装 requests,统一处理超时、请求头 │ ├── assert_utils.py # 分层断言工具 │ └── data_factory.py # 测试数据生成器 ├── data/ │ ├── login_cases.yaml # 接口层参数化用例数据 │ └── accounts.json # 测试账号池 └── testcase/ ├── test_login_api.py # 接口层登录用例 └── test_login_ui.py # UI 层冒烟用例很多初学者会问:为什么conftest.py要放在根目录而不是 testcase 目录下?这是因为 pytest 的 fixture 查找范围是向上递归的。放在根目录,所有子目录里的用例都能直接使用,不需要 import;如果放在 testcase 里面,就只能 testcase 下的用例使用,而 common 目录如果想要用它就会很别扭。
这个目录结构是我在 Trae 中输入“pytest 项目如何组织登录测试代码并支持 yaml 数据驱动”后得到的初稿,我再根据自己的项目习惯调整过一遍。值得说明的是,AI 生成的目录树往往偏理想化,你在实际落地时完全可以只保留需要的那部分,但conftest.py、common、data、testcase这四个目录最好不要省。
2.3 让 Trae 生成 conftest.py 登录 fixture
登录测试里最重要的 fixture 就是登录态。不管接口层还是 UI 层,都会反复用到“已经登录”的环境。一个最基础的 fixture 长这样:
import pytest import requests @pytest.fixture(scope="session") def base_url(): """测试环境基础地址,多环境时建议从环境变量读取""" return "https://test-api.example.com" @pytest.fixture(scope="session") def login_token(base_url): """执行本次会话需要的登录 token""" payload = { "username": "autotest_01", "password": "Test@123" } response = requests.post(f"{base_url}/api/login", json=payload, timeout=10) assert response.status_code == 200, f"登录失败,响应内容:{response.text}" return response.json().get("token")这是 Trae 给我的第一版,我随后做了三处改动:加了超时时间、加了失败断言信息、把return response.json()["token"]改成.get()方式。第一处防止请求挂死,第二处让失败原因一眼可见,第三处则是为了避免 KeyError 把真正的业务问题掩盖掉。
scope="session"的含义是同一个测试会话内只执行一次登录,后续所有用例共享这个 token。登录接口调用成本高,没必要每条用例都重新登录。但如果测试套件跑的时间特别长,token 会过期,这个 fixture 就会成为定时炸弹。后面我会专门讲 token 过期怎么处理。
3. 接口层的登录用例:把“成功失败排列组合”交给参数化
3.1 先从接口文档里提炼出用例矩阵
接口层的核心任务,是把登录功能的业务分支用最少的代码覆盖到。设计用例之前,先别急着写脚本,把接口文档摊开,圈出所有对外的输入和输出。我一般会直接做一个用例矩阵,然后丢给 Trae 让它照着生成代码。
假设某个系统的登录接口是POST /api/login,请求参数是username和password,响应是一个 JSON,里面包含business_code和data.token。我可以先定义这样一张表:
| 用例 ID | username | password | 预期 HTTP 状态 | 预期 business_code | 预期数据 |
|---|---|---|---|---|---|
| login_01 | autotest_01 | Test@123 | 200 | 0 | token 不为空 |
| login_02 | autotest_01 | WrongPass1 | 200 | 1001 | 错误提示存在 |
| login_03 | ghost_user | whatever | 200 | 1002 | 用户不存在 |
| login_04 | (空) | Test@123 | 400 | 2001 | 参数缺失 |
| login_05 | autotest_01 | (空) | 400 | 2002 | 参数缺失 |
| login_06 | locked_user | Test@123 | 200 | 1003 | 账号已锁定 |
| login_07 | admin#test | Test@123 | 400 | 2003 | 非法字符 |
这张表看着简单,却凝聚了登录测试最核心的边界思维:正确的能进,错误的进不去,异常参数被拦截,账号状态有分支。业务码那一列是我根据常见接口规范假设的,不同系统可能用 0 表示成功,也可能用 200,但设计思路完全一致。
拿到这张表之后,我会让 Trae 生成对应的参数化用例。Trae 的优势在这里体现得很明显:它能把表格直接变成@pytest.mark.parametrize的数据结构,省掉手写列表和字典的时间。
3.2 Trae 生成参数化用例,数据与代码分离
参数化是 pytest 里最常用的数据驱动方式。下面这段代码就是 Trae 根据我的用例矩阵生成的,我只做了少量删减:
import pytest LOGIN_CASES = [ {"id": "login_01", "username": "autotest_01", "password": "Test@123", "expect_status": 200, "expect_code": 0}, {"id": "login_02", "username": "autotest_01", "password": "WrongPass1", "expect_status": 200, "expect_code": 1001}, {"id": "login_03", "username": "ghost_user", "password": "whatever", "expect_status": 200, "expect_code": 1002}, {"id": "login_04", "username": "", "password": "Test@123", "expect_status": 400, "expect_code": 2001}, {"id": "login_05", "username": "autotest_01", "password": "", "expect_status": 400, "expect_code": 2002}, {"id": "login_06", "username": "locked_user", "password": "Test@123", "expect_status": 200, "expect_code": 1003}, {"id": "login_07", "username": "admin#test", "password": "Test@123", "expect_status": 400, "expect_code": 2003}, ] @pytest.mark.parametrize("case", LOGIN_CASES, ids=[c["id"] for c in LOGIN_CASES]) def test_login_api(base_url, case): resp = requests.post(f"{base_url}/api/login", json={"username": case["username"], "password": case["password"]}, timeout=10) assert resp.status_code == case["expect_status"] assert resp.json().get("business_code") == case["expect_code"]注意ids参数,它决定了测试报告中每一条用例显示的名字。如果不加,报告里全是test_login_api[case0]这种,看着头大。加了这个以后就会显示test_login_api[login_01],一眼就知道是哪条数据挂了。
如果你希望业务同事也能维护用例数据,可以把 LOGIN_CASES 挪到data/login_cases.yaml,用yaml.safe_load读取。好处是业务人员不需要碰 Python;坏处是 yaml 不会在编码阶段检查数据类型。我的原则是:数据量小、团队全是技术同学时,放在 Python 里更安全;数据量大、需要跨岗位协作时,用 yaml 更合适。
3.3 断言要分三层:HTTP 状态、业务码、数据完整性
很多刚写接口自动化的人,断言只写一句assert resp.status_code == 200,这是我在 code review 里见过最多的问题。登录接口尤其不能这么写,因为很多系统在账号锁定、密码错误的情况下,HTTP 状态依然返回 200,只是在business_code里做了区分。如果你只断言 HTTP 状态,那用例永远不会失败,但实际业务是失败的。
我习惯把接口断言拆成三层:
| 断言层级 | 判断对象 | 典型写法 | 作用 |
|---|---|---|---|
| 传输层 | HTTP 状态码 | resp.status_code == 200 | 确定网络链路和网关正常 |
| 业务层 | business_code | resp.json()["business_code"] == 0 | 确定业务是否真正成功 |
| 数据层 | 响应关键字段 | token 非空、长度合理 | 防止“假成功” |
三层都用上,才算一条合格的登录用例。数据层特别容易被忽略,我见过不少接口返回{"code": 0, "token": null},业务码是成功,但没有 token,后续用例拿着空 token 继续跑,最后报一堆莫名其妙的 401。这类问题就是数据层断言缺位造成的。
Trae 生成断言时,默认只会写状态码和简单的值比较。我建议在 prompt 里额外加一句:“请按 HTTP 状态、业务码、数据完整性三层设计断言”,它能生成比默认更健壮的代码。这个技巧在实际使用中非常提升生成质量。
4. UI 层的登录用例:Selenium + Trae,把“点来点去”变成可维护脚本
4.1 Web 端登录:从定位符到显式等待
接口层已经证明了登录逻辑没问题,UI 层为什么还要做?因为真实用户的路径不是发一个 JSON,而是在页面上输入、点击、跳转。前端可能的 JS 错误、按钮不可点击、弹窗遮挡,这些只有 UI 测试能发现。但 UI 测试又是最脆弱的,所以我只保留一条正向冒烟路径:正确账号能登录成功。
Selenium 是 Web 端最常用的工具,配合 Trae 生成脚本,十几分钟就能跑通。一个最基础的登录脚本如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def test_login_ui(): driver = webdriver.Chrome() try: driver.get("https://test-web.example.com/login") wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.ID, "username"))).send_keys("autotest_01") driver.find_element(By.ID, "password").send_keys("Test@123") driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click() wait.until(EC.url_contains("/dashboard")) assert "/dashboard" in driver.current_url finally: driver.quit()这段代码里有几个细节值得讲。
第一,我刻意不用time.sleep。固定等待是 UI 测试的头号维护噩梦,网络一抖动用例就挂。WebDriverWait会轮询页面状态,10 秒内只要元素出现就继续,比 sleep 稳定得多。
第二,登录成功的断言没有用截图性的 OCR 检查,而是直接判断 URL 是否跳转到/dashboard。选择这个断言是因为它是后端登录完成后前端跳转的标志,既有业务意义,又不会因为页面文案微调而误报。
第三,driver.quit()一定要放在finally里。浏览器不关,跑一轮测试下来一堆僵尸进程,CI 机器内存直接爆掉。这个我踩过不止一次。
4.2 处理登录页的三种硬骨头:验证码、弹窗、iframe
真正做登录 UI 测试时,十有八九会遇到那么一两个特别烦的元素。我这里讲最典型的三个,全都靠 Trae 辅助排查过。
验证码。测试环境最稳妥的方案是让后端提供一个“万能验证码”,或者直接在配置里关闭验证码校验。千万不要在测试脚本里去接 OCR 识别,稳定性和识别率都不靠谱,而且还会拖慢用例。如果团队坚持要在测试环境保留验证码,可以让开发开一个测试接口返回当前验证码,脚本先去调接口拿到结果,再填入页面。这一步让 Trae 生成代码并不难,prompt 就写“登录页有验证码,测试环境存在验证码获取接口,请生成先取验证码再登录的 Selenium 代码”。
弹窗。登录成功后经常弹活动公告,把后续操作按钮挡住。处理方式不是每次都去点弹窗,那太脆弱。我会在等待跳转之前,用一段 JS 把遮罩层直接移除:
driver.execute_script("document.querySelector('.modal-mask').remove()")需要先确认遮罩层的 CSS 选择器。这个办法虽然粗暴,但在冒烟用例里非常有效,能让脚本不再受前端运营位变化的影响。Trae 在帮我写这种临场处理代码时很顺手,因为在对话里描述页面结构比翻文档快得多。
iframe。部分账号体系是嵌在 iframe 里的,一开始find_element始终找不到输入框,那时才意识到需要切换上下文。Selenium 需要先switch_to.frame,定位输入框,再操作,结束后switch_to.default_content()切回来。Trae 看到iframe关键词后能直接给出切换代码,这点比较省事。
4.3 移动端登录测试的 Appium 扩展
如果你被测的登录功能在 App 里,思路和 Selenium 完全一致,只是定位方式由 CSS/ID 变成了 mobile 端的resource-id、xpath或accessibility_id。Appium 的代码结构跟 Selenium 几乎一个模子,我直接用 Trae 生成过 Android 端的登录冒烟用例,只需在启动参数里配上 App 的包名和启动 Activity 即可。
desired_caps = { "platformName": "Android", "appPackage": "com.example.app", "appActivity": ".LoginActivity", "noReset": True }noReset值得单独说明。如果设成 False,Appium 每次启动 App 都会清掉本地数据,登录状态自然也没了,每次用例都要重新走完整个登录流程。设成 True 能保留用户数据,但在真机上可能导致用例依赖上一次登录状态,断言反而会变得不稳。我建议测试团队准备一台专用的自动化测试机,noReset设 True,设备里固定放一个干净账号的登录态,这样冒烟用例跑起来又稳又快。
5. 登录自动化最值得记的五个“坑”,Trae 能帮你填但更得你判断
5.1 测试数据和线上数据混在一起
登录测试最怕的就是测试账号跑进生产环境。有人可能会说:“我测的是 test 环境,怎么会跑到生产?”但很多公司的测试环境是从生产脱敏的,账号体系却仍然连着一个公共的数据库。如果你的脚本固定使用autotest_01这个账号,跑完不清理,等下次手误连错环境,污染的就是一套真实用户数据。
我的习惯是用测试数据生成器,让每个测试账号尽可能随机:
import uuid def random_user(prefix="test"): return f"{prefix}_{uuid.uuid4().hex[:8]}"在用例中需要注册新账号时,调用random_user(),避免长期复用同一账号。在接口层测试登录功能时,如果被测系统支持预置账号,也可以在测试开始前通过后台接口批量准备数据,跑完再清理。Trae 很擅长生成这类“数据工厂”代码,但具体的清理逻辑还是要你根据系统的用户表设计去判断。
5.2 Token 和登录态过期
前文提到scope="session"的 fixture 整个测试会话只执行一次登录。如果套件里包含大量用例,跑上几个小时,token 早就过期了。我在一个接口回归套件里遇到过:前面 200 条用例全绿,到第 201 条开始全部 401。当时找了一个多小时,最后才发现 token fixture 执行一次后没有过期控制。
解决办法有两个方向。第一,在ApiClient里封装一个“请求前检查 token 有效时间”的逻辑;第二,把登录 fixture 改成function作用域,每条用例都重新登录,但这种方式比较浪费资源。我推荐折中方案:session登录一次,同时在接口请求封装里判断返回 401 时自动重新登录并重试一次。核心代码思路如下:
class ApiClient: def __init__(self, base_url, token): self.base_url = base_url self.token = token def post(self, path, json=None): resp = requests.post(self.base_url + path, headers={"Authorization": f"Bearer {self.token}"}, json=json, timeout=10) if resp.status_code == 401: new_token = refresh_login() self.token = new_token resp = requests.post(... ) # 重新发起请求 return resp这块逻辑建议让 Trae 先给一版,然后你把真实的 token 过期策略告诉它,让它把刷新逻辑补充完整。AI 的上下文理解能力在这里很有用。
5.3 断言写得太死导致误报与漏报
登录接口的响应如果是一个大 JSON,有些人图省事,直接把整个响应体当作期望值存下来,然后逐字段比对。这在接口刚上线时确实全绿,可一旦后端加了一个无关紧要的字段,比如"server_time": "2025-06-01",整条用例就红了。这种误报比漏报更打击团队信心。
正确做法是只断言业务关键字段。登录接口我用统一的三层断言,把业务码、token 是否存在、错误提示信息是否符合预期单独提取出来。至于时间戳、环境号等杂项,一律不看。Trae 默认生成的断言往往偏保守,你可以明确告诉它:“只保留与业务码、token、错误提示相关的断言,其余字段忽略”。
5.4 AI 生成代码的通病:过度 mock 或忽略依赖
Trae 能给测试写代码,但它有时会自作主张。我有一次让它生成“登录接口依赖服务不可用时的测试”,它直接在我的测试文件里引入了一个 mock 库,把登录接口给完全替换掉了。表面上看测试全绿,但真实请求根本没发出去,那次之后我就记住了:凡是用 Trae 生成的代码,先全局搜一下mock和patch这两个关键词,确认它们没有把被测接口本身 mock 掉。
另外,AI 还喜欢把 fixture 串联得很深。比如登录依赖用户注册,注册依赖验证码,验证码依赖短信平台,它可能会生成一整套嵌在一起的 mock。这在单元测试里没问题,但接口自动化测试追求的是真实链路,登录、注册、验证码都应该是真实服务,除非它是付费短信或者第三方接口,才考虑单独打桩。你要把握住一个大原则:自动化测试要测的是你的系统,不是测一个 AI 生成的模拟玩具。
5.5 登录用例的执行顺序与数据隔离
pytest 默认按文件内的定义顺序执行,很多人误以为它可以完全随机。真正危险的是用例之间产生了隐藏依赖:比如 A 用例修改了密码,B 用例还拿着旧密码去登录。这种问题在数据驱动的登录用例里特别容易出现,因为同一个数据列表里可能有多个账号、多个状态。
我的处理方式是:每条登录用例都应该是独立可执行的,不在用例内部依赖其他用例创建的账号。如果确实需要预置账号,优先放在 conftest 的 fixture 里,用函数作用域保证每次用例执行前都拿到一个干净账号。pytest-ordering 插件可以显式指定 UI 冒烟用例的先决条件,但我不建议把登录用例和账号状态用例用顺序绑定在一起,数据隔离永远比顺序编排优先。
@pytest.mark.run(order=1) def test_login_success(base_url): ... @pytest.mark.run(order=2) def test_user_lock(base_url): ...6. 把 Trae 变成团队自动化测试的“经验沉淀库”
6.1 把业务规则写成 AI 可理解的注释和规格
Trae 生成代码的质量,很大程度上取决于你给它的上下文。很多人用 AI 写测试时只说“帮我写登录测试”,然后抱怨生成的代码是模板货。真正好用的方式是把它当作一个需要完整产品背景的新同事,把接口文档、业务规则、异常分支写得越清楚,它生成的东西越靠近你的需求。
我常用的 prompt 模板是:
这是一个登录接口测试项目,pytest 框架。接口为 POST /api/login。username 必填,密码错误时 business_code 为 1001,账号锁定为 1003,参数缺失时返回 400 和业务码 2001。请根据这些规则生成参数化测试用例,并将数据放在独立 yaml 文件中。
这样的上下文,比单纯说“生成登录测试”要具体得多,Trae 生成的用例矩阵会更贴近真实业务。更重要的是,这条 prompt 本身就可以保存下来,作为团队测试设计的规格文档。后续任何人想新增登录分支,直接把新规则补进 prompt,再让 AI 生成对应用例,效率会高很多。
6.2 集成 pytest-html 报告和 CI 流水线
脚本能跑了还不够,登录测试作为回归基础,应该稳定输出报告,并且能接入 CI。pytest-html 是我用得最多的报告工具,一条命令就能生成:
pytest -v --html=report.html --self-contained-html其中--self-contained-html会把所有 CSS、JS 都打进一个 HTML 文件里,直接发给同事就能看,不用依赖网络资源。Trae 可以帮助把这个命令封装成一个run_tests.sh脚本,加上环境变量检查和失败截图逻辑。
接入 CI 后,每次代码合入前都要跑一遍登录测试。这一步通常让我写一个简单的 shell 脚本,在流水线里执行:
#!/bin/bash set -e source venv/bin/activate pytest -v --html=report.html --self-contained-html关键点是set -e,这样只要测试有失败,脚本立即退出并抛错,CI 平台才会把流水线标红。Trae 还能帮你生成不同 CI 平台用的配置文件,你只需要在对话里说明你的平台类型,它就能给出对应的 YAML 配置。这部分内容基础且重复,让 AI 代劳非常划算。
6.3 我的习惯:每解决一个 bug,就让 Trae 生成一条回归用例
最后分享一个比较个人的习惯。每次线上或测试环境出现登录相关的 bug,修复之后,我会做两件事:第一,把 bug 的根因用两句话写进测试用例的注释里;第二,把复现步骤和修复前后的接口响应贴给 Trae,让它生成一条对应的回归用例,并归入登录用例集。
这个习惯坚持下来之后,我手里的登录测试从最开始的一页用例,慢慢长成了一个贴近真实业务边界的用例库。Trae 在这个过程中扮演的角色像一个记录员:我把踩坑经验讲给它,它帮我转成标准化的 pytest 代码,我再审核、修改、合并。时间久了,团队里每个人的登录测试经验都沉淀到了同一套资产里,而不是散落在各自的聊天记录和笔记中。
登录测试永远不会是自动化测试里最炫酷的那部分,但它一定是投入产出比最高的那部分。把登录这件事做扎实,后面所有业务的自动化测试才有一个可靠的出发点。