TFSReporter — Extension Azure DevOps
Génération de rapports de tests professionnels depuis Azure DevOps Test Plans — PDF, Excel, HTML.

Table des matières
Présentation
TFSReporter est une extension Azure DevOps qui s'intègre directement dans le menu Test Plans. Elle permet de générer des rapports de tests complets, incluant :
- Les résultats d'exécution (dernière exécution + historique)
- Une matrice de traçabilité complète (Test Case → User Story → Epic → Bugs)
- Des KPIs et métriques calculés automatiquement
- Des exports professionnels en PDF, Excel et HTML
L'extension fonctionne entièrement dans le navigateur, sans serveur backend.
Fonctionnalités
Rapport de tests
- Sélection du Test Plan et des Test Suites à inclure
- Récupération automatique des résultats de tests via l'API REST
- Dédoublonnage : les résultats sont groupés par Test Case, seul le plus récent est utilisé pour les KPIs
- Filtrage automatique de la suite racine (parent)
Matrice de traçabilité
- Lien Test Case → User Story / PBI (via relations
TestedBy, Hierarchy)
- Lien User Story → Epic (via relation parent)
- Collecte des Bugs liés aux Test Cases et User Stories
- Métriques de couverture : % de US avec au moins un TC, bugs ouverts, etc.
- Titre du rapport, référence projet, numéro de change
- Contacts IT et métier
- Domaine fonctionnel, application, périmètre
- Environnement (DEV / QA / UAT / PREPROD / PROD)
- Testeur, approbateur et rôle
Exports
| Format |
Contenu |
| PDF |
Rapport paginé avec page de garde, KPIs, résultats, traçabilité, graphiques |
| Excel |
Classeur multi-onglets (Résultats, Suites, Traçabilité) avec filtres et mise en forme |
| HTML |
Rapport interactif autonome avec graphiques Chart.js et styles inline |
Interface
- 4 onglets dans le panneau de rapport :
- Résultats — Derniers résultats avec tooltip des runs passés
- Traçabilité — Matrice TC → US → Epic → Bugs avec liens cliquables
- Bugs — Liste des bugs avec badges d'état colorés
- Historique complet — Tous les résultats avec indicateur du plus récent
Captures d'écran
L'icône de l'extension est située dans images/icon.png.
Ajouter des captures d'écran dans le dossier images/ et les référencer ici.
Architecture
┌────────────────────────────────────────────────────────┐
│ Azure DevOps │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Test Plans Hub → TFSReporter (iframe) │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ React 18 + MUI 5 + Zustand │ │ │
│ │ │ ┌────────┐ ┌────────┐ ┌───────────────┐ │ │ │
│ │ │ │Metadata│ │ Plan │ │ Report Panel │ │ │ │
│ │ │ │ Form │ │Selector│ │ (4 tabs) │ │ │ │
│ │ │ └────────┘ └────────┘ └───────────────┘ │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ REST API (Bearer token) │
│ │ │
│ ┌─────────────┐ ┌───────────┐ ┌──────────────────┐ │
│ │ Test Plans │ │ Test │ │ Work Item │ │
│ │ API │ │ Runs API │ │ Tracking API │ │
│ └─────────────┘ └───────────┘ └──────────────────┘ │
└────────────────────────────────────────────────────────┘
Prérequis
| Outil |
Version minimum |
| Node.js |
18+ |
| npm |
9+ |
| TypeScript |
5.3+ |
| tfx-cli |
0.16+ (inclus en devDependency) |
| Azure DevOps |
Services (Cloud) ou Server 2019+ |
Compte publisher
Un compte publisher sur le Visual Studio Marketplace est nécessaire pour publier l'extension. Le publisher actuel est Kisskool.
Installation du projet
# Cloner le dépôt
git clone https://github.com/AlexThibaud1976/TFS_Reporter_Addon.git
cd TFS_Reporter_Addon
# Installer les dépendances
npm install
Développement
# Build en mode watch (développement)
npm run dev
# Build de production
npm run build
# Nettoyer dist/ et releases/
npm run clean
Scripts npm disponibles
| Script |
Commande |
Description |
dev |
webpack --mode development --watch |
Build dev avec watch |
build |
webpack --mode production |
Build de production optimisé |
package |
build + tfx extension create |
Build + création du VSIX |
package:dev |
build + tfx extension create --rev-version |
Build + VSIX avec auto-incrément version |
clean |
rimraf dist releases |
Suppression des dossiers de sortie |
Build et packaging
# Build + création du fichier VSIX
npm run package
Le fichier VSIX est généré dans le dossier releases/ :
releases/Kisskool.tfsreporter-1.1.1.vsix
Taille du bundle (production)
| Chunk |
Taille |
Contenu |
framework.js |
~385 KB |
React, MUI, Emotion, Zustand |
sdk.js |
~7.6 KB |
Azure DevOps Extension SDK + API |
hub.js |
~54 KB |
Code applicatif (composants, services, store) |
| Total initial |
~447 KB |
Chargement au démarrage |
| Chunks async |
~1.85 MB |
jsPDF, ExcelJS, Chart.js (chargés à la demande) |
Déploiement sur Azure DevOps
1. Publier l'extension (première fois)
npx tfx extension publish --manifest-globs vss-extension.json --token <PAT>
2. Mettre à jour l'extension
npx tfx extension publish --manifest-globs vss-extension.json --token <PAT>
Le PAT (Personal Access Token) doit avoir le scope Marketplace (Publish).
3. Partager avec une organisation
- Aller sur marketplace.visualstudio.com/manage
- Sélectionner l'extension TFSReporter
- Cliquer sur Share/Unshare → ajouter le nom de l'organisation Azure DevOps
- Dans Azure DevOps : Organization Settings → Extensions → Shared → Installer
4. Accéder à l'extension
Dans Azure DevOps :
- Naviguer vers Test Plans
- L'onglet TFSReporter apparaît dans la barre de navigation du hub
Configuration des scopes
L'extension requiert les permissions suivantes, déclarées dans vss-extension.json :
| Scope |
Description |
vso.test |
Lecture des Test Plans, Suites, Cases et Résultats |
vso.test_write |
Écriture sur les données de test (réservé pour usage futur) |
vso.work |
Lecture des Work Items (User Stories, Epics, Bugs) pour la traçabilité |
Structure du projet
TFS_Reporter_Addon/
├── vss-extension.json # Manifeste de l'extension Azure DevOps
├── package.json # Dépendances npm et scripts
├── tsconfig.json # Configuration TypeScript
├── webpack.config.js # Configuration Webpack (code splitting)
├── README.md # Ce fichier
├── GUIDE_ETAPES_MANUELLES.md # Guide d'installation pas à pas
│
├── images/
│ ├── icon.png # Icône de l'extension (Marketplace)
│ └── ref.png # Image de référence
│
├── releases/ # Fichiers VSIX générés
│ └── Kisskool.tfsreporter-X.Y.Z.vsix
│
├── dist/ # Sortie Webpack (généré)
│ └── hub/
│ ├── index.html
│ ├── hub.js
│ ├── framework.js
│ ├── sdk.js
│ └── chunks/ # Chunks async (jsPDF, ExcelJS, Chart.js)
│
└── src/
├── hub/
│ ├── hub.tsx # Point d'entrée — initialisation SDK
│ └── index.html # Template HTML (Webpack)
│
├── models/
│ └── types.ts # Tous les types TypeScript
│
├── store/
│ └── report.store.ts # Store Zustand (état global)
│
├── hooks/
│ └── useReportActions.ts # Hook — actions export (lazy loading)
│
├── services/
│ ├── ado-api.service.ts # Service API REST Azure DevOps
│ ├── pdf.service.ts # Export PDF (jsPDF + autoTable)
│ ├── excel.service.ts # Export Excel (ExcelJS)
│ └── html.service.ts # Export HTML (template inline)
│
└── components/
├── App.tsx # Composant racine
├── layout/
│ └── MainLayout.tsx # Layout principal (entête + contenu)
├── forms/
│ └── MetadataForm.tsx # Formulaire métadonnées (14 champs)
├── common/
│ ├── PlanSelector.tsx # Sélecteur Plan + Suites
│ └── ReportPanel.tsx # Panneau rapport (4 onglets)
└── pages/
├── ReportPage.tsx # Page principale
└── OtherPages.tsx # Pages supplémentaires
Stack technique
| Catégorie |
Technologie |
Version |
Usage |
| UI |
React |
18.2 |
Composants |
| UI |
MUI (Material UI) |
5.15 |
Design system |
| UI |
Emotion |
11.11 |
CSS-in-JS |
| State |
Zustand |
4.4 |
Store global |
| Charts |
Chart.js + react-chartjs-2 |
4.4 / 5.2 |
Graphiques (async) |
| PDF |
jsPDF + jspdf-autotable |
2.5 / 3.8 |
Export PDF (async) |
| Excel |
ExcelJS |
4.4 |
Export Excel (async) |
| SDK |
azure-devops-extension-sdk |
4.2 |
Intégration ADO |
| API |
azure-devops-extension-api |
4.266 |
Types API |
| Build |
Webpack |
5.89 |
Bundling + code splitting |
| Language |
TypeScript |
5.3 |
Typage statique |
Modèle de données
Types principaux
// Métadonnées métier (14 champs)
ProjectMetadata { reportTitle, projectRef, changeNumber, itContact, ... }
// Plan / Suite / Case
TestPlanSummary { id, name, state, iteration, startDate, endDate }
TestSuiteSummary { id, name, planId, suiteType, hasParentSuite, testCases[] }
TestCaseSummary { id, title }
// Résultats
TestResultItem { id, testCaseId, testCaseName, suiteName, outcome,
durationInMs, runBy, completedDate, isLatest, associatedBugs[] }
// Traçabilité
TraceabilityRow { testCaseId, testCaseName, latestOutcome,
requirement (US/PBI), epic, bugs[] }
// Métriques
ReportMetrics { total, passed, failed, blocked, passRate, ... }
TraceabilityMetrics { totalTestCases, linkedToRequirement, linkedToEpic,
totalBugs, openBugs, coverageRate }
// Données complètes
ReportData { plan, suites, results, bugs, metrics,
traceability, traceabilityMetrics, generatedAt }
Flux de données
TestPlan → TestSuites (filtré sans parent)
→ TestCases par suite
→ TestResults par run (groupés, isLatest)
→ WorkItems (TC → US → Epic, Bugs)
→ ReportData → Export (PDF / Excel / HTML)
API Azure DevOps utilisées
Test Plans API
| Endpoint |
Usage |
GET {project}/_apis/testplan/plans |
Liste des plans de test |
GET {project}/_apis/testplan/plans/{planId}/suites |
Suites d'un plan |
GET {project}/_apis/testplan/plans/{planId}/suites/{suiteId}/testcase |
Cas de test d'une suite |
Test Runs API
| Endpoint |
Usage |
GET {project}/_apis/test/runs |
Runs d'un plan |
GET {project}/_apis/test/runs/{runId}/results |
Résultats d'un run |
GET {project}/_apis/test/runs/{runId}/results/{resultId}/bugs |
Bugs liés |
Work Item Tracking API
| Endpoint |
Usage |
GET _apis/wit/workitems?ids={ids}&$expand=Relations |
Work items avec relations |
Authentification
Toutes les requêtes utilisent un Bearer token obtenu via SDK.getAccessToken(). Aucun PAT n'est nécessaire à l'exécution.
Optimisation du bundle
Code splitting (Webpack 5)
L'extension utilise une stratégie de code splitting en 3 niveaux :
framework.js (~385 KB) — React, MUI, Emotion, Zustand → chargé au démarrage
sdk.js (~7.6 KB) — SDK Azure DevOps → chargé au démarrage
- Chunks async — jsPDF, ExcelJS, Chart.js → chargés à la demande uniquement
Lazy loading des exports
Les services d'export (PDF, Excel, HTML) sont importés dynamiquement via React.lazy() et import() :
const { generatePdf } = await import('@services/pdf.service');
Cela évite de charger ~1.85 MB de librairies tant que l'utilisateur ne clique pas sur un bouton d'export.
Historique des versions
| Version |
Date |
Changements |
| 1.1.1 |
2025-02 |
Fix noms de suites, noms TC dans traçabilité, détection US/Bugs améliorée, fallback WIT API triple |
| 1.1.0 |
2025-02 |
Matrice de traçabilité (TC→US→Epic→Bugs), filtrage suite parent, dédoublonnage résultats, 4 onglets rapport |
| 1.0.4 |
2025-02 |
API REST directe avec Bearer token (remplacement SDK client) |
| 1.0.2 |
2025-02 |
Optimisation bundle (2.6 MB → 534 KB), code splitting |
| 1.0.1 |
2025-02 |
Fix visibilité dans le menu Test Plans |
| 1.0.0 |
2025-02 |
Version initiale — sélection plan/suites, rapport PDF/Excel/HTML |
Dépannage
L'extension n'apparaît pas dans Test Plans
- Vérifier que l'extension est installée dans l'organisation (pas seulement publiée)
- Vérifier que le target est
ms.vss-test-web.test-hub-group dans vss-extension.json
- Vider le cache du navigateur et rafraîchir
Le dropdown des plans est vide
- Vérifier que le scope
vso.test est bien déclaré
- Ouvrir la console (F12) et chercher les erreurs réseau
- Le token Bearer peut avoir expiré → rafraîchir la page
La traçabilité affiche "—" partout
- Ouvrir la console (F12) et chercher les logs
[Traçabilité] et [WIT]
- Vérifier que le scope
vso.work est déclaré
- Vérifier que les Test Cases ont bien des liens vers des User Stories dans Azure DevOps
- Les relations supportées :
TestedBy-Forward, TestedBy-Reverse, Hierarchy-Reverse
Les noms de suites sont vides
- L'API
/test/runs/{id}/results ne retourne pas toujours testSuite.name
- L'extension enrichit automatiquement les noms depuis les suites chargées
- Si le problème persiste, vérifier les logs console
[Suite enrichment]
Erreur CORS ou 401
- L'extension doit être chargée dans Azure DevOps (iframe), pas en standalone
- Le
SDK.init() doit être appelé avant toute requête API
- Vérifier les scopes dans
vss-extension.json
Le VSIX ne se génère pas
# Vérifier que tfx-cli est installé
npx tfx --version
# Rebuild complet
npm run clean
npm install
npm run package
Licence
Extension privée — usage interne uniquement.
Auteur
Publisher : Kisskool
Extension ID : tfsreporter
Repository : github.com/AlexThibaud1976/TFS_Reporter_Addon