ADR-0002 passa ad Accettata per Claude Code e Codex con l'esito delle prove reali: id di sessione da thread.started, output JSONL, risposta = ultimo agent_message, ripresa senza -s e sola lettura via sandbox_mode, -- prima del prompt. MVP, ROADMAP, INSTALL e README descrivono l'interruttore CLI, la nuova opzione --engine e il problema del modello predefinito che richiede un Codex più recente. TESTING.md aggiunge le righe CX, EN e ST-12. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
53 lines
5.4 KiB
Markdown
53 lines
5.4 KiB
Markdown
# ADR-0003 — Strategia di test e regola "nuova funzione = nuovi test"
|
|
|
|
- **Stato**: Proposta
|
|
- **Data**: 2026-10-15
|
|
- **Collegato a**: [ADR-0001](0001-gui-multipiattaforma-avalonia.md), [ADR-0002](0002-motori-cli-claude-codex-antigravity.md)
|
|
|
|
## Contesto
|
|
Oggi non esistono test. L'app gira su due sistemi operativi, ha una CLI, una GUI e una dipendenza esterna (`claude`) che non si può chiamare nei test: costa, è lenta e non è deterministica. Con l'arrivo di altri motori (ADR-0002) la superficie da proteggere cresce. Serve una strategia che garantisca **copertura completa** e che renda i test parte del lavoro di ogni nuova funzione.
|
|
|
|
## Criteri di decisione
|
|
1. Nessun test dipende da `claude`, `codex`, `agy`, dalla rete o da un account.
|
|
2. Gli stessi test girano su Windows e Linux, senza schermo (CI senza display).
|
|
3. Copertura misurata e con soglia che fa fallire la build, non solo un numero da guardare.
|
|
4. Ogni requisito scritto nei doc è tracciabile a uno o più test.
|
|
5. Costo basso per aggiungere un test: il codice deve essere progettato per essere testabile.
|
|
|
|
## Decisione
|
|
- **Regola**: una funzione, correzione o modifica di comportamento non è finita finché non ha test che la coprono, **nello stesso commit**. Una correzione di bug parte da un test che fallisce. La regola e il flusso sono in [TESTING.md](../TESTING.md).
|
|
- **Piano dei test come documento**: [TESTING.md](../TESTING.md) è l'unica sorgente della matrice requisito → test e della politica di copertura. Gli altri doc la richiamano con un link.
|
|
- **Strumenti**: xUnit come framework; `Avalonia.Headless` (con l'integrazione xUnit) per i test della GUI senza schermo; `coverlet` per la copertura. Le versioni compatibili con Avalonia 12 e .NET 10 vanno verificate (vedi sotto).
|
|
- **Doppio di `claude`**: un piccolo eseguibile di test, `FakeClaude`, scritto in C# e compilato insieme ai test. Registra argomenti, cartella di lavoro e stdin, e risponde in base a variabili d'ambiente (testo, stderr, exit code, ritardo). Essendo un eseguibile nativo funziona uguale su Windows e Linux (uno script `.sh` o `.cmd` non sarebbe avviabile direttamente come `claude`).
|
|
- **Livelli**: unitari (Core, ViewModel, renderer markdown), componenti GUI headless (finestra, template, tastiera), end-to-end sull'eseguibile pubblicato (CLI e codice 127) e smoke di publish per `win-x64` e `linux-x64`.
|
|
- **Predisposizioni di testabilità** nel codice (da fare insieme ai primi test):
|
|
- `ChatStore` diventa un'istanza con cartella iniettata, non uno statico legato a `LocalApplicationData`.
|
|
- L'esecuzione dei motori sta dietro un'interfaccia (`IEngineRunner`) iniettata nel ViewModel; l'implementazione reale resta in `Core/EngineRunner.cs`. I test del ViewModel usano un finto runner; quelli di `EngineRunner` usano `FakeClaude` (che con la configurazione giusta imita anche Codex).
|
|
- La conferma di eliminazione, gli appunti e il focus sono già delegati (`ConfirmDelete`, `CopyText`, `FocusInput`) e restano sostituibili.
|
|
- Gli ADR-0002 (motori) richiedono che ogni motore abbia la propria batteria di test sugli argomenti e sul parser dell'output.
|
|
- **Struttura del repo**: codice dell'app in `src/agent-wiki-ui/`, test in `tests/`, soluzione unica alla radice. Così il globbing del csproj dell'app non include i sorgenti dei test. Il progetto dell'app espone gli `internal` ai test con `InternalsVisibleTo`.
|
|
- **Porte di qualità**: copertura minima per area (in TESTING.md); `dotnet test` con copertura deve passare su Windows e Linux. Il fornitore di CI non è ancora scelto: i comandi sono indipendenti dal fornitore e vivono nel repo.
|
|
|
|
## Opzioni considerate
|
|
| Opzione | Esito | Motivo |
|
|
|---|---|---|
|
|
| Test manuali con checklist | Scartata | Non scala, non gira in CI, non protegge dalle regressioni. |
|
|
| Test solo unitari sulla logica | Scartata | La GUI e la CLI reale (exit code, 127, cartella di lavoro, stdin) resterebbero scoperte. |
|
|
| Test GUI con screenshot di riferimento | Rinviata | Font e rendering cambiano tra Windows e Linux: i confronti pixel sono instabili. Si usano asserzioni sull'albero visuale; gli screenshot restano come artefatti da guardare. |
|
|
| `claude` finto come script | Scartata | Su Windows `claude` si avvia direttamente (senza `cmd /c`): serve un eseguibile. |
|
|
| **xUnit + Headless + FakeClaude + coverlet** | **Scelta** | Copre tutti i livelli, senza dipendenze esterne, su entrambi i sistemi. |
|
|
|
|
## Conseguenze
|
|
**Positive**: regressioni intercettate su entrambi i sistemi; requisiti tracciabili; i motori aggiuntivi si aggiungono con test di contratto uniformi.
|
|
**Negative / costi**: un refactoring iniziale per iniettare cartella dati e runner; la struttura `src/` + `tests/` sposta file; la soglia di copertura obbliga a mantenere i test anche per codice di interfaccia; i test headless sono più lenti degli unitari.
|
|
|
|
## Da verificare
|
|
- [ ] Versioni di xUnit, `Avalonia.Headless` (integrazione xUnit) e `coverlet` compatibili con Avalonia 12 e .NET 10, e `dotnet test` funzionante con la soluzione.
|
|
- [ ] `Avalonia.Headless` con rendering Skia disponibile su Windows e Linux senza display (in questa macchina il rendering headless è già stato provato fuori dal repo).
|
|
- [ ] Nessun test di GUI instabile per i tempi (usare attese su condizioni, non pause fisse).
|
|
- [ ] Scelta del fornitore di CI e traduzione dei comandi in una pipeline con matrice Windows + Linux.
|
|
|
|
## Riferimenti
|
|
- Piano, matrice e regole: [TESTING.md](../TESTING.md).
|
|
- Passi: [ROADMAP.md](../ROADMAP.md), Fase 6.
|