这不巧了吗,我最近刚写了一个获取邮件信息的方法,再用正则表达式或者其他方式提取一下验证码
from imapclient import IMAPClient
import email
from email.header import decode_header
from email.utils import parseaddr
def get_email(sender_email=None, folder="INBOX", subject_keyword=None,
only_unread=False, mark_as_read=False, limit=None):
"""
使用 IMAPClient 获取邮件,并设置 IMAP ID 信息
"""
IMAP_SERVER = "XXXX"
EMAIL_ACCOUNT = "XXXX"
PASSWORD = "XXXX"
result = []
with IMAPClient(IMAP_SERVER, ssl=True) as server:
# 登录
server.login(EMAIL_ACCOUNT, PASSWORD)
# 设置 IMAP ID 信息
server.id_({
"name": "myname",
"version": "1.0.0",
"vendor": "myclient",
"support-email": "testmail@test.com"
})
# 列出文件夹(调试用)
folders = server.list_folders()
print("所有文件夹:")
for i in folders:
print(i)
# 选择目标文件夹
try:
server.select_folder(folder)
except Exception as e:
print(f"无法打开文件夹: {folder}\n{e}")
return []
# 搜索条件
criteria = []
if only_unread:
criteria.append("UNSEEN")
else:
criteria.append("ALL")
if sender_email:
criteria.append(f'FROM "{sender_email}"')
# 搜索邮件
messages = server.search(criteria)
if not messages:
print("没有找到符合条件的邮件")
return []
print(f"找到 {len(messages)} 封符合条件的邮件")
count = 0
for msgid, data in server.fetch(messages, ["RFC822"]).items():
msg = email.message_from_bytes(data[b"RFC822"])
# 解码主题
subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding or "utf-8", errors="ignore")
if subject_keyword and subject_keyword not in subject:
continue
# 解码发件人
raw_from = msg.get("From")
name, addr = parseaddr(raw_from)
decoded_name = decode_header(name)[0][0]
if isinstance(decoded_name, bytes):
decoded_name = decoded_name.decode("utf-8", errors="ignore")
from_ = f"{decoded_name} <{addr}>"
# 提取正文
body = ""
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
content_disposition = str(part.get("Content-Disposition"))
if content_type == "text/plain" and "attachment" not in content_disposition:
charset = part.get_content_charset() or "utf-8"
try:
body = part.get_payload(decode=True).decode(charset, errors="ignore")
except Exception:
body = ""
break
else:
charset = msg.get_content_charset() or "utf-8"
body = msg.get_payload(decode=True).decode(charset, errors="ignore")
result.append({
"subject": subject,
"from": from_,
"body": body
})
# 标记为已读
if mark_as_read:
server.set_flags(msgid, ["\\Seen"])
count += 1
if limit and count >= limit:
break
return result
# 测试:读取未读邮件
if __name__ == "__main__":
emails = get_email(folder="INBOX", only_unread=True, mark_as_read=True limit=1)
print("结果:", emails)
我发现一个更省事的方法,直接调用 manus api (他支持直接打开浏览器),让他把测试步骤解析成 json 结构,接口虽然不会返回任务的详细结果,但会返回 task_id,等任务执行完成直接请求
https://api.manus.im/session.v1.SessionService/GetSession 接口,
lastDisplayMessage 字段就是最后返回的结果,可以直接拿去用,缺点就是仅支持 WEB 端且价格有点贵
官网:https://manus.im/app
api 文档:https://open.manus.ai/docs/api-reference/create-task

多模态能力的 ui 测试平台是不是要把前端的页面结构传给 AI 呀,如果一条用例涉及多个页面,需要把多个页面结构一起传给 AI
+1
平台支持手机端 app UI 自动化测试吗,如果支持,是如何实现的呢
接口都 404 了
如果后端使用的是 python,可以使用 eval 函数,其他语言应该也有相应的函数可以实现。
可以在断言类型里加一个 eval,先算出来 a+b 的结果,最后再断言相等
a = 1.555
b = 2.456
c = 4.01
result = eval("round(a + b, 2)") # 四舍五入保留两位小数
接口自动化其实可以使用 apifox,我看 metersphere 免费的也仅支持接口自动化
✅ Allure 历史记录的原理简述:
Allure 会为每条用例计算一个 historyId(基于测试函数名和参数等生成的哈希值),并在 Jenkins 每次构建时将上次的 history 文件复制到 allure-results 中来进行比对。
🎯 可能导致 “没有历史记录” 的原因:
测试用例的名称或参数发生变化
如果用例名变了、或参数化的参数值不同,会导致 historyId 变化,Allure 会认为是 “新用例”。
上次构建的 history 数据未正确保存到当前构建
Jenkins 需要在构建时,将上一个构建的 allure-results/history 目录复制到当前的 allure-results 中,否则没有 “历史”。
pytest-allure 没有生成正确的 historyId
在某些场景下(特别是动态生成用例或使用了不规范的参数名),可能导致 historyId 计算不一致。
✅ 正确设置历史记录的做法:
cp -r previous_build/allure-report/history current_build/allure-results/
示例(Pipeline 脚本):
stage('Run Tests') {
steps {
script {
// 假设你将上次构建的 history 存在 artifacts 中
sh 'cp -r ${WORKSPACE}/previous_allure_report/history ${WORKSPACE}/allure-results || true'
sh 'pytest --alluredir=allure-results'
}
}
}
对于参数化用例,尽量使用 @pytest.mark.parametrize 的 ids 参数来保持用例名称稳定。
@pytest.mark.parametrize("user_input", [1, 2], ids=["input_1", "input_2"])
def test_example(user_input):
...
✅ 推荐补充做法:
在 Jenkins 中将构建 artifacts 中的 allure-results 和 allure-report 保留并归档。
在 Allure Commandline 中使用 --clean 但确保历史文件提前合并进来。
以上是 ChatGPT 的回复,我试了一下,主要就是将旧报告中的 history 文件夹拷贝出来,再放进新的 allure-results 目录中,在生成测试报告,就会有历史记录了。历史记录只会记录是否成功,不能查看详细信息,感觉用处不大。