Test Dashboard — Azure DevOps Extension

A testing dashboard for Azure DevOps focused on Test Plans, Test Cases, and execution results. It ships two contributions:
- Test Dashboard hub — a full-page experience under the Test Plans area with four tabs:
- Dashboard — a sprint-scoped analytics view (see below).
- Test Plans — every plan in the project with state, area/iteration paths, and dates.
- Test Cases — browse cases by plan → suite, with state and automation status.
- Execution Results — overall pass/fail/blocked summary plus the most recent test runs.
- Test Execution Summary widget — an at-a-glance dashboard tile showing the pass rate and outcome breakdown across recent runs.
Built with React + the official azure-devops-ui Formula design system and the azure-devops-extension-sdk / azure-devops-extension-api REST clients.
Sprint dashboard
The Dashboard tab has dependent Release → Sprint dropdowns that default to the
current sprint (the one whose start/finish dates contain today). Six widgets re-query
whenever the selection changes:
- Test Execution Outcome — donut + stacked bar of passed/failed/blocked/N-A/not-run.
- Test Execution Outcome by User Story — outcome per requirement-based suite's user story.
- Open Bugs by Priority — donut grouped by priority.
- Open Bugs by Assignee & State — stacked bars per assignee, segmented by state.
- Bugs Root Cause Category — bars grouped by root-cause field.
- Open Bugs — Blocker & High Priority — count + actionable list of P1/P2 / critical-high bugs.
Assumptions (adjust in code if your process differs)
- Release/Sprint = the iteration tree. Top-level iteration nodes are treated as Releases
and their children as Sprints (
WorkItemDataService.getIterationTree).
- "Open bug" = a
Bug whose state is not Closed, Done, or Removed
(CLOSED_STATES in WorkItemDataService).
- Root Cause is read from whichever bug field ref-name contains
RootCause / Root Cause
(ROOT_CAUSE_HINTS); falls back to Unspecified.
- Blocker & high = priority 1/2 or severity Critical/High (
isBlockerOrHigh).
- Test outcomes are scoped by plan iteration — plans whose
iteration path is the selected
sprint or a descendant (TestDataService.getPlansForIteration). "By user story" reads
requirement-based suites and their linked work items.
Project layout
src/
common/ Shared helpers (SDK init, async hook, status/empty views, outcome bar, table)
services/ TestDataService — thin wrapper over the Test Plan + Test REST clients
hub/ Full-page hub (Hub.tsx + components/)
widget/ Dashboard widget (Widget.tsx)
vss-extension.json Extension manifest (contributions, scopes, files)
webpack.config.js One bundle per contribution iframe
Prerequisites
Setup
npm install
Then set your publisher id in vss-extension.json (replace your-publisher-id).
Develop
npm run build:dev # one-off development build into ./dist
npm run watch # rebuild on change
npm run lint # type-check only (tsc --noEmit)
Package & publish
npm run package # builds production bundles and produces a .vsix in ./dist
Then either:
Finally, share the extension with your organization and install it from the Marketplace. After installing:
- Open Test Plans → Test Dashboard for the hub.
- On any team Dashboard, click Edit → Add widget → Test Execution Summary.
Required scopes
| Scope |
Why |
vso.test |
Read test plans, suites, points, runs, results |
vso.work |
Read work-item fields on test cases |
vso.project |
Resolve the current project context |
Azure DevOps Server (on-prem) compatibility
The extension runs on Azure DevOps Services and Azure DevOps Server 2022.1 (on-prem).
All REST/base URLs are resolved from the collection at runtime via the SDK location service
(src/common/baseUrl.ts) instead of hard-coding dev.azure.com, so
work-item links, AI comments, wiki publishing, and the current-iteration lookup all use your
server's collection URL.
To install on Server: build the .vsix, then upload it via Collection Settings → Extensions →
Manage extensions → Upload, and install it into the collection. Notes:
- Requires Server 2022.1 (REST API 7.1). On older servers the wiki/comment calls
(
api-version=7.1 / 7.1-preview.3) may need lowering.
- The AI review (Claude) calls the Anthropic API directly from the browser — the server must
allow outbound HTTPS to
api.anthropic.com, or leave the Claude key unset to skip it.
Notes
img/logo.png is a placeholder — replace it with your own 128×128 icon before publishing.
- The widget has no configuration UI; it summarizes the last 50 test runs in the project. Add a config contribution if you want per-tile filtering.
- Data volume: the Execution Results tab and the widget read recent runs (cheap, pre-aggregated). Per-plan point aggregation (
getPlanOutcomeSummary) walks every suite and is intended for on-demand use.