ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

软件测试必会:Python数据类型与运算符实战详解

软件测试必会:Python数据类型与运算符实战详解 先澄清一个很多测试新手都会有的误区学软件测试不是只要会“点点点”就行。尤其是想拿高薪、想进大厂、想做自动化测试的朋友代码基础是绕不开的一道坎。而在代码基础里数据类型和运算符又是最底层的两块基石。你写测试用例时用到的边界值、等价类你在自动化脚本里写的断言你调接口时对返回参数的校验本质上都是在跟数据类型和运算符打交道。这篇文章是“软件测试入门到精通”系列的第二课我会结合软件测试的真实场景把 Python 的数据类型与运算符讲透。内容会覆盖基础概念、代码示例、完整实战案例、高频面试题以及测试工作中的最佳实践。无论是零基础转行还是已经在职想补强代码能力这篇教程都值得你跟着敲一遍。1. 为什么软件测试要先搞定运算符与数据类型1.1 测试人员学代码不是为了当开发先看三个常见场景。场景一需求文档里写“用户名长度 6-12 位”。你作为测试要设计正常用例和异常用例。6 位、12 位是边界值5 位、13 位是越界值。这些数据的判断逻辑写在代码里就是len(username) 6 and len(username) 12。如果你看不懂这个表达式就很难真正理解开发同学写出来的功能边界在哪里。场景二接口测试返回了一段 JSON你需要断言“登录成功”。底层逻辑其实就是判断code 200并且msg里包含“成功”。这里既用到了比较运算符也用到了逻辑运算符and。不理解运算符就写不出有效的断言。场景三自动化脚本要读取一批测试账号每个账号依次登录并执行操作。这个过程中需要用到列表存储数据、字典保存用户信息、循环遍历以及条件判断。数据结构选得好不好直接决定脚本好不好维护。这三个场景说明一件事学习运算符和数据类型是测试工程师从“手工用例思维”走向“测试开发思维”的关键一步。1.2 本文涉及的核心范围本文以 Python 3 为语言基础重点拆解五块内容Python 常见数据类型与相互转换算术、赋值、比较、逻辑、成员、身份等运算符运算符优先级和易错点用边界值和等价类思想设计测试数据基于注册功能编写完整的自动化断言脚本。读完本文你可以独立看懂简单的 Python 测试脚本也能自己动手设计测试用例并写成可执行的断言代码。2. 环境准备搭建 Python 学习环境2.1 安装 Python 解释器我建议所有测试初学者使用 Python 3.8 以上的版本。不需要纠结最新的 3.13 还是 3.12选一个稳定版本即可。安装步骤按操作系统区分Windows前往 Python 官网下载.exe安装包勾选Add Python to PATH然后一路 Next。macOS下载.pkg文件按向导安装。Linux使用包管理器例如sudo apt install python3。安装完成后打开终端Windows 用 CMD 或 PowerShell输入python --version如果能输出类似Python 3.12.x的内容说明安装成功。2.2 推荐 IDE 工具测试人员写脚本常用的有三类工具PyCharm专业 Python IDE社区版免费适合写自动化测试工程。VS Code轻量编辑器安装 Python 插件后体验很好。Jupyter Notebook适合逐行验证代码学习阶段非常好用。如果你是零基础我更推荐 PyCharm 或 VS Code。第一个项目不建议在编辑器选择上花太多时间能跑起来就行。2.3 示例项目结构本文实战部分会创建一个非常简单的项目目录lesson2_demo/ ├── register.py # 被测试的注册函数 ├── test_register.py # 自动化断言脚本 └── notes.py # 数据类型与运算符练习脚本全部基于 Python 标准库不需要安装任何第三方包。这样你可以把精力完全放在理解代码逻辑上不用被环境问题干扰。3. 数据类型进阶从“知道”到“会测”3.1 Python 基本数据类型Python 中最基础的数据类型有五种每种类型在测试中的关注点完全不同。类型说明示例测试关注点int整数100、-3、0边界值、正负数、0float浮点数3.14、-0.5精度问题、小数位数bool布尔值True、False真假的等价转换str字符串admin、123空串、长度、特殊字符NoneType空值None字段为空与字段不存在list列表[1, 2, 3]有序、可变、下标访问tuple元组(1, 2, 3)有序、不可变dict字典{name: Tom}键值对、接口响应体set集合{1, 2, 3}无序、去重新建notes.py文件输入以下代码# notes.py age 25 price 99.9 is_vip True name Tom nothing None print(type(age)) # class int print(type(price)) # class float print(type(is_vip)) # class bool print(type(name)) # class str print(type(nothing)) # class NoneTypetype()返回变量的类型。在测试脚本中这个函数经常用来校验接口返回数据的类型是否符合预期。3.2 复合数据类型与测试场景复合类型在测试脚本中几乎每天都会用到尤其是list和dict。# notes.py names [Alice, Bob, Charlie] # list position (10, 20) # tuple user {username: admin, age: 20} # dict tags {test, automation, test} # set重复的 test 会被去重 print(names[0]) # Alice print(position[1]) # 20 print(user[username]) # admin print(tags) # {test, automation}接口测试中Python 用requests库发送请求后响应的 JSON 数据会被解析为dict或list。比如登录接口返回{ code: 200, message: success, data: { token: abc123, user: { id: 1001, name: Tom } } }在 Python 中就可以这样取值response { code: 200, message: success, data: { token: abc123, user: {id: 1001, name: Tom} } } print(response[data][user][name]) # Tom print(response[data][token]) # abc123这就是字典的嵌套取值。测试人员必须熟练这种操作而且还要学会判断response[data]是否为None避免空指针异常。3.3 类型判断与类型转换测试脚本中经常需要判断类型和做类型转换。判断类型有两种写法print(type(123) str) # True print(isinstance(123, str)) # True print(isinstance(123, (int, float))) # True推荐isinstance()因为它支持一次判断多个类型代码更清晰。类型转换更常用。接口返回的字段可能是字符串18而断言要和数字 18 比较这时必须转换a 18 b int(a) print(b 2) # 20 c 3.99 d int(c) print(d) # 3直接丢弃小数部分 e str(100) print(e 元) # 100元这里有一个测试人员特别容易踩的坑print(bool(false)) # True print(bool()) # FalsePython 中只有空字符串、0、None、空列表、空字典等会被转换为 False其他值都是 True。所以当接口返回字符串false时不能直接用bool()去转换否则判断会出错。正确做法是status false print(status false) # True3.4 用数据类型思维设计测试数据等价类划分和边界值分析是软件测试最核心的两个方法而它们都和数据类型强相关。假设需求规定“用户年龄字段为整数范围 18~60”测试数据可以这样设计测试类型测试数据预期结果有效等价类25成功边界下界18成功边界上界60成功下边界减一17失败上边界加一61失败类型错误abc、18.5、None失败这个表格的每一行背后都对应了代码中的比较运算符和类型判断。边界值分析本质上就是在寻找比较运算符两边的临界点。4. 运算符详解测试逻辑的基石4.1 算术运算符算术运算符用于数学计算。Python 中的常见写法如下a 10 b 3 print(a b) # 13 print(a - b) # 7 print(a * b) # 30 print(a / b) # 3.3333333333333335 print(a // b) # 3 print(a % b) # 1 print(a ** b) # 1000这里要特别注意/和//的区别。/是普通除法结果是浮点数//是整除结果向下取整。比如判断 10 个苹果分给 3 个人每人能分几个用10 // 3得到 3判断还剩几个用10 % 3得到 1。在测试脚本中取余运算常用于判断奇偶、判断是否能被整除number 10 print(number % 2 0) # True说明是偶数4.2 赋值运算符赋值运算符用来给变量赋值。最常见的写法是复合赋值x 10 x 5 # x x 5结果是 15 print(x) x - 3 # x 15 - 3结果是 12 print(x) x * 2 # x 12 * 2结果是 24 print(x) x / 4 # x 24 / 4结果是 6.0 print(x)赋值运算符在测试脚本中的典型场景是统计失败用例数量fail_count 0 fail_count 1这里必须提醒一个新手高频率错误Python 没有和--运算符。如果你在 Java 或 C 语言里写习惯了i到 Python 里会直接报语法错误。正确的写法是i 1。4.3 比较运算符比较运算符用于比较两个值的大小或相等关系结果永远是布尔值True或False。a 5 b 3 print(a b) # False等于 print(a ! b) # True不等于 print(a b) # True大于 print(a b) # False小于 print(a b) # True大于等于 print(a b) # False小于等于比较运算符是断言的核心。自动化测试中断言接口返回码本质就是比较运算response_code 200 print(response_code 200) # True print(response_code ! 500) # True print(response_code 200) # True新手特别容易混淆和。是赋值是判断相等。这是软测面试笔试中的高频考点几乎每一次基础题测试都会出现。字符串比较时要注意大小写print(abc abc) # True print(abc ABC) # False如果需求中不区分大小写测试脚本中需要先统一转为小写再比较username Admin print(username.lower() admin) # True4.4 逻辑运算符逻辑运算符有三种and、or、not分别对应“与”“或”“非”。age 25 has_id True print(age 18 and has_id) # True两个条件都成立 print(age 18 or has_id) # True至少一个成立 print(not has_id) # False取反在自动化测试中and和or经常用于组合多个校验条件username test001 password abc123 is_valid_username len(username) 6 and len(username) 12 is_valid_password len(password) 8 and len(password) 16 if is_valid_username and is_valid_password: print(参数校验通过) else: print(参数校验失败)这里有一个 Python 区别于其他语言的特性短路运算。and和or并不总是返回True或False它们会返回参与运算的具体值。print(0 and hello) # 0第一个为假直接返回 0 print(1 and hello) # hello print(0 or hello) # hello print( or default) # default这个特性在实际工作中有一个非常实用的场景给变量设置默认值。name username name or guest print(username) # guest测试数据配置文件中经常用这种方式做兜底。4.5 成员运算符、身份运算符与位运算符成员运算符in和not in用于判断一个值是否存在于列表、字典、字符串等容器中。fruit_list [apple, banana, orange] print(apple in fruit_list) # True print(grape in fruit_list) # False print(a in banana) # True user_dict {username: admin, role: tester} print(username in user_dict) # True判断键是否存在在接口测试中in常用于判断响应体是否包含某个字段。比如断言响应中包含token字段response_keys [code, message, data, token] print(token in response_keys) # True身份运算符is和is not比较的是两个对象是否是同一个对象也就是内存地址是否相同。a [1, 2, 3] b [1, 2, 3] print(a b) # True值相等 print(a is b) # False不是同一个对象在测试脚本中判断None时推荐使用is None而不要写 Noneresult None print(result is None) # True推荐写法位运算符直接操作整数的二进制位包括、|、^、~、、。日常功能测试中很少用到但在权限系统、嵌入式测试和配置项校验中偶尔会碰到。READ 1 # 二进制 001 WRITE 2 # 二进制 010 EXECUTE 4 # 二进制 100 # 用户拥有读和写权限 user_permission READ | WRITE # 结果是 3 # 判断是否有读权限 print(user_permission READ) # 1说明有读权限 print(user_permission EXECUTE) # 0说明没有执行权限这类写法在测试底层权限模型时可能会遇到建议了解即可。4.6 运算符优先级当一个表达式里有多个运算符时优先级决定了运算顺序。常见优先级从高到低如下优先级运算符说明高**幂运算*、/、//、%乘除取余、-加减、!、、、、比较not逻辑非and逻辑与低or逻辑或尽量用括号来明确运算顺序。加括号不是为了显得谨慎而是为了让阅读代码的人一眼看懂逻辑。# 不推荐的写法 if a b 10 and c 2 or d ! 0: pass # 推荐的写法 if ((a b) 10 and (c 2)) or (d ! 0): pass在测试用例设计阶段如果被测代码里同时存在and和or一定要认真分析它的优先级是否正确因为这是开发最容易出 bug 的地方也正是测试人员发挥价值的地方。5. 完整实战案例注册功能从需求到自动化断言理论知识讲完现在进入正题。我们以一个注册功能为例完整演示从需求分析、测试用例设计到编写自动化断言脚本的全过程。5.1 需求描述被测注册功能规则如下用户名6~12 位只能包含字母、数字和下划线不能以数字开头。密码8~16 位必须同时包含字母和数字。确认密码必须与密码一致。邮箱必须包含和.不能在开头.不能在末尾。5.2 编写被测函数 register.py文件路径register.py# register.py def register(username, password, confirm_password, email): 模拟用户注册校验函数 :param username: 用户名 :param password: 密码 :param confirm_password: 确认密码 :param email: 邮箱 :return: 成功返回 (True, 注册成功)失败返回 (False, 错误信息) # 1. 用户名格式校验 if not isinstance(username, str): return False, 用户名必须为字符串 if len(username) 6 or len(username) 12: return False, 用户名长度必须在6到12位之间 if not (username.isalnum() or _ in username): return False, 用户名只能包含字母、数字和下划线 if username[0].isdigit(): return False, 用户名不能以数字开头 # 2. 密码格式校验 if not isinstance(password, str): return False, 密码必须为字符串 if len(password) 8 or len(password) 16: return False, 密码长度必须在8到16位之间 if not (any(c.isdigit() for c in password) and any(c.isalpha() for c in password)): return False, 密码必须同时包含字母和数字 # 3. 两次密码一致性 if password ! confirm_password: return False, 两次输入的密码不一致 # 4. 邮箱格式校验 if not isinstance(email, str) or not in email or . not in email: return False, 邮箱格式不正确 if email.startswith() or email.endswith(.): return False, 邮箱格式不正确 return True, 注册成功这个函数里用到了很多字符串内建方法isalnum()判断字符串是否由字母或数字组成isdigit()判断字符串是否全为数字startswith()判断字符串是否以某个前缀开头endswith()判断字符串是否以某个后缀结尾any()搭配生成器判断密码中是否存在数字或字母。这些都是测试脚本中非常实用的工具函数。5.3 设计测试用例按照边界值分析和等价类划分思想设计以下测试用例用例编号用户名密码确认密码邮箱预期结果TC01test01abc12345abc12345usertest.com成功TC02test0abc12345abc12345usertest.com用户名短于6位失败TC03test0123456789abc12345abc12345usertest.com用户名长于12位失败TC041test01abc12345abc12345usertest.com用户名以数字开头失败TC05test01abc12345abc12345usertest.com用户名含特殊字符失败TC06test001abc123abc123usertest.com密码短于8位失败TC07test001abc123456789012345abc123456789012345usertest.com密码长于16位失败TC08test001abcdefghabcdefghusertest.com密码全字母失败TC09test0011234567812345678usertest.com密码全数字失败TC10test001abc12345abc12344usertest.com两次密码不一致失败TC11test001abc12345abc12345usertest.com邮箱缺少失败TC12test001abc12345abc12345test.com邮箱开头失败TC13test001abc12345abc12345usertest.com.邮箱点号结尾失败TC14123456abc12345abc12345usertest.com用户名以数字开头失败这 14 条用例覆盖了合法路径、长度边界、格式错误、逻辑错误等主要场景。5.4 编写自动化断言脚本文件路径test_register.py# test_register.py from register import register def run_case(username, password, confirm_password, email, expected_result): 执行单个测试用例并断言结果 :param expected_result: 预期结果True 表示成功False 表示失败 result, message register(username, password, confirm_password, email) if result ! expected_result: print(f[FAILED] username{username}, password{password}, email{email}) print(f 预期: {成功 if expected_result else 失败}, 实际: {message}) return False else: print(f[PASSED] username{username}, 结果{message}) return True if __name__ __main__: test_cases [ # (用户名, 密码, 确认密码, 邮箱, 预期结果) (test01, abc12345, abc12345, usertest.com, True), # TC01 (test0, abc12345, abc12345, usertest.com, False), # TC02 (test0123456789, abc12345, abc12345, usertest.com, False), # TC03 (1test01, abc12345, abc12345, usertest.com, False), # TC04 (test01, abc12345, abc12345, usertest.com, False), # TC05 (test001, abc123, abc123, usertest.com, False), # TC06 (test001, abc123456789012345, abc123456789012345, usertest.com, False), # TC07 (test001, abcdefgh, abcdefgh, usertest.com, False), # TC08 (test001, 12345678, 12345678, usertest.com, False), # TC09 (test001, abc12345, abc12344, usertest.com, False), # TC10 (test001, abc12345, abc12345, usertest.com, False), # TC11 (test001, abc12345, abc12345, test.com, False), # TC12 (test001, abc12345, abc12345, usertest.com., False), # TC13 (123456, abc12345, abc12345, usertest.com, False), # TC14 ] total len(test_cases) passed 0 for case in test_cases: username, password, confirm_password, email, expected case if run_case(username, password, confirm_password, email, expected): passed 1 print(f\n共执行 {total} 条用例通过 {passed} 条失败 {total - passed} 条) if passed total: print(测试全部通过) else: print(存在失败用例请检查被测函数逻辑)5.5 运行与验证在项目目录lesson2_demo下执行python test_register.py预期输出结果摘录[PASSED] usernametest01, 结果注册成功 [PASSED] usernametest0, 结果用户名长度必须在6到12位之间 [PASSED] usernametest0123456789, 结果用户名长度必须在6到12位之间 ... 共执行 14 条用例通过 14 条失败 0 条 测试全部通过这个脚本不依赖任何第三方测试框架直接运行就能看到结果。如果你后续学习了pytest可以把这套用例改写成pytest参数化形式报告会更规范执行效率也更高。6. 常见问题与排查思路在学习和使用数据类型与运算符的过程中有几个高频问题几乎每个人都会遇到。问题现象常见原因解决思路10 / 3结果不是预期 3/是浮点除法返回浮点数改用//整除或round()取整assert 0 0报错字符串和整数类型不匹配先确认类型再用int()或str()转换bool(false)返回 True非空字符串都会被转为 True不要用bool()使用 false比较用is判断整数相等失败is比较内存地址小整数池外不保证比较值用判断 None 用isabc和ABC不相等字符串比较区分大小写忽略大小写时先调用lower()and/or的结果不是 True/FalsePython 逻辑运算符返回实际值了解短路特性避免误判字典用in判断值失败in对 dict 只判断键判断值使用value in dict.values()这里再补充一个网上经常讨论的兼容性问题非 h5 平台:key不支持逻辑运算符的兼容性问题。这个问题常见于部分低代码平台或特殊前端运行时。不同平台对运算符的支持范围不一样有些平台不支持、||有些平台不支持三元运算符导致同样的表达式在不同环境运行结果不同。作为测试人员在做兼容性测试时不能默认所有平台都具备相同的运算符支持能力要结合目标平台的官方文档设计最小验证用例做冒烟测试。7. 最佳实践与工程建议7.1 测试脚本中不使用魔法数字不要把6、12、8、16这些校验条件直接散落在代码里。建议定义成常量或者放在配置文件里USERNAME
返回列表