需求跟踪汇总示例报表

Azure DevOps Services |Azure DevOps Server 2022 |2020 Azure DevOps Server

需求跟踪汇总报表基于 需求跟踪报告 ,并演示如何聚合一级汇总的指标。 例如,如果要使用用户情景跟踪要求,则可以使用本文中提供的查询聚合功能的数据。

下图中显示了一个示例。

Power BI 案例概述汇总报表的屏幕截图。

此报表针对它列出的每个要求显示以下信息:

  • 已完成工时百分比:进度栏,根据与要求关联的所有任务的已完成工时汇总显示已完成工时百分比。
  • 通过的测试:基于最近的测试运行通过的测试用例数。
  • 失败的测试:基于最近的测试运行失败的测试用例数。
  • 运行测试:执行的测试运行数。
  • 活动 bug:处于活动状态的链接 bug 数。
  • 已关闭的 bug:处于“已关闭”、“已完成”或“已完成”状态的链接 bug 的数量。

备注

仅通过基于要求的测试 套件链接的测试用例支持要求跟踪。 要求工作项(User Story (Agile) 、Product Backlog Item (Scrum) 、Requirement (CMMI) 或 Issue (Basic) )与手动测试执行之间的关联仅在测试用例通过 基于要求的测试套件链接时才形成。

报表回答的问题

需求跟踪报告可用于回答以下类型的问题。

工作进度

  • 每个要求的剩余工时量是否符合预期?
  • 是否首先实现排名靠前的要求?
  • 为每个要求定义了多少个测试? 有多少测试通过?
  • 正在实现哪些没有为其定义测试用例的要求?

质量进度

  • 针对每个要求运行了多少个测试用例,以及已通过多少个测试用例?
  • 每个要求有多少个活动 bug?
  • 是否针对正在测试的要求发现了 bug?
  • bug 是否正在解决,或者它们是否保持活动状态?

风险评估

  • 哪些要求存在风险?
  • 哪些要求不足以稳定发布?
  • 我们今天可以交付哪些要求?

重要

Power BI 集成和对分析服务的 OData 源的访问通常适用于 Azure DevOps Services 和 Azure DevOps Server 2020 及更高版本。 本文中提供的示例查询仅对 Azure DevOps Server 2020 及更高版本有效,并且取决于 v3.0-preview 或更高版本。 我们鼓励你使用这些查询并向我们提供反馈。

先决条件

  • 若要查看分析数据并查询服务,需要是具有 基本 访问权限或更高访问权限的项目的成员。 默认情况下,向所有项目成员授予查询 Analytics 和定义 Analytics 视图的权限。
  • 若要了解有关服务和功能启用以及常规数据跟踪活动的其他先决条件,请参阅 访问 Analytics 的权限和先决条件

备注

本文假定你已阅读 使用 OData 查询的示例报表概述 ,并基本了解 Power BI。

要使报表生成有用数据,需要执行以下任务:

  • 你已定义要求工作项,并将其分配给感兴趣的区域和迭代路径。 有关如何定义区域和迭代路径的信息,请参阅 定义区域路径定义迭代路径
  • 若要获取完成小时数的百分比,需要填写“ 完成工时 ”和 “剩余工时” 字段,这些任务或 bug 链接到 链接类型的要求。
  • 若要获取测试用例的执行状态,你将在与这些要求相对应的Test Plans中创建基于要求的测试套件。 通过看板添加的内联测试满足此先决条件,但链接到测试的要求则不满足。 若要了解详细信息,请参阅 创建测试计划和测试套件
  • 若要获取 bug 的状态,你将使用 链接类型创建 bug 并将其链接到要求。

示例查询

若要生成报表,必须将三个 Power BI 查询添加到 Power BI Desktop,然后将其链接。 每个查询 WorkItems 执行 或 TestPoints 实体集。

备注

以下部分提供的 Power BI 查询代码段包括扩展列和更改数据类型所需的数据转换。

查询区域和迭代路径

为了将报表范围限定为特定的区域和迭代路径,可以使用 和 IterationSK筛选查询AreaSK。 有关详细信息,请参阅 使用 OData Analytics 定义基本查询

备注

若要确定用于筛选或报表的可用属性,请参阅Azure Boards元数据参考。 可以使用 提供的 EntitySetNavigationPropertyBinding Path 值下EntityType的任何Property值筛选查询或返回属性。 每个对应 EntitySet 一个 EntityType。 若要详细了解每个值的数据类型,请查看为相应的 EntityType提供的元数据。

查询要求的完成小时数百分比

备注

WorkItemType根据所使用的进程更改 。 Scrum 模板支持 功能 ,基本模板分别支持 Epic 作为汇总工作项类型。

可以将下面列出的 Power BI 查询直接粘贴到 “获取数据空白>查询 ”窗口中。 有关详细信息,请参阅 使用 OData 查询的示例报表概述

let
    Source = OData.Feed("https://analytics.dev.azure.com/{organization}/{project}/_odata/v3.0-preview/WorkItems? 
$filter=( 
    IterationSK eq {iterationSK}
    and AreaSK eq {areaSK}
    and WorkItemType eq 'Feature'
)
&$expand=Descendants( 
    $apply=filter( CompletedWork ne null or RemainingWork ne null ) 
    /aggregate( 
        iif(CompletedWork ne null, CompletedWork, 0) with sum as SumCompletedWork, 
        iif(RemainingWork ne null, RemainingWork, 0) with sum as SumRemainingWork 
    ) 
    /compute( 
        (SumCompletedWork add SumRemainingWork) as TotalWork, 
        SumCompletedWork as SumCompleted 
    ) 
    /compute( 
        iif(TotalWork gt 0,(SumCompleted div cast(TotalWork, Edm.Double) mul 100), 0) as PercCompletedWork 
    ) 
)
&$select=WorkItemId, Title", null, [Implementation="2.0"]),
    #"Expanded Descendants" = Table.ExpandTableColumn(Source, "Descendants", {"SumCompletedWork", "SumRemainingWork", "TotalWork", "SumCompleted", "PercCompletedWork"}, {"Descendants.SumCompletedWork", "Descendants.SumRemainingWork", "Descendants.TotalWork", "Descendants.SumCompleted", "Descendants.PercCompletedWork"}),
    #"Changed Type" = Table.TransformColumnTypes(#"Expanded Descendants",{{"Descendants.SumCompletedWork", type number}, {"Descendants.SumRemainingWork", type number}, {"Descendants.TotalWork", type number}, {"Descendants.SumCompleted", type number}, {"Descendants.PercCompletedWork", type number}})
in
    #"Changed Type"

查询要求的测试执行状态

备注

若要确定用于筛选或报表的可用属性,请参阅 Test Plans Analytics 的元数据参考。 可以使用 提供的 EntitySetNavigationPropertyBinding Path 值下EntityType的任何Property值筛选查询或返回属性。 每个对应 EntitySet 一个 EntityType。 若要详细了解每个值的数据类型,请查看为相应的 EntityType提供的元数据。

可以将下面列出的 Power BI 查询直接粘贴到 “获取数据空白>查询 ”窗口中。 有关详细信息,请参阅 使用 OData 查询的示例报表概述

let
    Source = OData.Feed("https://analytics.dev.azure.com/{organization}/{project}/_odata/v3.0-preview/TestPoints? 
	$apply=filter(
	    (TestSuite/RequirementWorkItem/IterationSK eq {iterationSK}
    and TestSuite/RequirementWorkItem/AreaSK eq {areaSK}
    and TestSuite/RequirementWorkItem/Processes/any(p:p/BacklogType eq 'RequirementBacklog')
    and TestSuite/RequirementWorkItem/Processes/all(p:p/IsBugType eq false)
	))
	/compute(iif(TestSuite/RequirementWorkItem/Parent ne null, TestSuite/RequirementWorkItem/Parent/WorkItemId, 0) as ParentWorkItemId, 
	iif(TestSuite/RequirementWorkItem/Parent ne null, TestSuite/RequirementWorkItem/Parent/Title, 'Unparented') as ParentWorkItemTitle
	)/groupby(
	    (ParentWorkItemId, ParentWorkItemTitle), 
	    aggregate(
	        $count as TotalCount, 
	        cast(LastResultOutcome eq 'Passed', Edm.Int32) with sum as PassedCount, 
	        cast(LastResultOutcome eq 'Failed', Edm.Int32) with sum as FailedCount, 
            cast(LastResultOutcome eq 'Blocked', Edm.Int32) with sum as BlockedCount,
            cast(LastResultOutcome eq 'NotApplicable', Edm.Int32) with sum as NotApplicableCount,
	        cast(LastResultOutcome eq 'None', Edm.Int32) with sum as NotRunCount, 
	        cast(LastResultOutcome ne 'None', Edm.Int32) with sum as RunCount)
)", null, [Implementation="2.0"]),
    #"Changed Type" = Table.TransformColumnTypes(#"Source",{{"TotalCount", type number}, {"PassedCount", type number}, {"FailedCount", type number}, {"BlockedCount", type number}, {"NotApplicableCount", type number}, {"NotRunCount", type number}, {"RunCount", type number}})
in
    #"Changed Type"

备注

条目 TestSuite/RequirementWorkItem/... 指示工作项必须通过 基于要求 的测试套件链接到测试套件,如 先决条件中所述。

查询链接到要求的 bug 的状态

备注

WorkItemType根据所使用的进程更改 。 Scrum 模板支持 功能 ,基本模板分别支持 Epic 作为汇总工作项类型。

可以将下面列出的 Power BI 查询直接粘贴到 “获取数据空白>查询 ”窗口中。 有关详细信息,请参阅 使用 OData 查询的示例报表概述

let
    Source = OData.Feed("https://analytics.dev.azure.com/{organization}/{project}/_odata/v3.0-preview/WorkItems?
    $filter=(
        IterationSK eq {iterationSK}
        and AreaSK eq {areaSK}
        and WorkItemType eq 'Feature'
    )
&$expand=Descendants(
    $apply=filter(
        WorkItemType eq 'Bug'
    )
    /groupby(
        (State),
        aggregate($count as Count)
    )
)
&$select=WorkItemId,Title", null, [Implementation="2.0"]),
    #"Expanded Descendants" = Table.ExpandTableColumn(Source, "Descendants", {"State", "Count"}, {"Descendants.State", "Descendants.Count"}),
    #"Filtered Rows" = Table.SelectRows(#"Expanded Descendants", each [Descendants.Count] <> null and [Descendants.Count] <> ""),
    #"Pivoted Column" = Table.Pivot(#"Filtered Rows", List.Distinct(#"Filtered Rows"[Descendants.State]), "Descendants.State", "Descendants.Count", List.Sum),
    #"Changed Type" = Table.TransformColumnTypes(#"Pivoted Column",{{"Active", type number}, {"Closed", type number}})
in
    #"Changed Type"

替换字符串和查询明细

将以下字符串替换为值。 不要在替换中包含括号 {} 。 例如,如果组织名称为“Fabrikam”,请将 替换为 {organization}Fabrikam,而不是 {Fabrikam}

  • {organization} - 组织名称
  • {project} - 项目的名称
  • {iterationSK} - 与感兴趣的 迭代路径 关联的 GUID。 若要查找 GUID,请参阅 [../extend-analytics/wit-analytics.md#iterationsk] (返回特定迭代路径的 IterationSK)
  • {areaSK} - 与相关区域路径关联的 GUID。 若要查找 GUID,请参阅 [../extend-analytics/wit-analytics.md#areask] (返回特定区域路径) 的 AreaSK。

查询明细

下表描述了查询的每个部分。

查询部件

说明


$filter=( IterationSK eq {iterationSK} and AreaSK eq {areaSK} 和 WorkItemType eq 'Feature' ) '

仅返回指定迭代和区域下特征的数据。

filter( (TestSuite/RequirementWorkItem/IterationSK eq {iterationSK} and TestSuite/RequirementWorkItem/AreaSK eq {areaSK} and TestSuite/RequirementWorkItem/Processes/any(p:p/BacklogType eq 'RequirementBacklog') and TestSuite/RequirementWorkItem/Processes/all(p:p/IsBugType eq false)))

仅返回指定迭代和区域下选定积压工作要求项的数据。

&$expand=Descendants( $apply=filter( CompletedWork ne null or RemainingWork ne null )

展开“功能”的子项,并返回工作项的 “已完成工时 ”和 “剩余工时 ”数据。

&$expand=Descendants( $apply=filter( WorkItemType eq 'Bug' ) /groupby( (State), aggregate($count as Count) )

展开“功能”的子项并筛选 bug,按“状态”对返回数据进行分组,并按子项的总计数进行日照。

/aggregate($count as TotalCount,

聚合已筛选测试点中的数据,并将计数为 TotalCount

cast(LastResultOutcome eq 'Passed', Edm.Int32) with sum as PassedCount, cast(LastResultOutcome eq 'Failed', Edm.Int32) with sum as FailedCount, cast(LastResultOutcome eq 'Blocked', Edm.Int32) with sum as BlockedCount, cast(LastResultOutcome eq 'NotApplicable', Edm.Int32) with sum as NotApplicableCount, cast(LastResultOutcome eq 'None', Edm.Int32) with sum as NotRunCount, cast(LastResultOutcome ne 'None', Edm.Int32) with sum as RunCount)

聚合时,根据测试点的最新执行结果“ 已通过”、“ 失败”、“ 已阻止”、“ 不可应用”和 “无”求和求和。 此外,将最新结果不等于 None 的测试点的值求和,以获取总计 RunCount

/aggregate( iif(CompletedWork ne null, CompletedWork, 0) with sum as SumCompletedWork, iif(RemainingWork ne null, RemainingWork, 0) with sum as SumRemainingWork

跨筛选的工作项聚合 已完成 工时和 剩余 工时数据。

)/compute( (SumCompletedWork add SumRemainingWork) as TotalWork, SumCompletedWork as SumCompleted

计算 已完成工时剩余工时的总汇总。

)/compute( iif(TotalWork gt 0,(SumCompleted div cast(TotalWork, Edm.Double) mul 100), 0) as PercCompletedWork )

计算已完成的 wor 百分比。

创建表报表

  1. 在“建模”选项卡中,选择“管理关系并按列链接三个WorkItemId查询结果。
  2. “可视化效果”下,选择“ ”。
  3. 从三个 Power BI 查询中添加感兴趣的列。
  4. 选择 “总和 ”作为累加列的聚合,例如 “通过的测试 ”等。

    Power BI 选择“总和”作为聚合

此处, 身份验证方案 是两个用户情景的父功能。

Power BI 示例案例概述汇总报表的屏幕截图。