第一次接触接口自动化测试时,我发现很多需要登录状态的接口总是返回"请先登录"的提示。经过反复尝试,终于理解了Session会话保持这个关键技术点。Session机制就像我们去银行办理业务:第一次去要出示身份证(登录),银行会给我们一个号码牌(Session ID),之后办理其他业务时只需出示这个号码牌,无需重复验证身份。
Session的完整生命周期包含三个阶段:
python复制import requests
session = requests.Session() # 创建新的Session对象
活跃阶段:客户端在后续请求中会自动携带这个Session ID。服务器通过ID找到对应的Session对象,实现状态保持。这就像我们在网站登录后,可以自由浏览其他页面而无需重复登录。
销毁阶段:当发生以下情况时Session会终止:
虽然Session和Cookie都能保持用户状态,但它们的实现机制有本质区别:
| 特性 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端浏览器 | 服务端内存/数据库 |
| 安全性 | 较低(可被修改) | 较高(服务端控制) |
| 容量限制 | 单个域名下约4KB | 理论上只受服务器内存限制 |
| 生命周期 | 可设置长期有效 | 通常随浏览器关闭而失效 |
| 性能影响 | 每次请求自动携带 | 需要服务端查找Session对象 |
提示:实际项目中,Session的安全性更高,适合存储敏感信息如用户ID、权限等;而Cookie适合存储非敏感且需要长期保存的数据。
在开始前需要准备:
建议使用虚拟环境:
bash复制python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
pip install requests
code复制_coderpeak_session=xxxx; _testerhome_session=yyyy; remember_token=zzzz
python复制import requests
# 准备请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Cookie": "_coderpeak_session=xxxx; remember_token=zzzz"
}
# 创建Session对象
session = requests.Session()
# 首次请求更新Session
home_url = "https://testerhome.com/"
response = session.get(home_url, headers=headers)
# 验证是否登录成功
if "退出登录" in response.text:
print("Session初始化成功!")
else:
print("登录状态异常,请检查Cookie")
python复制# 获取个人通知
notify_url = "https://testerhome.com/notifications/personal"
notify_res = session.get(notify_url).json()
print(f"未读通知数:{notify_res['unread_count']}")
# 获取个人信息
setting_url = "https://testerhome.com/setting"
setting_res = session.get(setting_url)
print(setting_res.text)
问题1:Session突然失效
问题2:返回403禁止访问
python复制headers["Referer"] = "https://testerhome.com/"
问题3:登录成功但获取不到数据
对于需要长期运行的测试脚本,建议实现Session自动续期:
python复制class AutoSession:
def __init__(self):
self.session = requests.Session()
self.last_activity = time.time()
def get(self, url, headers=None):
# 超过30分钟自动更新Session
if time.time() - self.last_activity > 1800:
self.renew_session()
self.last_activity = time.time()
return self.session.get(url, headers=headers)
def renew_session(self):
login_url = "https://testerhome.com/login"
data = {"username": "your_id", "password": "your_pwd"}
self.session.post(login_url, data=data)
当需要模拟多个用户时,可以使用Session池:
python复制from threading import Lock
class SessionPool:
def __init__(self):
self.pool = {}
self.lock = Lock()
def get_session(self, user):
with self.lock:
if user not in self.pool:
session = requests.Session()
# 初始化登录逻辑
self.pool[user] = session
return self.pool[user]
python复制session.get(url, timeout=(3.05, 27)) # 连接超时3.05秒,读取超时27秒
python复制import os
cookie = os.getenv('TESTERHOME_COOKIE')
python复制session = requests.Session()
session.mount('https://', requests.adapters.HTTPAdapter(
max_retries=3,
ssl_version=ssl.PROTOCOL_TLSv1_2
))
python复制# 测试完成后主动关闭Session
try:
# 测试代码...
finally:
session.close()
模拟用户完整购物流程:
python复制def test_purchase_flow():
# 1. 登录
session = login(username, password)
# 2. 浏览商品
products = session.get("/api/products").json()
# 3. 加入购物车
cart_res = session.post("/api/cart", json={"product_id": 123})
# 4. 结算订单
order_res = session.post("/api/orders", json={"address_id": 1})
# 5. 验证结果
assert order_res.status_code == 200
将Session管理集成到测试框架中:
python复制import pytest
@pytest.fixture(scope="module")
def auth_session():
session = requests.Session()
yield session
session.close()
def test_user_profile(auth_session):
res = auth_session.get("/api/user/profile")
assert res.json()["username"] == "test_user"
使用Session模拟真实用户行为:
python复制from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 5)
def on_start(self):
# 每个虚拟用户先登录
self.client.post("/login", {
"username": "test",
"password": "123456"
})
@task
def view_profile(self):
self.client.get("/profile")
当Session不生效时,可以按以下步骤排查:
python复制print(session.headers)
python复制resp = session.get(url, allow_redirects=False)
print(resp.status_code, resp.headers['Location'])
python复制import logging
import http.client
http.client.HTTPConnection.debuglevel = 1
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
我在实际项目中遇到过最棘手的问题是某些网站会检测Session的生成方式。解决方案是模拟完整的浏览器指纹:
python复制headers = {
"Accept-Language": "zh-CN,zh;q=0.9",
"Sec-Ch-Ua": '"Chromium";v="104"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "Windows",
}
记住,Session保持是接口自动化测试的基础技能,但不同网站的实现方式可能千差万别。关键是要理解原理,然后灵活应对各种实际情况。