Stack QA — Vue d'ensemble¶
PerfShop embarque une stack complète de test parallèle à l'application elle-même. L'objectif pédagogique est de donner aux étudiants un environnement réaliste où ils peuvent écrire, versionner, exécuter et piloter des tests automatisés — exactement comme dans une vraie organisation — sans rien installer de plus que la stack Docker Compose de base.
Cette page donne la vue d'ensemble du workflow QA. Les pages suivantes descendent dans le détail de chaque composant.
Source de vérité
Toutes les informations de cette section proviennent des fichiers compose (docker-compose.desktop.yml, docker-compose.build.yml), des Dockerfiles custom (test-runner/Dockerfile), des configurations Squash Orchestrator (squash-orchestrator/*.yaml), et des scripts de seed (forgejo-seed/seed.py, squash-seed/seed.py).
Onze services, trois familles¶
flowchart TB
subgraph perf["Performance testing"]
direction TB
JM["perfshop-jmeter<br/>(justb4/jmeter:5.5)<br/>container idle"]
JMUI["perfshop-jmeter-ui<br/>(node:20-alpine)<br/>UI custom"]
JMUI -->|"docker exec"| JM
end
subgraph alm["ALM et exécution fonctionnelle"]
direction TB
SQDB[("perfshop-squash-db<br/>postgres:16")]
STM["perfshop-testmgmt<br/>Squash TM"]
ORCH["perfshop-orchestrator<br/>Squash Orchestrator"]
TR["perfshop-test-runner<br/>RF 7 + pytest 8 + SSH"]
SEL["perfshop-selenium<br/>standalone-chrome"]
SQDB --> STM
STM --> ORCH
ORCH -->|"SSH :22"| TR
TR -->|"WebDriver :4444"| SEL
end
subgraph dev["Scripting et SCM"]
direction TB
FG["perfshop-forgejo<br/>Git auto-hébergé"]
SUI["perfshop-scripts-ui<br/>éditeur/lanceur"]
SUI -->|"API Git + token"| FG
SUI -->|"docker exec"| TR
end
FG -.->|"polling SCM<br/>(clone + pull)"| STM
Les trois familles couvrent trois usages complémentaires :
| Famille | Rôle | Outil de pilotage |
|---|---|---|
| Performance testing | Tirs de charge JMeter, scénarios de montée en puissance, corrélation résultats ↔ backend | perfshop-jmeter-ui |
| ALM et exécution fonctionnelle | Gestion des exigences, des tests et des campagnes Squash TM, exécution orchestrée sur un runner distant | perfshop-testmgmt (Squash TM) |
| Scripting et SCM | Écriture, versionnement, lancement ad-hoc de scripts Robot Framework / pytest | perfshop-scripts-ui + perfshop-forgejo |
Le total est de 11 services QA — aucune consolidation possible, chaque brique a une responsabilité nette.
Workflow pédagogique typique¶
Voici un scénario de bout en bout qui mobilise l'ensemble de la stack QA :
sequenceDiagram
autonumber
actor E as Étudiant
participant SUI as perfshop-scripts-ui
participant FG as perfshop-forgejo
participant STM as perfshop-testmgmt
participant ORCH as perfshop-orchestrator
participant TR as perfshop-test-runner
participant SEL as perfshop-selenium
participant BE as perfshop-app
Note over E,BE: 1. Écriture et versionnement
E->>SUI: Ouvre l'éditeur web
E->>SUI: Modifie login.robot
SUI->>FG: Push branch (API Git + token CI)
Note over E,BE: 2. Exécution ad-hoc locale
E->>SUI: Clique "Run"
SUI->>TR: docker exec robot login.robot
TR->>SEL: Session WebDriver
SEL->>BE: GET /login + POST /api/auth/login
BE-->>SEL: Set-Cookie JSESSIONID
SEL-->>TR: Assertions OK
TR-->>SUI: Output Robot + log.html
SUI-->>E: Résultat dans l'UI
Note over E,BE: 3. Intégration dans Squash TM
STM->>FG: Poll SCM (toutes les N minutes)
FG-->>STM: Liste des scripts du dépôt
E->>STM: Crée un cas de test, lie le script login.robot
E->>STM: Lance l'exécution de la campagne
Note over E,BE: 4. Orchestration et exécution
STM->>ORCH: POST /jobs (token JWT RS512)
ORCH->>TR: SSH clé publique, copie script, lance robot
TR->>SEL: Session WebDriver
SEL->>BE: Scénario complet (login → panier → commande)
BE-->>SEL: Réponses
TR-->>ORCH: Exit code + stdout/stderr + log.html
ORCH-->>STM: Résultat d'exécution
Note over E,BE: 5. Consultation et investigation
STM-->>E: Rapport campagne (PASS/FAIL par cas)
E->>SEL: noVNC :7900 pour voir la session Chrome (si debug)
Ce workflow réunit toutes les briques de la stack QA en un seul flow. Aucune étape n'est artificielle — c'est le chemin normal qu'un ingénieur QA suit dans une vraie organisation utilisant Squash TM + Forgejo + Robot Framework.
Le rôle central du test-runner¶
perfshop-test-runner est le point de convergence : les scripts arrivent chez lui par deux chemins différents (UI ad-hoc via Scripts UI, ou orchestration Squash via SSH), il les exécute, et il produit les mêmes artefacts quel que soit le chemin d'origine.
flowchart LR
SUI["perfshop-scripts-ui<br/>(docker exec)"]
ORCH["perfshop-orchestrator<br/>(SSH :22)"]
TR["perfshop-test-runner<br/>Robot Framework 7.0<br/>+ pytest 8.0<br/>+ OpenSSH server<br/>+ squash-tf-services"]
SEL["perfshop-selenium:4444"]
LOGS["/rf-logs<br/>(bind mount)"]
SUI --> TR
ORCH --> TR
TR --> SEL
TR --> LOGS
LOGS -.lu par.-> PT["Promtail"]
LOGS -.lu par.-> VEC["Vector"]
Cette double entrée est possible parce que le test-runner embarque à la fois :
- Un serveur SSH (
openssh-server) pour l'orchestrateur - Un shell bash accessible via
docker execpour Scripts UI
Les logs produits dans /rf-logs/ sont collectés par Promtail ET par Vector, ce qui les rend visibles à la fois dans Loki (dashboard dashboard-jmeter → panel logs perfshop-test-runner) et dans OpenSearch (index perfshop-qa*).
Différences clés entre les deux modes d'exécution¶
| Aspect | Via Scripts UI (ad-hoc) | Via Squash TM (campagne) |
|---|---|---|
| Qui déclenche ? | Étudiant au clavier | Formateur ou automate |
| Transport | Socket Docker → docker exec |
SSH → ssh user@runner |
| Traçabilité | Logs dans /rf-logs, visibles dans Scripts UI |
Logs dans /rf-logs + résultat structuré dans Squash TM (PASS/FAIL par cas) |
| Versionnement | Le script est déjà en cours d'édition dans Forgejo | Le script est pulled depuis Forgejo via le plugin SCM Git de Squash TM |
| Reporting | Sortie Robot Framework brute + log.html | Campagne Squash TM avec historique, dashboard, assignations |
| Cas d'usage pédagogique | « J'écris un script, je veux voir s'il marche » | « Je joue une campagne de non-régression documentée » |
Les deux modes ne s'excluent pas : le même login.robot peut être exécuté en ad-hoc pendant le développement, puis intégré à une campagne Squash TM pour les exécutions planifiées.
JMeter — un flux parallèle¶
Le tir JMeter suit un flux complètement séparé des outils fonctionnels (Squash, Selenium, Robot Framework). Il n'y a pas d'orchestrateur, pas de SCM, pas de reporting centralisé — juste un container JMeter idle et une UI custom qui le pilote via le socket Docker.
sequenceDiagram
autonumber
actor F as Formateur
participant JMUI as perfshop-jmeter-ui
participant SOCK as /var/run/docker.sock
participant JM as perfshop-jmeter
participant BE as perfshop-app
participant PROM as Prometheus
participant GRAF as Grafana
F->>JMUI: Sélectionne un scénario .jmx
F->>JMUI: Configure vUsers, duration, rampup
JMUI->>SOCK: docker exec perfshop-jmeter<br/>jmeter -n -t scenario.jmx -l results.jtl ...
SOCK->>JM: Lance le tir
JM->>BE: Flood HTTP (selon scénario)
JM->>JM: Expose /metrics sur :9270 pendant le tir
PROM->>JM: Scrape /metrics :9270 (toutes les 5s)
PROM->>BE: Scrape /actuator/prometheus :9090 (toutes les 5s)
GRAF->>PROM: Query PromQL (panels dashboard-jmeter)
GRAF-->>F: Graphes temps réel
JM-->>JMUI: stdout + results.jtl
C'est un choix délibéré : un tir JMeter est une activité ponctuelle et centrée backend qui n'a pas besoin de toute la machinerie ALM. Le formateur lance un tir, observe le dashboard Grafana dashboard-jmeter, corrèle avec les métriques backend, et c'est tout.
Tableau récapitulatif des 11 services¶
| Service | Image | Port hôte par défaut | Rôle |
|---|---|---|---|
perfshop-jmeter |
justb4/jmeter:5.5 |
— | Moteur JMeter (idle entre les tirs) |
perfshop-jmeter-ui |
node:20-alpine (code monté) |
3005 | UI custom de pilotage JMeter |
perfshop-squash-db |
postgres:16 |
5433 | PostgreSQL dédié à Squash TM |
perfshop-testmgmt |
squashtest/squash-tm:latest |
8088 | ALM — exigences, tests, campagnes |
perfshop-orchestrator |
squashtest/squash-orchestrator:latest |
— | Pilotage SSH des exécutions |
perfshop-squash-seed |
python:3.11-slim |
— | Init du projet Squash TM (one-shot) |
perfshop-selenium |
selenium/standalone-chrome:latest |
4444 + 7900 | Selenium Grid + noVNC |
perfshop-test-runner |
perfshop-test-runner:latest (build local) |
— | RF 7 + pytest 8 + OpenSSH |
perfshop-forgejo |
codeberg.org/forgejo/forgejo:14 |
3009 | Git auto-hébergé |
perfshop-forgejo-seed |
python:3.11-slim |
— | Init compte CI + dépôt + token (one-shot) |
perfshop-scripts-ui |
node:20-alpine (code monté) |
3008 | Éditeur/lanceur de scripts |
Chaîne de dépendance au démarrage¶
L'ordre de démarrage des services QA est contraint par plusieurs healthchecks et dépendances :
flowchart TB
SQDB[("perfshop-squash-db<br/>healthcheck pg_isready")]
STM[("perfshop-testmgmt<br/>healthcheck /squash/isSquashAlive")]
FG[("perfshop-forgejo<br/>healthcheck /api/v1/version")]
FSEED["perfshop-forgejo-seed<br/>(one-shot)"]
SSEED["perfshop-squash-seed<br/>(one-shot)"]
SEL["perfshop-selenium"]
TR["perfshop-test-runner"]
ORCH["perfshop-orchestrator"]
SUI["perfshop-scripts-ui"]
JM["perfshop-jmeter"]
JMUI["perfshop-jmeter-ui"]
SQDB --> STM
STM --> ORCH
STM --> SSEED
FG --> FSEED
FSEED --> SSEED
FG --> SUI
TR --> ORCH
TR --> SUI
SEL --> TR
JM --> JMUI
Points-clés :
perfshop-squash-seedattend explicitement la complétion réussie deperfshop-forgejo-seed, parce qu'il a besoin du token CI Forgejo (stocké dans le volumeforgejo-token-data) pour configurer la connexion SCM entre Squash TM et le dépôt Git.perfshop-scripts-uiattend à la foisperfshop-forgejohealthy,perfshop-test-runnerdémarré, et le backendperfshop-app— il consomme les trois.perfshop-test-runnerdémarre dès que Selenium est démarré, sans attendre aucun healthcheck (Selenium répond vite ; le test-runner peut attendre une session WebDriver au moment voulu).
Pour aller plus loin¶
- Squash TM — configuration de l'ALM, JWT, plugin SCM
- Squash Orchestrator — pools YAML, pilotage SSH
- Selenium — Grid standalone Chrome, noVNC
- Test Runner — Dockerfile custom, RF 7, pytest 8
- JMeter — container idle, UI custom, plugin Prometheus
- Scripts UI — éditeur web, intégration Forgejo
- Forgejo — Git auto-hébergé, seed, token CI