如何用Python的xml.etree.ElementTree检测XML标签存在性
问题:解析XML筛选含failure的testcase并格式化输出
我用Python的xml.etree.ElementTree解析了一个XML测试报告,结构如下:
<?xml version="1.0" encoding="UTF-8"?> <testsuites> <testsuite name="force.apex" timestamp="2022-08-01T11:13:33.672Z" hostname="***" tests="192" failures="21" errors="0" time="371.30"> <testcase name="wavewrapTest" classname="SVC_WaveInsightGeneratorDatasetVerTest" time="0.10"> </testcase> <testcase name="testSVC_UpdateLastTransactionDateTest" classname="SVC_UpdateLastTransactionDateTest" time="2.65"> </testcase> <testcase name="wavewrapTest" classname="SVC_WaveInsightJSONResponseHandlerTest" time="0.10"> </testcase> <testcase name="testFeedComment" classname="DataMaskFeedItemTest" time="2.05"> <failure message="System.NullPointerException: Argument cannot be null."><![CDATA[Class.SVC_AccountQueueableHashedId.execute: line 15, column 1]]></failure> </testcase> <testcase name="testFeedItem" classname="DataMaskFeedItemTest" time="0.76"> <failure message="System.NullPointerException: Argument cannot be null."><![CDATA[Class.SVC_AccountQueueableHashedId.execute: line 15, column 1]]></failure> </testcase> <testcase name="schedulerTest" classname="pi_scheduleBirthdayTaskTest" time="0.09"> <failure message="System.QueryException: List has no rows for assignment to SObject"><![CDATA[Class.pi_scheduleBirthdayTaskTest.schedulerTest: line 19, column 1]]></failure> </testcase> <testcase name="testDefaultSchedule" classname="SVC_AMLBatchTest" time="0.15"> <failure message="System.AsyncException: Based on configured schedule, the given trigger 'SCHEDULED_APEX_JOB_TYPE.000000000000000' will never fire."><![CDATA[Class.SVC_AMLBatchTest.testDefaultSchedule: line 228, column 1]]></failure> </testcase> </testsuite> </testsuites>
需要筛选出包含带message属性的failure标签的testcase,并按格式Class <classname> failed with message <message>输出,跳过没有failure标签的testcase。
我尝试过以下代码,但都无法得到正确结果:
第一个尝试的代码:
for item in root.findall(".//testcase"): failure = item.find('failure') if failure is None: continue failures = failure.text for item1 in root.findall(".//testcase/failure"): children = item1.get('message') print("Class: {} failed with message: {}".format(failures, children))
第二个尝试的代码:
for item in root.iter('testcase'): for item1 in root.iter('failure'): print(item.attrib['classname'], item1.attrib['message'])
正确解决方案
你的代码问题在于:
- 第一个代码错误获取了
failure的文本内容(CDATA部分)而非testcase的classname,且内层循环遍历所有failure标签后,children只会保留最后一个failure的message,导致匹配错误。 - 第二个代码的嵌套循环会将每个
testcase与所有failure标签组合输出,结果重复且对应关系混乱。
正确思路是:遍历每个testcase,找到其内部的failure标签,若存在则提取当前testcase的classname和failure的message属性,按要求格式输出。
完整代码如下:
import xml.etree.ElementTree as ET # 解析XML文件(如果是本地文件,替换为以下两行) # tree = ET.parse('test_report.xml') # root = tree.getroot() for testcase in root.findall(".//testcase"): # 查找当前testcase下的failure标签 failure = testcase.find("failure") if failure is not None: # 获取属性值 classname = testcase.attrib.get("classname") error_msg = failure.attrib.get("message") if classname and error_msg: print(f"Class {classname} failed with message {error_msg}")
执行后输出结果:
Class DataMaskFeedItemTest failed with message System.NullPointerException: Argument cannot be null. Class DataMaskFeedItemTest failed with message System.NullPointerException: Argument cannot be null. Class pi_scheduleBirthdayTaskTest failed with message System.QueryException: List has no rows for assignment to SObject Class SVC_AMLBatchTest failed with message System.AsyncException: Based on configured schedule, the given trigger 'SCHEDULED_APEX_JOB_TYPE.000000000000000' will never fire.
内容的提问来源于stack exchange,提问作者Andrei Deacu
相关产品推荐
相关产品推荐

