要求跟踪示例报告

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

可以使用要求跟踪报告跟踪属于“要求”类别的工作项的质量。 “要求”类别包括工作项,如用户情景(敏捷)、产品积压工作项(Scrum)、问题(基本)和要求(CMMI)。 若要了解有关工作项类别的详细信息,请参阅 跟踪用户情景、问题、bug 和其他工作项

下图显示了要求跟踪报表的示例。

Power BI 要求跟踪报表的屏幕截图。

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

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

注意

仅支持通过 基于要求的测试套件链接的测试用例进行要求跟踪。 要求工作项(User Story(Agile)、产品积压工作项(Scrum)、要求(CMMI)、要求(基本)和手动测试执行之间的关联仅在测试用例通过基于要求的测试套件链接时形成。

报告解答的问题

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

工作进度

  • 每个要求剩余的工作量是否与预期相对应?
  • 是否首先实施排名靠前的要求?
  • 为每个要求定义了多少个测试? 通过多少个测试?
  • 正在实施哪些要求,这些要求没有为其定义测试用例?

质量进度

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

风险评估

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

重要

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

先决条件

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

注意

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

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

示例查询

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

注意

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

注意

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

查询区域和迭代路径

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

查询满足要求的小时数百分比

注意

以下查询适用于敏捷过程,因为它定义了 Remaining Work 工作项和 Completed Work 字段。

可以将下面列出的 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 Processes/any(p:p/BacklogType eq 'RequirementBacklog') 
        and Processes/all(p:p/IsBugType eq false)
    )
    &$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"

查询要求的测试执行状态

注意

若要确定用于筛选器或报表目的的可用属性,请参阅 测试计划分析的元数据参考。 可以使用 提供的 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(TestSuite/RequirementWorkItem/WorkItemId as WorkItemId, TestSuite/RequirementWorkItem/Title as WorkItemTitle)
    /groupby(
        (WorkItemId, WorkItemTitle),
        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 的状态

可以将下面列出的 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 Processes/any(p:p/BacklogType eq 'RequirementBacklog') 
        and Processes/all(p:p/IsBugType eq false)
    )
    &$expand=Links(
        $apply=filter(
            (LinkTypeName eq 'Child' or LinkTypeName eq 'Related')
            and TargetWorkItem/WorkItemType eq 'Bug'
        )
        /groupby(
            (TargetWorkItem/State),
            aggregate($count as Count)
        )
    )&$select=WorkItemId,Title", null, [Implementation="2.0"]),
    #"Expanded Links" = Table.ExpandTableColumn(Source, "Links", {"TargetWorkItem", "Count"}, {"Links.TargetWorkItem", "Links.Count"}),
    #"Expanded Links.TargetWorkItem" = Table.ExpandRecordColumn(#"Expanded Links", "Links.TargetWorkItem", {"State"}, {"Links.TargetWorkItem.State"}),
    #"Filtered Rows" = Table.SelectRows(#"Expanded Links.TargetWorkItem", each [Links.Count] <> null and [Links.Count] <> ""),
    #"Pivoted Column" = Table.Pivot(#"Filtered Rows", List.Distinct(#"Filtered Rows"[Links.TargetWorkItem.State]), "Links.TargetWorkItem.State", "Links.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} )'

仅返回所选迭代、区域和积压工作项的数据。

Processes/any(p:p/BacklogType eq 'RequirementBacklog')

以这样的方式筛选工作项,使其至少应属于“要求”类别,以处理与其关联的至少一个进程。

Processes/all(p:p/IsBugType eq false)

获取要求时省略 bug 类型工作项。 在基本进程模板中,问题工作项也是 bug 类型,因此对于基本进程,请从查询中删除此子句。

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) ) )

仅根据迭代和区域返回所选要求的数据。

/aggregate($count as TotalCount,

聚合筛选的测试点中的数据,其计数为 TotalCount

cast(LastResultOutcome eq 'Passed', Edm.Int32) with sum as Passed

聚合时,类型强制转换测试点将最新的执行结果“传递”到 1,并将其汇总为“”Passed指标。

&$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 )

计算已完成的 wor 百分比。

创建表报表

若要创建报表,请执行以下步骤:

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

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

报表应如下图所示。

Power BI 要求跟踪报表的屏幕截图