摘要:上一篇文章我们熟悉了这三个函数:findalls、get_var、get_var的使用,这一次我们搭建一个简单的测试框架,主要是由YAML文件和这三个函数组成!
上一篇文章我们熟悉了这三个函数:findalls、get_var、get_var的使用,这一次我们搭建一个简单的测试框架,主要是由YAML文件和这三个函数组成!
测试数据 YAML 文件如下:
# test_data.yamltest_cases: findalls_test: description: "测试 findalls 函数" test_strings: - "用户ID: ${user_id}, 用户名: ${username}" - "订单号: ${order_id}, 金额: ${amount}" - "没有变量的字符串" - "只有${single_var}一个变量" - "嵌套${var1}和${var2}多个变量" sub_var_test: description: "测试 sub_var 函数" test_cases: - string: "欢迎 ${user} 登录系统" variables: user: "张三" expected: "欢迎 张三 登录系统" - string: "订单 ${order_id} 金额为 ${amount} 元" variables: order_id: "ORD123456" amount: "199.99" expected: "订单 ORD123456 金额为 199.99 元" - string: "空变量 ${empty_var} 测试" variables: empty_var: "" expected: "空变量 测试" - string: "没有需要替换的变量" variables: {} expected: "没有需要替换的变量" get_var_test: description: "测试 get_var 函数" test_cases: - key: "token" raw_str: '{"aa": 11, "bb": {"token": "3424324234233"}}' expected: "3424324234233" - key: "user_id" raw_str: '{"user_id": "12345", "name": "张三"}' expected: "12345" - key: "email" raw_str: '{"user": {"email": "test@example.com"}}' expected: "test@example.com" - key: "order_id" raw_str: "order_id:ORD789012,status:completed" expected: "order_id" - key: "status" raw_str: "order_id:ORD789012,status:completed" expected: "status" - key: "price" raw_str: "product:phone,price:2999" expected: "price"完整的测试代码如下:
import reimport jsonimport typing as tfrom string import Templateimport yaml# 全局缓存cache = {}def findalls(string: t.Text) -> t.Dict[t.Text, t.Any]: """查找所有""" key = re.compile(r"\${(.*?)\}").findall(string) res = {k: cache.get(k) for k in key} print("需要替换的变量:{}".format(res)) return resdef sub_var(keys: t.Dict, string: t.Text) -> t.Text: """替换变量""" s = Template(string) res = s.safe_substitute(keys) print("替换结果:{}".format(res)) return resdef get_var(key: t.Text, raw_str: t.Text) -> t.Text: """获取变量""" try: # 先判断raw_str的结构是不是json结构 json.loads(raw_str) _obj = re.compile(r'\"%s\"\s*:\s*\"([^\"]+)\"' % key).findall(raw_str) return _obj[0] if _obj else None except: print(f"raw_str_is_not_json_str: {raw_str}") matches = re.compile(r'%s' % key).findall(raw_str) return matches[0] if matches else Nonedef run_tests: """运行所有测试""" # 加载测试数据 with open('test_data.yaml', 'r', encoding='utf-8') as f: test_data = yaml.safe_load(f) print("=" * 50) print("开始测试 findalls 函数") print("=" * 50) # 测试 findalls 函数 cache.update({ "user_id": "1001", "username": "张三", "order_id": "ORD001", "amount": "199.99", "single_var": "单个值", "var1": "变量1", "var2": "变量2" }) for i, test_string in enumerate(test_data['test_cases']['findalls_test']['test_strings']): print(f"\n测试用例 {i+1}: {test_string}") result = findalls(test_string) print(f"结果: {result}") print("\n" + "=" * 50) print("开始测试 sub_var 函数") print("=" * 50) # 测试 sub_var 函数 for i, test_case in enumerate(test_data['test_cases']['sub_var_test']['test_cases']): print(f"\n测试用例 {i+1}:") print(f"原始字符串: {test_case['string']}") print(f"替换变量: {test_case['variables']}") result = sub_var(test_case['variables'], test_case['string']) print(f"期望结果: {test_case['expected']}") print(f"测试结果: {'通过' if result == test_case['expected'] else '失败'}") print("\n" + "=" * 50) print("开始测试 get_var 函数") print("=" * 50) # 测试 get_var 函数 for i, test_case in enumerate(test_data['test_cases']['get_var_test']['test_cases']): print(f"\n测试用例 {i+1}:") print(f"查找键: {test_case['key']}") print(f"原始字符串: {test_case['raw_str']}") result = get_var(test_case['key'], test_case['raw_str']) print(f"提取结果: {result}") print(f"期望结果: {test_case['expected']}") print(f"测试结果: {'通过' if result == test_case['expected'] else '失败'}")if __name__ == "__main__": run_tests输出结果如下:
开始测试 findalls 函数测试用例 1: 用户ID: ${user_id}, 用户名: ${username}需要替换的变量:{'user_id': '1001', 'username': '张三'}结果: {'user_id': '1001', 'username': '张三'}测试用例 2: 订单号: ${order_id}, 金额: ${amount}需要替换的变量:{'order_id': 'ORD001', 'amount': '199.99'}结果: {'order_id': 'ORD001', 'amount': '199.99'}测试用例 3: 没有变量的字符串需要替换的变量:{}结果: {}测试用例 4: 只有${single_var}一个变量需要替换的变量:{'single_var': '单个值'}结果: {'single_var': '单个值'}测试用例 5: 嵌套${var1}和${var2}多个变量需要替换的变量:{'var1': '变量1', 'var2': '变量2'}结果: {'var1': '变量1', 'var2': '变量2开始测试 sub_var 函数测试用例 1:原始字符串: 欢迎 ${user} 登录系统替换变量: {'user': '张三'}替换结果:欢迎 张三 登录系统期望结果: 欢迎 张三 登录系统测试结果: 通过测试用例 2:原始字符串: 订单 ${order_id} 金额为 ${amount} 元替换变量: {'order_id': 'ORD123456', 'amount': '199.99'}替换结果:订单 ORD123456 金额为 199.99 元期望结果: 订单 ORD123456 金额为 199.99 元测试结果: 通过测试用例 3:原始字符串: 空变量 ${empty_var} 测试替换变量: {'empty_var': ''}替换结果:空变量 测试期望结果: 空变量 测试测试结果: 通过测试用例 4:原始字符串: 没有需要替换的变量替换变量: {}替换结果:没有需要替换的变量期望结果: 没有需要替换的变量测试结果: 通过开始测试 get_var 函数测试用例 1:查找键: token原始字符串: {"aa": 11, "bb": {"token": "3424324234233"}}提取结果: 3424324234233期望结果: 3424324234233测试结果: 通过测试用例 2:查找键: user_id原始字符串: {"user_id": "12345", "name": "张三"}提取结果: 12345期望结果: 12345测试结果: 通过测试用例 3:查找键: email原始字符串: {"user": {"email": "test@example.com"}}提取结果: None期望结果: test@example.com测试结果: 失败测试用例 4:查找键: order_id原始字符串: order_id:ORD789012,status:completedraw_str_is_not_json_str: order_id:ORD789012,status:completed提取结果: order_id期望结果: order_id测试结果: 通过测试用例 5:查找键: status原始字符串: order_id:ORD789012,status:completedraw_str_is_not_json_str: order_id:ORD789012,status:completed提取结果: status期望结果: status测试结果: 通过测试用例 6:查找键: price原始字符串: product:phone,price:2999raw_str_is_not_json_str: product:phone,price:2999提取结果: price期望结果: price测试结果: 通过发现的问题和改进建议
从测试结果可以看出:
get_var 函数在处理嵌套 JSON 时存在问题(测试用例3失败)。
当前正则表达式只能匹配一级键值对。
无法处理嵌套的 JSON 对象。
get_var 函数在非 JSON 字符串中的行为可能不符合预期。
当前返回的是键名本身,而不是键值。
改进建议
def get_var_improved(key: t.Text, raw_str: t.Text) -> t.Text: """改进的获取变量函数""" try: # 尝试解析为JSON data = json.loads(raw_str) # 支持嵌套键查找,如 "user.email" keys = key.split('.') result = data for k in keys: if isinstance(result, dict) and k in result: result = result[k] else: return None return str(result) if result is not None else None except json.JSONDecodeError: print(f"raw_str_is_not_json_str: {raw_str}") # 对于非JSON字符串,尝试查找 key:value 模式 pattern = r'%s\s*[=:]\s*([^,\s]+)' % key match = re.search(pattern, raw_str) return match.group(1) if match else None来源:李哥说山水
