你们产品测试团队多少人?如何分工?
接口自动化是你实现的吗?你负责哪部分?
是配置化还是要写代码?
接口之间有依赖、鉴权、token过期、隧道加密,如何设计自动化框架保证稳定?
session、token如何管理?过期如何处理?
前三个问题我按实际情况说了,但语气心虚,因为那个时候感觉不是框架核心搭建者,没有自信。后两个涉及底层机制,有概念但讲不系统。
仔细分析,这几个问题的设置是有梯度的:17-18看参与深度 → 19看抽象能力 → 20-21看是否真的懂底层。环环相扣。
现在我结合自己项目里遇到的实际场景,把这些点一个个捋清楚。当然,整理的内容部分,依旧参考了AI给我的方向,介意的话不用往下读。
一、团队分工和我的角色(17-18题)
面试官在考察什么: 你到底是框架搭建者还是用例执行者?你的自动化深度够不够?
我当时答得小心翼翼:"有专门的自动化团队搭框架,我在自己测的产品中落地"。非常不自信。
其实可以这样说:
"我们公司有专门的自动化团队负责框架核心——pytest二次封装、公共工具函数、报告模板等。我在产品线的角色是框架落地,不是简单拿过来跑。具体做了几件事:第一,根据产品接口的特点补充了对应的方法,比如我们的登录密码是前端加密传输的,框架原生不支持,我自己在Python里实现了同样的加密过程,才能调通登录接口拿token;第二,把token管理、多接口依赖传参这些产品特有的逻辑封装成fixture;第三,做了多线程优化,全量执行时间缩短了不少。"
做的每一件事都是真实的,只是之前说"落地"两个字,面试官听到的可能是"用别人现成的"——而上面这段话,面试官听到的是"我把一个通用框架适配成了一个产品能用的自动化方案"。
二、配置化还是写代码(19题)
AI分析:这个问题不是在问"你们是哪种",是在问"你知道什么时候该用哪种吗"。
| 配置化(YAML/JSON/Excel) | 写代码(Python/pytest) | |
|---|---|---|
| 怎么做 | 写配置文件描述接口和断言 | 写测试逻辑代码 |
| 门槛 | 低 | 需要编程能力 |
| 灵活度 | 简单场景够用,复杂场景兜不住 | 什么都能写 |
| 适合场景 | 简单CRUD、快速铺量 | 有依赖鉴权、加密、复杂业务链路 |
实际团队大多是“混合模式”:常规接口参数和断言走配置,鉴权、token刷新、加密这些配置表达不了的逻辑写代码兜底。
三、核心机制:token管理、接口依赖、执行顺序(20-21题)
这是五个问题里最核心的部分。我从自己项目里遇到的实际问题讲起。
3.1 登录卡在哪——密码加密
我测的项目,登录接口的密码不是明文传输。前端用加密算法处理后再发给后端。我最开始做自动化,直接跳过登录——每次手动配个token进去,token过期了再手动换。能用,但麻烦麻烦麻烦(AI吐槽我这里的自动化像个笑话...)。
后来下决心攻克:找开发问清楚加密算法和密钥,在Python里复现同样的加密过程,调通登录接口拿到token。
这一步是后面所有自动化能力的基石。登录通了,token才有来源。
3.2 token怎么管——不用等报错了再换
拿到token后,最直接的做法是每个用例开头调一次登录。但比如跑10个用例登录10次,既慢又容易被服务端限流。
用一个全局管理器,token快过期了自己去刷新:
class TokenManager:def __init__(self):self._token=Noneself._expires_at=0def get_token(self):# 每次用例来拿token,顺手看一眼时间if time.time() >self._expires_at-300: # 提前5分钟刷新self._refresh()return self._tokendef _refresh(self):"""真正去调登录接口,拿新token"""encrypted_pwd=encrypt_password("123456") # 复现前端加密resp=requests.post("/api/login",json={"username": "admin", "password": encrypted_pwd})data=resp.json()self._token=data["token"]# 记录过期时间expires_in=data.get("expires_in", 3600)self._expires_at=time.time() +expires_in
不是开两个线程在后台盯着。 就是用的时候看一眼。就像你用手机不是雇人24小时盯着电量,而是每次掏出来之前自己瞟一眼——低于20%就找充电宝,还满着就继续用。token也一样,谁要token谁触发检查,一个单线程,一条路走到底。

3.3 怎么提前知道过期时间——看token是哪种
如果是JWT(三段式,用 . 隔开):
token长这样:eyJhbGciOi...eyJ1c2VyX2lkIjo...SflKxwR...
中间那段直接解码就能看到过期时间,不用等服务端报401:
import base64, jsonpayload=token.split(".")[1] # 取中间那段payload+="="* (4-len(payload) %4) # JWT的base64要补=号data=json.loads(base64.urlsafe_b64decode(payload))print(data["exp"]) # 过期时间戳,直接拿到了
如果不是JWT(一长串乱码,不分段):
token本身不包含任何信息。只能看登录接口的返回值里有没有 expires_in 字段(单位秒),自己算:当前时间 + expires_in = 过期时间。如果接口什么都不返回,就只能兜底——收到401再重新登录。

3.4 pytest的fixture到底干了什么
fixture不是什么高深概念。经AI分析,就是我写的 do_login() 函数,pytest会自动调、自动传结果。没有fixture时,每个用例都得自己调登录,十个用例写十遍。
有fixture之后:
# scope="session" 意思是:整个测试过程只登录一次,所有用例共用@pytest.fixture(scope="session")def token():returnTokenManager().get_token()# 参数里写 token,pytest自动帮你调上面的fixture,把结果传进来def test_查询订单(token):resp=requests.get("/api/orders",headers={"Authorization": f"Bearer {token}"})assertresp.status_code==200def test_创建订单(token): # 同样,直接用,不用自己登录...
scope控制登录几次:
| scope值 | 含义 | 什么时候用 |
|---|---|---|
"function" | 每个用例都调一次(默认) | 需要完全隔离的数据 |
"class" | 一个测试类调一次 | 类内用例共享 |
"module" | 一个.py文件调一次 | 按模块隔离 |
"session" | 整个测试过程调一次 | token这种全局共用的 |
3.5 接口之间有依赖怎么办
举例——登录拿token → 创建订单拿order_id → 支付用order_id。
fixture之间可以嵌套,pytest自动按依赖关系排顺序:
@pytest.fixture(scope="session")def token():"""第一步"""return TokenManager().get_token()@pytest.fixturedef auth_headers(token):"""第二步:依赖token"""return {"Authorization": f"Bearer {token}"}@pytest.fixturedef created_order(auth_headers):"""第三步:依赖auth_headers"""resp=requests.post("/api/orders", headers=auth_headers, json={...})return resp.json()["order_id"]def test_pay(auth_headers, created_order):"""第四步:依赖前面全部"""resp=requests.post("/api/pay", headers=auth_headers,json={"order_id": created_order})assert resp.status_code==200
pytest自动排顺序: 不管代码写在前还是写在后,pytest会分析依赖链——token → auth_headers → created_order → test_pay——按这个顺序执行。你不用担心谁先谁后。

3.6 return和yield的区别
fixture里的 return 和 yield,区别只在一个地方——需不需要善后。
# return:交出去就完了(登录拿token就是这种)@pytest.fixturedef token():resp=requests.post("/api/login", json={...})return resp.json()["token"]# 到此结束,后面没有了# yield:交出去→等用例跑完→回来善后(比如关了数据库连接)@pytest.fixturedef db():conn=connect_db()yield conn# 先交出连接,等用例用完conn.close() # 回来关闭
拿token不需要善后,所以用 return 就够了。
四、隧道加密是什么
面试官问"隧道加密"的时候,我反应了一会。后来问了AI才搞懂。
像平时访问网站,HTTPS本身就是一层加密通道(传输层加密)。请求内容在传输过程中别人看不到。
面试官问的隧道加密通常更进一步——比如政务、金融系统用IPSec隧道或者国密VPN,不仅通道本身加密,传输内容的body可能还要用国密算(SM2/SM3/SM4)再加密一层。
对我们自动化框架的影响分两种:
加密在传输层:框架不感知,requests照常发
加密在应用层(body要SM4加密后才发):框架需要加一层加解密处理
这就跟做登录时"密码要SM4加密"是一个道理——只是不止密码,可能是整个请求body都要加密。
五、问题怎么答嘞
按三层递进:
第一层——角色(17-18):
"框架由自动化团队搭建,我在产品线落地。但落地不是简单执行——比如我们登录密码是前端加密的,框架原生不支持,我在Python里复现了加密过程;token管理、多接口依赖也封装成了fixture。"
第二层——实现方式(19):
"配置和代码混合。常规接口走配置减少重复,鉴权、token刷新这些复杂逻辑写代码兜底。"
第三层——底层机制(20-21):
"token管理用了一个全局管理器,每次用例取token时检查过期时间,提前5分钟自动刷新——不是后台监视线程,就是调用时看一眼。整个测试过程只登录一次,scope设为session。接口依赖通过fixture嵌套,pytest自动按依赖链编排执行顺序。"
面试官从回答里挑关键词往下追问——说fixture他就问fixture怎么用,说token他就问token怎么刷新(理想情况是这样的)。所以说的每个点,都要准备好被追一层。
这也反过来说明一件事:简历上写了的、项目讲述时主动展开的,就是面试官的提问方向。 擅长哪方面,就有意识多说几句细节,把它们变成我的主场。面试官的问题链,往往是自己递过去的话头。

答不好,不是因为没做过,是因为做过的事没整理成体系。现在回头看——做过加密登录、写过token管理、用过fixture——每件事都是对的,只是缺一个框架把它们串起来。
End.-----碎碎念-----💪
我最近不是写这场面试的问题总结,就是这家我很想去的公司。嗯,听朋友说他们又招人了,那我可以确信,确实是我面试过程中有一些问题,不是像当初hr给我的婉拒理由,说他们战略有调整,暂时不招人了,那就是不适配,无缘咯
。
所以为什么更新这么快,因为受刺激了,要继续总结才行啊,也时不时的刷boss,又开始收藏岗位了,没想到还能变相督促,加油加油继续加油。
不管拿不拿offer,都希望你心想事成!

夜雨聆风