Python字符串操作在Playwright自动化测试中的核心应用与实战技巧
1. 项目概述:为什么字符串操作是自动化测试的基石
干了这么多年自动化测试,我见过太多因为字符串处理不当而导致的“灵异事件”。一个看似简单的元素文本断言失败,背后可能藏着编码问题、空格差异或者动态内容截取错误。尤其是在像 Playwright 这样现代、高效的自动化框架里,我们与网页的交互,本质上就是一场与字符串的“博弈”。你定位元素靠的是字符串选择器,你验证结果比对的也是字符串内容,你从页面上提取的数据更是五花八门的字符串。如果字符串操作这门“内功”不扎实,你的自动化脚本就会像建立在流沙上的城堡,看似华丽,一碰就散。
《最新出炉》这个系列,咱们定位就是“入门篇”,但入门绝不意味着浅尝辄止。今天,我们就深挖一下 Python 中那些你必须掌握的字符串操作技巧,并紧密结合 Playwright 自动化测试的真实场景。你会发现,这些基础操作,才是支撑起稳定、健壮测试用例的真正骨架。无论你是刚刚接触 Playwright,想从 Selenium 转型过来,还是已经写了一些脚本但总觉得排查问题很费力,这篇关于字符串“上篇”的梳理,都能帮你把基础打牢。咱们不搞花架子,就聊实实在在的代码和踩过的坑,让你写的每一行 assert 都更有底气。
2. 核心需求解析:自动化测试中字符串操作的四大战场
在开始敲代码之前,我们得先想明白:在 Playwright 自动化测试里,我们到底在哪些地方需要和字符串“较劲”?理解了战场,才能选对武器。
2.1 战场一:元素定位与动态选择器构建
这是字符串操作最频繁的场景。Playwright 提供了多种定位方式( text= , css= , xpath= ),其中很多都需要我们动态拼接字符串。
典型场景 :你要测试一个表格,需要点击“用户姓名”为“张三”的那一行后面的“编辑”按钮。这个“张三”可能来自测试数据文件。你的选择器可能就是 'tr:has-text("张三") >> button:text("编辑")' 。这里,将变量 username = "张三" 嵌入到选择器字符串中,就是最基本的字符串格式化操作。如果用户名包含引号或特殊字符,直接拼接就会导致语法错误,脚本直接崩溃。
更深层需求 :不仅仅是简单的拼接。有时你需要从一部分文本中定位元素,比如“包含‘订单’字样的按钮”。这就需要使用字符串方法来判断或生成匹配模式。
2.2 战场二:断言验证与文本内容处理
从页面上获取到的文本( text_content() , inner_text() )很少是“干净”的。它可能包含:
- 多余的空格和换行 :特别是从
inner_text()获取时,会保留元素内的格式。 - 不可见字符 :如
(不间断空格)、\u200b(零宽空格)。 - 动态前缀/后缀 :比如“总计:$100.00”,你只关心数字“100.00”。
- 多语言和编码 :虽然现代网页多用 UTF-8,但偶尔也会遇到编码问题。
你的断言 assert page.text_content(‘.total’) == ‘100.00’ 很可能因为一个多余的空格而失败。因此,对获取的字符串进行“清洗”(trim, strip, replace)和“提取”(slice, split, regex)是必备技能。
2.3 战场三:测试数据准备与参数化
测试数据往往存储在外部文件(如 CSV, JSON, Excel)或从数据库读取。这些数据读入内存后,通常以字符串形式存在。你可能需要:
- 格式化 :将字符串模板与变量结合,生成最终的测试输入(如邮件正文、地址信息)。
- 转换 :将字符串转换为其他类型(如整数、浮点数、日期)进行业务逻辑计算,然后再转换回字符串进行输入或断言。
- 生成 :动态生成符合特定规则的字符串,如随机邮箱、手机号、订单号,用于测试新建功能。
2.4 战场四:日志记录与报告生成
清晰易懂的日志和报告是调试和排查问题的生命线。你需要将各种变量(定位器、预期值、实际值、状态)组织成人类可读的字符串信息,记录到文件或控制台。如何格式化这些日志信息,使其在成千上万行日志中一目了然,也离不开字符串操作。
理解了这四大战场,我们就能有的放矢地学习 Python 的字符串工具箱了。接下来,我们进入实战环节,我会结合 Playwright 代码,逐一拆解这些核心操作。
3. 基础但至关重要的字符串操作三剑客
在深入复杂操作前,有三个基础方法你必须像呼吸一样自然地去使用。它们在 Playwright 脚本中出场率极高。
3.1 strip() 、 lstrip() 、 rstrip() :文本清洗第一步
从 Playwright 获取文本后,第一步永远是去除首尾空白字符。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://example.com')
# 假设某个元素的实际HTML是:<span> Hello World </span>
raw_text = page.text_content('span') # 可能得到 " Hello World "
# 直接断言会失败!
# assert raw_text == "Hello World" # False
cleaned_text = raw_text.strip()
print(f"原始文本: '{raw_text}'") # 输出: ' Hello World '
print(f"清洗后文本: '{cleaned_text}'") # 输出: 'Hello World'
assert cleaned_text == "Hello World" # True
browser.close()
为什么是 strip() ? inner_text 会保留元素内的文本格式,包括换行和缩进。 text_content 虽然好一些,但元素本身的样式或布局也可能引入空格。 strip() 能移除字符串开头和结尾的 所有 空白字符(空格、制表符 \t 、换行符 \n 、回车符 \r 等)。这是避免因格式问题导致断言失败的最简单、最有效的方法。
lstrip() 和 rstrip() 用在哪儿? 有时你只需要去除一边的空白。例如,从输入框 get_attribute(‘value’) 获取的值,用户可能在开头误输入了空格,但结尾的空格通常会被浏览器忽略。这时用 lstrip() 更精准。或者处理某些有固定后缀的文本时,你可能只想清理开头。
实操心得 :养成条件反射,对任何从页面上
text_content()或inner_text()获取的字符串,立即调用.strip()。这能避免至少 30% 因格式问题导致的偶发性失败。
3.2 replace() :不仅仅是简单的替换
str.replace(old, new[, count]) 方法看似简单,但在测试数据准备和文本清理中威力巨大。
场景一:清理特定字符
# 从页面上获取的价格可能包含货币符号和千位分隔符
price_text = page.text_content(‘.price‘).strip() # 假设得到 “$1,234.56”
# 为了转换为浮点数进行比较,需要移除 $ 和 ,
price_number = float(price_text.replace(‘$‘, ‘‘).replace(‘,‘, ‘‘))
assert price_number > 1000
场景二:处理动态内容中的固定部分
# 页面提示信息可能是:“成功创建了订单,订单号:ORD-20231027-78901”
message = page.text_content(‘.alert-success‘).strip()
# 我们只关心固定的前缀部分是否出现,可以移除动态的订单号部分进行比较
if message.replace(order_number, ‘[NUMBER]‘) == “成功创建了订单,订单号:[NUMBER]“:
print(“订单创建成功消息正确”)
这里, order_number 是之前生成的变量。通过 replace 将动态部分替换为占位符,使得断言可以专注于静态文本。
场景三:构造包含引号的选择器(进阶) 这是一个容易踩坑的地方。如果文本内容本身包含单引号或双引号,直接拼接到选择器里会破坏语法。
username = “O‘Connor“ # 名字里有个单引号
# 错误做法:选择器字符串会提前结束
# selector = f‘button:text(“{username}“)‘ # 语法错误!
# 正确做法:使用 replace 进行转义,或者使用不同的引号
selector1 = f“button:text(‘{username}‘)“ # 用双引号包裹整个字符串,内部用单引号
# 或者,更稳妥地使用 CSS 转义或 Playwright 的转义函数(如果存在)
# 但一个简单的 replace 可以临时解决:
escaped_username = username.replace(“‘“, “\\‘“) # 将单引号替换为转义的单引号
selector2 = f‘button:text(“{escaped_username}“)‘
注意 :对于复杂的文本,建议使用 Playwright 提供的
escape_for_selector类的方法(如果有)或优先考虑使用其他属性(如data-testid)进行定位,避免文本定位的脆弱性。replace在这里是一种应急的字符串处理手段。
3.3 split() :从大段文本中提取关键信息
当页面元素返回的是一大段文本,而你只需要其中的某一部分时, split() 是你的首选工具。它根据指定的分隔符将字符串切分成列表。
典型场景:获取表格某一行的特定列数据
# 假设一个表格行的文本内容是 “张三 30 男 zhangsan@example.com“
row_text = page.text_content(‘tr:first-child‘).strip()
columns = row_text.split() # 默认以任何空白字符(空格、换行等)分割
print(columns) # 输出: [‘张三‘, ‘30‘, ‘男‘, ‘zhangsan@example.com‘]
name, age, gender, email = columns # 可以直接解包
assert name == “张三“
assert int(age) > 18 # 转换为整数进行比较
更精细的分割 : 如果数据是用特定的字符分隔的,比如逗号、制表符或“|”。
csv_line = “Apple,Red,Round,Sweet“
attributes = csv_line.split(‘,‘)
print(attributes) # 输出: [‘Apple‘, ‘Red‘, ‘Round‘, ‘Sweet‘]
# 限制分割次数:只分割前N次
log_entry = “ERROR 2023-10-27 10:00:00 ModuleA - Something went wrong“
parts = log_entry.split(‘ ‘, 3) # 只分割前3个空格
print(parts) # 输出: [‘ERROR‘, ‘2023-10-27‘, ‘10:00:00‘, ‘ModuleA - Something went wrong‘]
# 这样就把日志级别、日期、时间和剩余信息分开了
在 Playwright 中的组合应用 :
# 获取一个包含多个子项的元素文本,如一个标签列表 “标签1, 标签2, 标签3“
tags_text = page.text_content(‘.tags‘).strip()
# 先按逗号分割,再对每个标签去除可能存在的空格
tag_list = [tag.strip() for tag in tags_text.split(‘,‘)]
print(tag_list) # 输出: [‘标签1‘, ‘标签2‘, ‘标签3‘]
# 现在可以方便地断言标签是否存在
assert “标签2“ in tag_list
split() 方法简单粗暴有效,是快速从结构化文本中提取数据的利器。但它依赖于分隔符的稳定性,如果页面格式变化,分隔符也可能变化,导致脚本失败。因此,对于非常重要的数据提取,有时需要结合更强大的正则表达式。
4. 字符串查找与验证:确保元素“所言非虚”
自动化测试中,我们经常需要判断页面上是否存在某个文本,或者某个文本是否包含特定的关键词。这不仅仅是做断言,还常用于条件判断,决定测试流程的走向。
4.1 in 关键字与 find() :成员检查与位置定位
最直观的检查就是使用 in 关键字。
page_text = page.text_content(‘body‘).strip()
if “登录成功“ in page_text:
print(“检测到登录成功提示,继续后续操作“)
# ... 执行登录后的操作
else:
print(“未发现成功提示,可能登录失败“)
# ... 执行失败处理或断言失败
in 操作符返回布尔值,简单高效。但它只告诉你“有没有”,不告诉你“在哪里”。
如果需要知道子字符串的位置,就要用到 str.find(sub[, start[, end]]) 方法。它返回子字符串首次出现的索引(从0开始),如果没找到则返回-1。
error_message = page.text_content(‘.error-panel‘).strip()
# 查找具体的错误代码
pos = error_message.find(“ErrorCode: 500“)
if pos != -1:
print(f“发现服务器内部错误,位置在索引 {pos}")
# 可以基于位置进行更精细的文本截取
# 例如,截取从错误代码开始的后50个字符
detail = error_message[pos:pos+50]
print(f“错误详情片段:{detail}“)
else:
print(“未发现特定的ErrorCode 500“)
find() 在解析一些有固定格式的日志或消息时非常有用。与之类似的还有 rfind() (从右向左查找)、 index() (类似 find() ,但找不到会抛出 ValueError ,在测试脚本中通常不如 find() 安全)。
4.2 startswith() 与 endswith() :精准的边界断言
很多时候,我们关心的是文本是否以某个特定内容开头或结尾。比如,验证成功提示、检查文件下载后的默认名称、确认URL跳转正确。
# 验证页面标题或特定提示
page_title = page.title()
if page_title.startswith(“仪表盘 - “):
print(“成功进入仪表盘页面“)
# 验证下载的文件名
# 假设通过某些手段获取了下载的文件名(例如监听下载事件)
downloaded_file = “report_20231027.csv“
if downloaded_file.endswith(“.csv“):
print(“文件格式正确,是CSV文件“)
if downloaded_file.startswith(“report_“):
print(“文件名前缀也符合规范“)
# 验证当前URL
current_url = page.url
if current_url.endswith(“/dashboard“):
print(“当前正处于仪表盘路由下“)
这两个方法比使用 in 或正则表达式更精确、性能更好,语义也更清晰。在断言中,我强烈推荐使用它们来代替模糊的包含检查。
4.3 大小写转换与规范化比较:避免“Case-Sensitive”的坑
网页上的文本大小写可能不一致,而我们的测试数据可能是固定大小写的。直接比较会导致失败。
# 页面上显示的是 “Welcome, John!“
ui_greeting = page.text_content(‘.welcome-msg‘).strip() # “Welcome, John!“
expected_greeting = “WELCOME, JOHN!“ # 我们的预期可能是大写的(例如来自配置)
# 直接比较失败
# assert ui_greeting == expected_greeting # False
# 方法1:都转成小写或大写再比较
assert ui_greeting.lower() == expected_greeting.lower() # True
# 方法2:使用 casefold() 进行更彻底的忽略大小写比较(对某些特殊字符更准确)
assert ui_greeting.casefold() == expected_greeting.casefold()
lower() vs casefold() :
lower():将字符串中所有大写字符转换为小写。适用于大多数英文场景。casefold():更加激进,旨在移除所有大小写区别。例如,德语字母‘ß‘(sharp s)的lower()还是‘ß‘,但casefold()会变成“ss“。在需要严格的无语言环境限制的大小写无关比较时(比如搜索引擎),casefold()更合适。对于大多数 Web UI 测试,lower()或upper()已足够。
规范化操作的最佳实践 : 我建议在测试脚本中定义一个辅助函数,专门用于进行“模糊”的文本比较,将 strip() 、大小写转换、甚至替换掉不间断空格等操作封装起来。
def normalize_text(text: str) -> str:
“”“清洗和规范化字符串,用于比较。”“”
if not text:
return text
# 1. 去除首尾空白
text = text.strip()
# 2. 将HTML不间断空格替换为普通空格
text = text.replace(‘\u00A0‘, ‘ ‘)
# 3. 将多个连续空格合并为一个(可选,根据需求)
# import re; text = re.sub(r‘\s+‘, ‘ ‘, text)
# 4. 转换为小写
text = text.lower()
return text
# 使用方式
actual = normalize_text(page.text_content(‘.message‘))
expected = normalize_text(“ Your Order Is Confirmed! “) # 预期文本也可以同样处理
assert actual == expected
这个 normalize_text 函数能处理很多因格式导致的断言失败,让你的测试更加健壮。
5. 字符串格式化:动态构建选择器与日志信息
这是将静态脚本变为动态、可复用脚本的关键。Python 提供了多种字符串格式化方式,在 Playwright 脚本中,我最常用的是 f-string 和 str.format() 。
5.1 f-string:现代、简洁的首选
Python 3.6 引入的 f-string 是当前最推荐的方式,可读性极高。
# 1. 动态构建选择器
product_name = “Playwright Guide Book“
# 定位包含特定产品名的“加入购物车”按钮
add_to_cart_selector = f‘div.product:has-text(“{product_name}“) >> button:has-text(“Add to Cart“)‘
page.click(add_to_cart_selector)
# 2. 参数化URL
order_id = 12345
page.goto(f“https://admin.example.com/orders/{order_id}/details“)
# 3. 生成清晰的日志信息
expected_count = 10
actual_count = len(page.query_selector_all(‘.item-row‘))
# 使用 f-string 生成包含变量值的断言失败信息,调试时一目了然
assert actual_count == expected_count, f“商品数量不符,预期 {expected_count},实际 {actual_count}“
f-string 直接在字符串前加 f ,用花括号 {} 包裹变量或表达式。它支持复杂的表达式甚至函数调用(但为了可读性,不建议在内部写太复杂的逻辑)。
5.2 str.format() :更灵活的格式化控制
当需要更复杂的格式控制时,比如数字的位数、对齐方式等, format() 方法更强大。
# 控制数字格式:浮点数保留两位小数,整数补零
total_amount = 1234.5
formatted_amount = “Total: ${:.2f}“.format(total_amount) # “Total: $1234.50“
page.fill(‘#amount‘, formatted_amount)
order_id = 42
padded_order_id = “Order #{:06d}“.format(order_id) # “Order #000042“
assert padded_order_id in page.text_content(‘.order-header‘)
# 按位置或关键字传递参数,适合从字典等数据结构中构建字符串
log_template = “Time: {timestamp} | Level: {level} | Message: {msg}“
log_entry = log_template.format(timestamp=“2023-10-27 10:00“, level=“INFO“, msg=“Test started.“)
print(log_entry)
在 Playwright 测试中, format() 特别适合用于生成符合特定格式要求的测试数据,或者整理报告输出。
5.3 实战:封装一个安全的动态选择器构建函数
结合字符串操作和格式化,我们可以封装一个更健壮的函数来构建 Playwright 文本选择器,处理文本中的引号问题。
def build_text_selector(element_type: str = “*“, text: str = None, contains: bool = False) -> str:
“”“
构建一个安全的 Playwright 文本选择器。
:param element_type: 元素类型,如 ‘button‘, ‘div‘,默认为 ‘*‘ 任何元素。
:param text: 需要匹配的文本。
:param contains: 如果为 True,使用 `:has-text()` 进行模糊匹配;为 False 使用 `:text-is()` 精确匹配(Playwright 1.28+)。
:return: 构建好的选择器字符串。
“”“
if not text:
return element_type
# 简单转义单双引号:如果文本中有单引号,就用双引号包裹整个文本,反之亦然。
# 这是一种简易处理,对于极端复杂的文本,可能需要更完整的转义。
if “'“ in text and ‘“‘ in text:
# 如果两种引号都有,优先转义单引号,并用双引号包裹
escaped_text = text.replace(“'“, “\\‘“)
quote_char = ‘“‘
elif “‘“ in text:
# 文本有单引号,用双引号包裹
escaped_text = text
quote_char = ‘“‘
else:
# 文本没有单引号,用单引号包裹(更常见)
escaped_text = text
quote_char = “'“
if contains:
# 使用 :has-text() 进行子串匹配
selector = f‘{element_type}:has-text({quote_char}{escaped_text}{quote_char})‘
else:
# 使用 :text-is() 进行精确文本匹配(要求Playwright版本支持)
# 或者使用老的 text= 选择器,但需要注意它也是精确匹配
selector = f‘{element_type}:text-is({quote_char}{escaped_text}{quote_char})‘
# 老版本兼容写法:selector = f‘{element_type}:text(“{escaped_text}“)‘ # 注意这里固定用了双引号
return selector
# 使用示例
button_selector = build_text_selector(“button“, “Submit Order“)
page.click(button_selector)
# 处理包含引号的文本
weird_text_selector = build_text_selector(“span“, “O‘Connor said: \“Hello\”“)
print(weird_text_selector) # 输出: span:has-text(“O‘Connor said: \“Hello\”“)
这个函数虽然简单,但解决了一个常见痛点。当然,对于生产级脚本,更推荐使用 data-testid 等专用测试属性来定位,完全避免文本内容的依赖。
6. 字符串拼接与性能考量:用 join() 告别低效循环
当我们需要将多个字符串片段组合成一个长的字符串时,比如生成一个长的 SQL 查询语句、构建一个复杂的 JSON 字符串体、或者拼接一个大的 HTML 片段,怎么做最高效?
错误示范(低效) :
parts = [“Line 1“, “Line 2“, “Line 3“, ... “Line 1000“]
result = ““
for part in parts:
result += part + “\n“ # 每次循环都创建一个新的字符串对象!
在 Python 中,字符串是不可变对象。每次使用 += 进行拼接,都会在内存中创建一个全新的字符串对象,并将旧对象的内容复制过去。如果循环次数很多(比如上千次),这种操作会非常消耗内存和时间。
正确做法:使用 str.join() :
parts = [“Line 1“, “Line 2“, “Line 3“, ... “Line 1000“]
result = “\n“.join(parts) # 一次性高效拼接
join() 方法接收一个可迭代对象(如列表、元组),并将其中的所有字符串元素用指定的分隔符(这里是换行符 \n )连接起来。它在内部进行了优化,性能远高于循环拼接。
在 Playwright 测试中的应用场景 :
# 场景1:生成一个测试用的多行地址
address_lines = [
“John Doe“,
“123 Main St“,
“Suite 400“,
“Anytown, CA 12345“
]
formatted_address = “\n“.join(address_lines)
page.fill(‘textarea#address‘, formatted_address)
# 场景2:构建一个复杂的 CSS 选择器列表(用于批量等待元素)
critical_selectors = [
“.page-loaded-indicator“,
“#main-content“,
“.user-avatar“,
“nav.main-menu“
]
# 用逗号连接,形成一个组合选择器,等待其中任何一个出现
combined_selector = “, “.join(critical_selectors)
page.wait_for_selector(combined_selector, state=“visible“)
# 场景3:生成动态的测试用例步骤描述
steps = []
steps.append(“1. 导航到登录页面“)
steps.append(f“2. 输入用户名: {test_username}“)
steps.append(f“3. 输入密码: {test_password}“)
steps.append(“4. 点击登录按钮“)
test_case_steps = “\n“.join(steps)
print(f“执行步骤:\n{test_case_steps}“)
养成使用 join() 的习惯,尤其是在循环体内构建字符串时,这是编写高效 Python 代码(包括测试脚本)的一个小但重要的技巧。
7. 字符串判断与类型安全:编写健壮的断言逻辑
自动化测试脚本必须健壮,能够优雅地处理各种边界情况,比如元素不存在(返回 None )或文本为空。直接对可能为 None 的对象调用字符串方法会导致 AttributeError 。
7.1 防御性编程:处理 None 和空字符串
# 不安全的写法
element = page.query_selector(‘.status-message‘) # 可能返回 None
text = element.text_content() # 如果 element 是 None,这里会抛出 AttributeError
if “success“ in text: # 如果 text 是 None,这里会抛出 TypeError
...
# 健壮的写法
element = page.query_selector(‘.status-message‘)
if element is None:
# 元素不存在,根据业务逻辑处理:可能是测试失败,也可能是正常状态
print(“警告:未找到状态消息元素“)
# 可以选择断言失败或记录日志后继续
# pytest.fail(“状态消息元素未找到“)
else:
text = element.text_content()
# 进一步检查 text 是否为 None 或空(虽然 text_content() 通常返回空字符串而非None)
if text and “success“ in text.strip().lower():
print(“操作成功“)
else:
print(f“操作可能失败,状态信息为: ‘{text}‘“)
关键点 :
- 总是检查
query_selector的返回值 。元素可能因为页面未加载、选择器错误或动态隐藏而找不到。 - 对字符串操作前,确认其非
None。使用if text:进行判断,它等价于if text is not None and text != ““:。 - 结合使用
strip()。即使有文本,也可能全是空格,if text:会判断为True,但strip()后可能为空。
7.2 实用的断言辅助函数
为了提高代码复用性和可读性,可以封装一些常用的字符串断言函数。
def assert_text_contains(element_selector: str, expected_substring: str, page, ignore_case=True, strip=True):
“”“断言指定元素包含某段文本。”“”
element = page.query_selector(element_selector)
assert element is not None, f“未找到元素: {element_selector}“
actual_text = element.text_content()
if actual_text is None:
actual_text = ““
if strip:
actual_text = actual_text.strip()
if ignore_case:
actual_text = actual_text.lower()
expected_substring = expected_substring.lower()
assert expected_substring in actual_text, \
f“元素 ‘{element_selector}‘ 的文本不包含 ‘{expected_substring}‘。实际文本: ‘{actual_text}‘“
def assert_text_equals(element_selector: str, expected_text: str, page, ignore_case=False, strip=True):
“”“断言指定元素的文本等于预期文本。”“”
element = page.query_selector(element_selector)
assert element is not None, f“未找到元素: {element_selector}“
actual_text = element.text_content()
if actual_text is None:
actual_text = ““
processed_actual = actual_text.strip() if strip else actual_text
processed_expected = expected_text.strip() if strip else expected_text
if ignore_case:
compare_result = processed_actual.lower() == processed_expected.lower()
else:
compare_result = processed_actual == processed_expected
assert compare_result, \
f“元素 ‘{element_selector}‘ 的文本与预期不符。\n预期: ‘{processed_expected}‘\n实际: ‘{processed_actual}‘“
# 使用示例
assert_text_contains(‘.toast-message‘, “保存成功“, page)
assert_text_equals(‘h1.page-title‘, “用户管理后台“, page, ignore_case=True)
这些函数内部处理了空值检查、文本清洗和大小写转换,让测试用例的主体部分更简洁、更专注于业务逻辑,同时也提供了清晰的断言失败信息,极大地方便了调试。
字符串操作的“上篇”我们就先探讨到这里,涵盖了从最基础的清洗、查找、格式化到性能优化和健壮性编程的核心内容。这些是构建可靠 Playwright 自动化测试脚本的基石。在下篇中,我们将深入更高级的主题,包括 正则表达式在文本提取中的威力 、 处理多行字符串和复杂编码 、以及如何利用字符串操作进行 数据驱动测试的封装 。掌握了这些,你就能游刃有余地应对自动化测试中 90% 以上的文本处理挑战。
更多推荐

所有评论(0)