刚开始学 Python 的时候,我特别困惑:循环、字典、函数、异常捕获......这些到底跟测试有什么关系?
直到我把每个知识点都跟接口测试挂上钩,才发现------原来我学的每一样东西,都是在为写接口自动化脚本做准备。
一、为什么测试要学 Python?
先把结论放前面:Python 是写接口自动化测试脚本的首选语言。
为什么不是 Java?因为 Python 语法简单、上手快,而且有 requests、pytest 这些非常成熟的测试库,写接口测试脚本效率极高。
那 Python 基础语法里,哪些跟测试直接相关?我总结了下,主要是三大块:
| 知识块 | 在测试中的作用 |
|---|---|
| 字典 | 接口请求体(JSON数据)的载体 |
| 函数 | 封装重复操作 + 断言结果 |
| 异常捕获 | 保证脚本遇到问题时不会整个崩掉 |
二、字典:接口测试数据的载体
2.1 为什么字典这么重要?
接口测试发的请求体通常是 JSON 格式,比如:
{"username": "admin", "password": "123456"}
而在 Python 里,这个 JSON 对应的数据类型就是字典。所以字典学得好不好,直接决定你能不能构造出正确的请求数据。
2.2 字典的基本操作
# 创建字典
dict1 = {'name': '张三', 'age': 18}
# 修改值
dict1['name'] = "李四"
# 新增元素
dict1['sex'] = "男"
# 删除元素
dict1.pop("name")
# 查询元素(推荐用 get,键不存在时不会报错)
dict1.get("age") # 返回 18
dict1.get("phone") # 返回 None(不会报错)
# dict1["phone"] # 会直接报错 KeyError
💡 测试视角 :
get()比[]安全。写测试脚本时,如果字段不存在,get()返回None不会让脚本崩溃,但[]会直接报错终止。
2.3 字典的遍历
dict1 = {"name": "张三", "age": 18}
# 遍历键
for k in dict1:
print(k)
# 遍历值
for v in dict1.values():
print(v)
# 遍历键值对
for k, v in dict1.items():
print(k, v)
💡 测试视角 :遍历在接口测试中常用于检查响应体。接口返回一大坨 JSON,你需要遍历它,看里面有没有你期望的字段和值。
2.4 列表嵌套字典
这是我认为最接近接口自动化测试形态的一段代码:
# 定义测试数据:列表里嵌套字典
test_data = [
{"username": "13488888888", "password": "123456"},
{"username": "", "password": "123456"},
{"username": "13488888881", "password": "1234"}
]
# 遍历数据,逐条校验
for i in test_data:
if i.get("username") == "13488888888" and i.get("password") == "123456":
print("登录成功")
else:
print("账号或密码错误")
💡 测试视角 :这就是数据驱动测试的雏形。你把所有测试数据放在一个列表里,循环让代码自动跑每一组数据,再判断结果------这已经是一个接口自动化测试的核心逻辑了。
2.5 从键盘动态构造测试数据
login_data = []
num = 5
for i in range(num):
username = input("请输入手机号:")
password = input("请输入密码:")
code = input("请输入验证码:")
data = {"username": username, "password": password, "code": code}
login_data.append(data)
print(login_data)
💡 测试视角 :这段代码展示了动态构造测试数据 的过程。实际测试中,你可以把
input()换成从 Excel 或 CSV 文件读取数据,实现更强大的数据驱动。
三、函数:封装重复操作 + 断言结果
3.1 什么是函数?
函数就是把一段会重复使用的代码包起来,给它起个名字,以后直接用名字调用就行。
# 定义函数
def demo1(phone):
"""手机号判断的函数"""
if phone == "13488888888":
print("账号成功")
else:
print("账号错误")
# 调用函数
demo1("13488888888") # 输出:账号成功
demo1("13488888889") # 输出:账号错误
💡 测试视角 :实际测试中,你可以把登录操作封装成一个
login()函数。以后每个测试用例直接调用login(),不需要重复写输入框、点击按钮的代码。
3.2 带返回值的函数
def demo1(phone):
if phone == "13488888888":
return "账号成功"
else:
return "账号错误"
# 调用函数并接收返回值
result = demo1("13488888888")
print(result)
💡 测试视角 :这是接口测试的核心逻辑!
在接口测试脚本里,你的函数会发送 HTTP 请求,然后
return response。外部拿到返回值后,用assert判断状态码是不是 200,不是就说明测试失败。python
def login(username, password): response = requests.post(url, json={"username": username, "password": password}) return response # 断言 result = login("admin", "123456") assert result.status_code == 200, "接口状态码不是200"这就是"自动判断测试结果"的核心逻辑。
四、异常捕获:保证脚本不崩
4.1 什么是异常捕获?
简单说就是:程序出错了,不要直接崩溃,而是优雅地处理一下再继续跑。
try:
num = int(input("请输入数据:"))
print(num)
except:
print("请输入正确数据")
💡 测试视角 :发接口请求时,可能会遇到断网、超时、服务器返回乱码等情况。如果不加
try,脚本直接红字报错崩溃,后面的用例全部停止。
4.2 捕获特定异常 + finally
try:
num = int(input("请输入整数:"))
result = 8 / num
print(result)
except ZeroDivisionError:
print("除数不能为0")
except ValueError:
print("请输入整数")
except Exception as e:
print(f"异常信息是:{e}")
finally:
print("xx进程关闭,程序执行结束")
| 关键字 | 作用 |
|---|---|
try |
尝试执行的代码 |
except ZeroDivisionError |
捕获特定异常(除零) |
except ValueError |
捕获特定异常(类型错误) |
except Exception as e |
兜底,捕获所有异常并打印信息 |
finally |
无论是否异常,最后都执行 |
💡 测试视角 :
finally非常实用。比如你打开了浏览器做 UI 自动化,不管测试用例成功还是失败,最后都要关闭浏览器------这个"关闭浏览器"就放在finally里。
4.3 主动抛异常
def input_password():
password = input("请输入密码:")
if len(password) < 8:
ex = Exception("密码长度不够8位")
raise ex
else:
return password
if __name__ == '__main__':
try:
print(input_password())
except Exception as e:
print(f"异常信息为:{e}")
💡 测试视角 :写测试用例时,如果数据校验失败(比如手机号是10位不是11位),可以主动
raise Exception("手机号格式不对,测试终止")。这叫"断言失败主动抛出错误",能让问题更清晰地暴露出来。
五、接口测试预演:把学到的串起来
假设现在有一个登录接口,我把上面学的字典、函数、异常捕获全部串起来写一个最简单的测试脚本:
import requests
def login(username, password):
"""发送登录请求,返回响应"""
try:
url = "https://reqres.in/api/login"
data = {"email": username, "password": password} # 字典构造请求数据
response = requests.post(url, json=data)
return response
except Exception as e:
print(f"请求失败:{e}")
return None
# 测试数据
test_cases = [
{"email": "eve.holt@reqres.in", "password": "cityslicka"},
{"email": "", "password": ""}
]
# 循环执行
for case in test_cases:
result = login(case["email"], case["password"]) # 函数封装
if result is not None:
assert result.status_code == 200, f"接口失败,状态码:{result.status_code}" # 断言
print("测试通过")
⚠️ 注意 :上面的脚本有个我踩过的坑------反向用例(空邮箱空密码)接口会返回 400,但代码写死了
assert == 200,跑到第二个用例就崩了。修复方式:给每条测试数据加上
expected字段,断言时用assert result.status_code == case["expected"]。不要把预期结果写死在代码里,这是数据驱动测试的基本意识。
test_cases = [
{"email": "eve.holt@reqres.in", "password": "cityslicka", "expected": 200},
{"email": "", "password": "", "expected": 400}
]
for case in test_cases:
result = login(case["email"], case["password"])
if result is not None:
assert result.status_code == case["expected"], \
f"预期{case['expected']},实际{result.status_code}"
print(f"测试通过,状态码:{result.status_code}")
💡 这段代码看起来简单,但里面的每一个部分,都对应我们前面学的知识点:
代码部分 对应知识点 {"email": ..., "password": ...}字典(请求数据载体) def login()函数(封装操作) return response带返回值的函数(拿结果做断言) try / except异常捕获(防止脚本崩) assert断言(自动判断测试结果) for case in test_cases列表嵌套字典(数据驱动)
六、Python接口测试核心语法速查卡
| 知识点 | 核心语法 | 测试用途 |
|---|---|---|
| 字典创建 | data = {"key": "value"} |
构造请求数据 |
| 字典取值 | data.get("key") |
安全取响应字段 |
| 字典遍历 | for k, v in data.items() |
遍历响应数据 |
| 列表嵌套字典 | [{"key": "value"}, ...] |
数据驱动测试 |
| 函数定义 | def func(): |
封装登录、请求等操作 |
| 函数返回 | return result |
拿响应结果做断言 |
| 断言 | assert 条件, "提示" |
自动判断测试是否通过 |
| 异常捕获 | try...except...finally |
防止脚本崩溃 |
| 主动抛异常 | raise Exception("信息") |
断言失败主动报错 |