如何统计Azure DevOps构建流水线测试的通过/失败/弃用数量?
统计Azure DevOps构建流水线测试结果数量的解决方案
问题背景
需要统计Azure DevOps构建流水线中测试的通过、失败、弃用数量,调用Test Runs API时遇到以下问题:
- 初始执行代码时,控制台输出Azure DevOps登录页面HTML,认证失败;
- 对Personal Access Token(PAT)做Base64编码后,请求返回400错误,无法获取测试运行数据;
- 调整认证方式后,API返回大量测试用例结果,但代码持续输出通过的测试用例,无法正确统计各类结果数量。
问题原因及修复方案
认证错误
- 错误原因:Basic认证要求格式为
用户名:PAT(用户名可留空),需编码:+PAT而非直接编码PAT;同时错误设置了Content-Type为application/json-patch+json,GET请求无需此类型。 - 修复:生成
:{PAT}的Base64编码作为认证头,设置Content-Type为application/json。
- 错误原因:Basic认证要求格式为
统计逻辑错误
- 错误原因:之前的代码按测试用例名称计数,而非按测试结果类型(outcome)统计,导致无法统计通过、失败等结果的数量。
- 修复:将
Counter的统计键改为outcome字段,直接累加各类结果的数量。
修正后的完整代码
import requests import base64 from datetime import datetime from dateutil.relativedelta import relativedelta from collections import Counter # 配置参数 organization = "你的组织名" project = "你的项目名" personal_access_token = "你的PAT" pipeline_id = "你的流水线ID" # 时间范围:最近一周 end_date = datetime.now() start_date = end_date - relativedelta(weeks=1) start_date_str = start_date.strftime("%Y-%m-%dT%H:%M:%SZ") end_date_str = end_date.strftime("%Y-%m-%dT%H:%M:%SZ") # 构建API请求URL:获取指定流水线的测试运行 test_runs_url = f"https://dev.azure.com/{organization}/{project}/_apis/test/runs?pipelineId={pipeline_id}&minLastUpdatedDate={start_date_str}&maxLastUpdatedDate={end_date_str}&api-version=7.1-preview.3" # 生成认证头 credentials = f":{personal_access_token}" encoded_credentials = base64.b64encode(credentials.encode("utf-8")).decode("utf-8") headers = { "Authorization": f"Basic {encoded_credentials}", "Content-Type": "application/json" } # 获取所有测试运行 response = requests.get(test_runs_url, headers=headers) if response.status_code != 200: print(f"获取测试运行失败,状态码: {response.status_code}") print(response.text) exit() test_runs = response.json()["value"] test_outcomes_counter = Counter() # 遍历每个测试运行,获取详细测试结果 for test_run in test_runs: test_run_id = test_run["id"] # 获取该测试运行的所有测试结果 test_results_url = f"https://dev.azure.com/{organization}/{project}/_apis/test/Runs/{test_run_id}/results?api-version=7.1-preview.3" test_results_response = requests.get(test_results_url, headers=headers) if test_results_response.status_code == 200: test_results = test_results_response.json()["value"] for result in test_results: outcome = result.get("outcome", "Unknown") # 按结果类型统计数量 test_outcomes_counter[outcome] += 1 # 可选:打印单个测试用例结果,不需要可注释 # test_case_name = result["testCase"]["name"] # print(f"测试用例: {test_case_name}, 结果: {outcome}") # 输出最终统计结果 print("\n=== 测试结果统计 ===") for outcome, count in test_outcomes_counter.items(): print(f"{outcome}: {count}") # 可选:统计最频繁失败的测试用例,不需要可注释 # failed_cases = Counter() # for test_run in test_runs: # test_run_id = test_run["id"] # test_results_url = f"https://dev.azure.com/{organization}/{project}/_apis/test/Runs/{test_run_id}/results?api-version=7.1-preview.3" # test_results_response = requests.get(test_results_url, headers=headers) # if test_results_response.status_code == 200: # test_results = test_results_response.json()["value"] # for result in test_results: # if result.get("outcome") == "Failed": # test_case_name = result["testCase"]["name"] # failed_cases[test_case_name] += 1 # if failed_cases: # most_frequent = failed_cases.most_common(1)[0] # print(f"\n最频繁失败的测试用例: {most_frequent[0]} (出现次数: {most_frequent[1]})") # else: # print("\n无失败测试用例")
额外说明
- API版本:使用
7.1-preview.3版本,兼容性更好,功能更完整; - 分页处理:若测试结果数量超过API默认返回上限,需处理
continuationToken参数来获取全部数据; - PAT权限:确保你的PAT拥有
Test Management的Read权限,否则会出现权限不足错误。
内容的提问来源于stack exchange,提问作者Buxior Engineer
相关产品推荐
相关产品推荐

