Python基础面试题:语言定位+数据类型+核心操作+算法实战
- 前言
- [一、 Python 语言定位:为什么测试岗必须学?](#一、 Python 语言定位:为什么测试岗必须学?)
- [二、 Python 数据类型:可变类型与不可变类型完整梳理](#二、 Python 数据类型:可变类型与不可变类型完整梳理)
- [三、 循环与条件:测试用例执行核心逻辑](#三、 循环与条件:测试用例执行核心逻辑)
-
- [(1)for 循环 vs while 循环(区别 + 测试场景选择)](#(1)for 循环 vs while 循环(区别 + 测试场景选择))
- [(2) 九九乘法表(循环嵌套基础 + 测试报告格式化)](#(2) 九九乘法表(循环嵌套基础 + 测试报告格式化))
- [(3)金字塔图案(循环嵌套 + 测试数据可视化)](#(3)金字塔图案(循环嵌套 + 测试数据可视化))
- [四、 排序算法:测试数据处理](#四、 排序算法:测试数据处理)
-
- (1)冒泡排序
- [(2)内置排序函数:sorted ()(测试场景首选)](#(2)内置排序函数:sorted ()(测试场景首选))
- 五、类与函数:测试脚本模块化核心
-
- (1)函数:测试用例复用基础
- [(2)类:测试框架 / 工具封装核心](#(2)类:测试框架 / 工具封装核心)
- (3)函数与类的区别
- [六、 测试岗 Python 面试易错点总结](#六、 测试岗 Python 面试易错点总结)
前言
Python 凭借简洁语法、丰富库生态、跨平台特性,成为软件测试工程师的首选语言 ------ 自动化测试(Selenium/Appium)、接口测试(Requests)、性能测试(Locust)、测试数据生成等场景均高频使用。本文从测试岗实际需求出发,系统整理 Python 核心知识点,覆盖语言定位、数据类型、常用操作、循环算法、类与函数。
一、 Python 语言定位:为什么测试岗必须学?
1. 语言地位
-
跨平台:支持 Windows/Mac/Linux,适配测试环境多样化需求
-
语法友好:代码简洁易读,开发效率高(测试脚本快速迭代)
-
库生态完善:测试相关库丰富(Requests、Selenium、Pytest、JsonPath 等)
-
应用场景广:覆盖功能测试、接口测试、自动化测试、性能测试、测试数据分析全流程
2. 测试岗核心应用场景
| 应用方向 | 代表库 / 工具 | 核心用途 |
|---|---|---|
| 接口测试 | Requests、JsonPath | 接口调用、响应解析、断言验证 |
| 自动化测试 | Selenium、Appium、Pytest | UI 自动化、用例管理、报告生成 |
| 性能测试 | Locust | 高并发场景测试、性能指标监控 |
| 测试数据生成 | Random、Faker | 批量生成合法 / 非法测试数据 |
| 测试结果分析 | Pandas、Matplotlib | 测试报告数据可视化、缺陷统计分析 |
二、 Python 数据类型:可变类型与不可变类型完整梳理
- 可变类型:创建后可直接修改内部元素,修改操作不会生成新对象,内存地址保持不变
- 不可变类型:创建后无法修改内部元素,若要改变内容,会生成一个全新的对象,内存地址发生变化
(1)可变类型(4种核心)
| 数据类型 | 语法标识/示例 | 核心特点 | 常见应用场景 |
|---|---|---|---|
| 列表(list) | 方括号 [],例:[1, "test", True] |
元素可重复、支持增删改查、有序排列 | 存储测试用例、接口返回列表数据、批量数据处理 |
| 字典(dict) | 大括号 {} 键值对,例:{"name": "admin", "age": 20} |
键唯一且不可变、值可任意修改、无序(Python3.7+有序) | 构造接口请求参数、解析JSON响应数据、配置项存储 |
| 集合(set) | 大括号 {} 无键值,例:{1, 2, 3, 3} |
元素唯一、无序排列、支持交并补差运算 | 测试数据去重、重复结果排查、数据唯一性校验 |
| 字节数组(bytearray) | bytearray(b"test") |
二进制数据类型、支持修改单个字节、面向字节操作 | 二进制文件处理、接口二进制数据传输(少见) |
(2)不可变类型(8种核心)
| 数据类型 | 语法标识/示例 | 核心特点 | 常见应用场景 |
|---|---|---|---|
| 整数(int) | 无引号,例:100、-5、0 |
无大小限制、支持四则运算、不可修改 | 用例ID、响应状态码、统计计数、参数数值 |
| 字符串(str) | 单/双/三引号,例:"test"、'python' |
字符序列、不可修改、支持切片和格式化 | 接口参数值、响应文本、用例描述、报告生成 |
| 元组(tuple) | 小括号 (),例:(1, "test", (2, 3)) |
元素可重复、不可修改、有序排列 | 存储固定配置、接口固定参数、不可变数据集合 |
| 浮点数(float) | 带小数点,例:3.14、0.5、-2.0 |
小数类型、精度有限(存在浮点误差)、不可修改 | 接口响应时间、性能测试指标、数值精度校验 |
| 布尔值(bool) | 仅 True / False(本质是1和0) |
二值类型、用于逻辑判断、不可修改 | 用例执行结果、条件判断、断言验证结果 |
| 复数(complex) | 实部+虚部,例:3+4j、1.0-2.0j |
由实部和虚部组成、支持复数运算、不可修改 | 科学计算、特殊领域开发(测试场景极少用) |
| 冻结集合(frozenset) | frozenset({1, 2, 3}) |
不可修改的集合、元素唯一、无序排列 | 固定不可变数据集、字典的键(需不可变类型) |
| NoneType(None) | None |
表示空值、无实际内容、不可修改 | 函数默认返回值、空参数占位、数据初始化 |
(3) 列表 (list) vs 字典 (dict)
| 对比维度 | 列表 (list) | 字典 (dict) |
|---|---|---|
| 索引方式 | 数字索引(0 开始) | 键索引(字符串 / 数字等) |
| 查找效率 | 遍历查找(O (n)),效率较低 | 哈希查找(O (1)),效率极高 |
| 适用场景 | 有序数据集合(如用例列表) | 键值对应数据(如接口参数) |
| 测试实战示例 | 存储批量测试用例 | 存储单条用例的参数(key = 参数名,value = 参数值) |
(4)列表常用操作(测试用例 / 数据处理)
| 操作类型 | 函数 / 语法 | 代码示例(测试场景) |
|---|---|---|
| 新增元素 | append ()(尾部) | cases.append(new_case) 新增测试用例 |
| 删除元素 | remove ()(按值) | cases.remove(case) 删除指定用例 |
| 反转 | reverse () / 切片 [::-1] | response_times[::-1] 反转响应时间列表 |
| 排序 | sorted ()(不修改原列表) | sorted(scores) 对测试成绩升序排序 |
| 切片截取 | list[start🔚step] | cases[1:3] 截取第 2-3 条测试用例 |
| 去重 | 字典有序性 / 遍历去重 | list(dict.fromkeys(response_data)) 接口数据去重 |
(5)字符串常用操作(接口数据提取)
| 操作类型 | 函数 / 语法 | 代码示例(测试场景) |
|---|---|---|
| 分割 | split() | response.split(',') 分割接口响应文本 |
| 替换 | replace() | param.replace(' ', '') 清除参数空格 |
| 查找 | find() / index() | response.find('"code":200') 校验响应状态码 |
| 拼接 | join() | ','.join(case_ids) 拼接用例 ID 字符串 |
| 格式化 | f-string / format() | f"用例{case_id}:{result}" 生成测试报告行 |
(6) 验证可变类型(修改不改变内存地址)
python
# 以列表(list)为例
my_list = [1, 2, 3]
print("修改前内存地址:", id(my_list))
# 执行修改操作(append添加元素)
my_list.append(4)
print("修改后内存地址:", id(my_list))
print("修改后列表内容:", my_list)
# 以字典(dict)为例
my_dict = {"name": "admin"}
print("\n字典修改前内存地址:", id(my_dict))
my_dict["age"] = 20
print("字典修改后内存地址:", id(my_dict))
print("字典修改后内容:", my_dict)
(7)列表 (list)
python
# 定义测试用例列表(测试场景:登录功能用例集)
login_cases = [
{"case_id": 1, "username": "admin", "password": "123456", "expected": "登录成功"},
{"case_id": 2, "username": "admin", "password": "", "expected": "密码不能为空"},
{"case_id": 3, "username": "", "password": "123456", "expected": "用户名不能为空"}
]
# 核心操作:增删改查(测试用例管理常用)
# 1. 新增用例(append尾部添加)
login_cases.append({"case_id": 4, "username": "test", "password": "test123", "expected": "登录成功"})
print("新增后用例集:", login_cases)
# 2. 删除用例(按条件删除case_id=2的用例)
for case in login_cases[:]: # 切片遍历,避免删除时索引错乱
if case["case_id"] == 2:
login_cases.remove(case)
print("删除后用例集:", login_cases)
# 3. 修改用例(更新case_id=3的预期结果)
for case in login_cases:
if case["case_id"] == 3:
case["expected"] = "用户名不可为空"
print("修改后用例集:", login_cases)
# 4. 查找用例(统计预期为"登录成功"的用例数)
success_count = len([case for case in login_cases if case["expected"] == "登录成功"])
print("预期登录成功的用例数:", success_count)
# 5. 列表常用工具函数(测试数据统计)
nums = [1, 3, 5, 36, 8]
print("列表最大值:", max(nums)) # 测试成绩/响应时间最大值统计
print("列表最小值:", min(nums)) # 测试成绩/响应时间最小值统计
print("列表长度:", len(nums)) # 用例总数统计
print("列表求和:", sum(nums)) # 测试数据求和(如接口响应时间总和)
(8)字符串 (str)
python
# 测试场景:接口返回文本处理
response_text = '{"code":200, "msg":"登录成功", "data":{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"}}'
# 核心操作:截取、替换、拼接(测试数据提取常用)
# 1. 截取token(字符串切片)
token = response_text.split('"token":"')[1].split('"')[0]
print("提取的token:", token)
# 2. 替换字符(接口参数格式化)
param = "username=admin&password=123456"
new_param = param.replace("123456", "******") # 密码脱敏处理
print("脱敏后参数:", new_param)
# 3. 拼接字符串(测试报告生成)
case_id = 1
result = "PASS"
report_line = "用例" + str(case_id) + ":执行结果-" + result
print("测试报告行:", report_line)
# 4. 字符串格式化(推荐f-string,测试报告美化)
report_line_f = f"用例{case_id}:执行结果-{result}"
print("f-string格式化报告行:", report_line_f)
(9) 字典 (dict)
python
# 测试场景:接口请求参数构造与响应解析
# 1. 构造接口请求参数
request_params = {
"username": "admin",
"password": "123456",
"remember_me": True
}
print("接口请求参数:", request_params)
# 2. 新增/修改参数(测试不同参数组合用例)
request_params["verify_code"] = "6666" # 新增验证码参数
request_params["password"] = "888888" # 修改密码参数
print("修改后请求参数:", request_params)
# 3. 提取响应数据(模拟接口返回JSON)
response_dict = {
"code": 200,
"msg": "success",
"data": {"user_id": 1001, "nickname": "测试用户"}
}
user_id = response_dict["data"]["user_id"] # 多层嵌套提取
print("提取的用户ID:", user_id)
# 4. 字典遍历(测试响应参数校验)
print("响应参数校验:")
for key, value in response_dict.items():
print(f"参数{key}:值{value},类型{type(value)}")
三、 循环与条件:测试用例执行核心逻辑
(1)for 循环 vs while 循环(区别 + 测试场景选择)
| 循环类型 | 适用场景 | 语法特点 | 测试场景示例 |
|---|---|---|---|
| for 循环 | 已知循环次数(如遍历用例集) | 遍历可迭代对象(列表 / 字典 / 范围) | 批量执行固定数量的测试用例 |
| while 循环 | 未知循环次数(如重试接口请求) | 满足条件时持续循环 | 接口请求失败后重试 3 次 |
python
# 1. for循环:批量执行测试用例(已知用例数量)
test_cases = [1, 2, 3, 4, 5] # 用例ID列表
for case_id in test_cases:
print(f"执行用例{case_id}:开始测试...")
# 模拟用例执行逻辑
print(f"执行用例{case_id}:测试完成")
# 2. while循环:接口请求重试(未知重试次数)
import random
def call_api():
"""模拟接口调用,随机返回成功/失败"""
return random.choice(["success", "fail"])
retry_count = 0 # 重试次数
max_retry = 3 # 最大重试次数
while retry_count < max_retry:
result = call_api()
if result == "success":
print("接口调用成功")
break
else:
retry_count += 1
print(f"接口调用失败,第{retry_count}次重试...")
if retry_count == max_retry:
print("接口调用失败,已达最大重试次数")
(2) 九九乘法表(循环嵌套基础 + 测试报告格式化)
python
# 右对齐版(测试报告美化输出场景)
print("右对齐九九乘法表:")
for i in range(1, 10):
for j in range(1, i + 1):
# :>4d 表示右对齐,占4个字符宽度,避免输出错位
print(f"{j}×{i}={i*j:>4d}", end="")
print() # 换行
# 左对齐版(简洁输出场景)
print("\n左对齐九九乘法表:")
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}×{i}={i*j:2d} ", end="")
print()
(3)金字塔图案(循环嵌套 + 测试数据可视化)
python
# 测试场景:测试报告中美化展示结果统计(如通过率占比可视化)
n = 9 # 金字塔层数
char = "✓" # 自定义字符(测试通过用✓,失败用✗)
for m in range(1, n):
# 空格填充+字符重复,形成金字塔
print((n - m) * " ", char * (2 * m - 1))
# 数字金字塔(测试数据层级展示)
print("\n数字金字塔:")
for m in range(1, n):
print((n - m) * " ", str(m) * (2 * m - 1))
四、 排序算法:测试数据处理
(1)冒泡排序
算法原理
-
核心思想:相邻元素两两比较,大元素下沉(升序排序)
-
测试场景:测试成绩排序、接口响应时间排序、测试数据去重后排序
python
# 测试场景优化版代码(避免修改原数据)
def bubble_sort(arr):
"""冒泡排序(测试版:不修改原数据,返回排序后新列表)"""
arr_copy = arr.copy() # 复制原数据(测试中关键:保留原始测试数据)
n = len(arr_copy)
for i in range(n - 1):
is_sorted = True # 优化标志:判断是否已有序,避免无效循环
for j in range(n - 1 - i):
if arr_copy[j] > arr_copy[j + 1]:
# 交换元素
arr_copy[j], arr_copy[j + 1] = arr_copy[j + 1], arr_copy[j]
is_sorted = False
if is_sorted:
break # 已有序,直接退出
return arr_copy
# 测试实战:接口响应时间排序(单位:秒)
response_times = [0.5, 0.2, 0.8, 0.3, 0.1]
sorted_times = bubble_sort(response_times)
print("原始响应时间:", response_times)
print("升序排序后:", sorted_times) # 输出:[0.1, 0.2, 0.3, 0.5, 0.8]
print("最快响应时间:", min(sorted_times))
print("最慢响应时间:", max(sorted_times))
(2)内置排序函数:sorted ()(测试场景首选)
python
# 测试场景:测试用例执行结果排序(按用例ID升序)
test_results = [
{"case_id": 3, "result": "PASS"},
{"case_id": 1, "result": "PASS"},
{"case_id": 2, "result": "FAIL"}
]
# 按case_id升序排序(key参数指定排序字段)
sorted_results = sorted(test_results, key=lambda x: x["case_id"])
print("按用例ID排序后:", sorted_results)
# 按result降序排序(FAIL在前,PASS在后,便于优先查看失败用例)
sorted_results_desc = sorted(test_results, key=lambda x: x["result"], reverse=True)
print("按结果降序排序后:", sorted_results_desc)
五、类与函数:测试脚本模块化核心
(1)函数:测试用例复用基础
python
# 测试场景:封装接口请求函数(复用性 + 维护性)
import requests
def send_request(url, method="get", params=None, json=None):
"""
封装HTTP请求函数(测试岗通用)
:param url: 接口URL
:param method: 请求方法(get/post)
:param params: get请求参数
:param json: post请求参数
:return: 响应字典
"""
try:
if method.lower() == "get":
response = requests.get(url, params=params, timeout=10)
elif method.lower() == "post":
response = requests.post(url, json=json, timeout=10)
else:
return {"code": -1, "msg": "不支持的请求方法"}
return {
"code": 200,
"msg": "请求成功",
"data": response.json()
}
except requests.exceptions.Timeout:
return {"code": -2, "msg": "接口请求超时"}
except Exception as e:
return {"code": -3, "msg": f"请求异常:{str(e)}"}
# 函数调用(测试登录接口)
login_url = "https://api.test.com/login"
login_data = {"username": "admin", "password": "123456"}
response = send_request(login_url, method="post", json=login_data)
print("接口响应结果:", response)
# 断言验证(测试核心步骤)
if response["code"] == 200 and response["data"]["status"] == "success":
print("登录接口测试通过")
else:
print("登录接口测试失败")
(2)类:测试框架 / 工具封装核心
python
# 测试场景:封装登录测试类(面向对象编程)
class LoginTest:
"""登录功能测试类(测试用例模块化管理)"""
def __init__(self, base_url):
self.base_url = base_url # 基础URL(类属性,复用)
self.session = requests.Session() # 保持会话(避免重复登录)
def login(self, username, password):
"""登录方法(核心功能封装)"""
url = f"{self.base_url}/login"
data = {"username": username, "password": password}
response = self.session.post(url, json=data, timeout=10)
return response.json()
def test_login_success(self):
"""测试登录成功用例(用例方法化)"""
result = self.login("admin", "123456")
assert result["status"] == "success", "登录成功用例失败"
print("登录成功用例:PASS")
def test_login_fail_wrong_pwd(self):
"""测试密码错误用例"""
result = self.login("admin", "wrong_pwd")
assert result["status"] == "fail", "密码错误用例失败"
assert result["msg"] == "密码错误", "错误提示不一致"
print("密码错误用例:PASS")
# 类实例化与用例执行
if __name__ == "__main__":
test = LoginTest("https://api.test.com")
test.test_login_success()
test.test_login_fail_wrong_pwd()
(3)函数与类的区别
| 对比维度 | 函数 | 类 |
|---|---|---|
| 核心用途 | 封装单一功能(如接口请求) | 封装相关功能集合(如登录模块所有用例) |
| 复用方式 | 直接调用 | 实例化后调用方法 |
| 测试场景选择 | 简单功能复用(如数据处理函数) | 复杂模块测试(如登录、下单等完整功能) |
| 优势 | 代码简洁,调用方便 | 模块化强,便于维护和扩展 |
六、 测试岗 Python 面试易错点总结
-
数据类型混淆 :列表
append()(添加单个元素)vsextend()(添加可迭代对象),测试中新增用例用append() -
可变类型修改 :字典 / 列表作为函数参数时,修改会影响原对象,测试中需用
copy()复制后操作 -
循环逻辑错误 :遍历列表时删除元素,需用切片
list[:]遍历,避免索引错乱 -
异常处理缺失:接口测试函数必须捕获超时、连接异常,否则单个用例失败导致脚本崩溃
-
字符串处理:接口响应数据提取优先用 JSON 解析,避免字符串切片(易因格式变化失效)

学习过程中,如果遇到别的问题,可在评论区留言交流 !