- docs/SPEC.md sostituito da un file per argomento (indice in docs/README.md) - assunzioni A1-A24 con dove nel codice e cosa succede se false - formule in LaTeX corrette (nessuno spazio prima del dollaro di chiusura), simboli e chiavi in tabella - diagrammi Mermaid per il flusso degli algoritmi e le dipendenze dei moduli - figura dei domini sul seed 1 (docs/img/domini_esempio.png) - README ridotto a indice con avvio rapido; CLAUDE.md e docstring allineati Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
5.5 KiB
Test
.venv/bin/pytest # tutti (≈ 7 s)
.venv/bin/pytest tests/test_fit.py # un file
.venv/bin/pytest -k raffreddamento # per nome
.venv/bin/pytest -x -q # ferma al primo errore, output breve
.venv/bin/pytest -rs # mostra i test saltati e il motivo
.venv/bin/ruff check src tests # stile e import (deve passare)
Due livelli
| Livello | File | Dati | Se i CSV mancano |
|---|---|---|---|
| Unitari | test_domini, test_fit, test_selezione, test_config_dati |
segnale sintetico generato nei test (conftest.py) |
girano comunque |
| Integrazione | test_integrazione |
input/gen_{1,2,3}.csv di gen_data; CLI |
saltati (non falliti) |
Un clone nuovo non ha i CSV (input/*.csv è ignorato da git): i test unitari bastano per lavorare sul codice; per quelli di integrazione si generano
i CSV come in uso.md §2.
Il segnale sintetico (tests/conftest.py)
T(t) = T_\text{amb} + \sum_j A_j\,e^{-(t-t_j)/\tau}\,\mathbb{1}[t \ge t_j] + \varepsilon, \qquad \varepsilon \sim \mathcal{N}(0, 0.1^2)
con T_\text{amb} = 23, \tau = 16 s, gradini (t_j, A_j) = (15, 80), (18, 70), (22, 60), campionamento 0.15 s, 120 s, nessun scarto casuale. La verità è nota, quindi si
possono controllare numericamente i parametri recuperati. La funzione segnale(...) accetta rumore, seme, gradini e durata per costruire casi particolari
(nessun gradino, un gradino, gradino sotto soglia). dT_C = T - T_\text{amb}. Fixture: cfg (config reale), sintetico, csv_gen (un CSV gen_data, saltato se assente).
test_domini.py — suddivisione (assunzioni A5, A6, A21)
| Test | Verifica |
|---|---|
test_tre_gradini |
3 gradini → 7 domini: riposo, (riscaldamento, raffreddamento) × 3 |
test_riscaldamento_e_la_salita_rapida |
ogni riscaldamento ha ≤ 3 campioni |
test_confini_vicini_agli_istanti_dei_gradini |
l'inizio di ogni riscaldamento è entro 0.5 s dal gradino vero |
test_domini_contigui_e_completi |
primo i0 = 0, ultimo i1 = n, nessun buco |
test_senza_gradini_un_solo_riposo |
nessun gradino → solo riposo |
test_un_solo_gradino |
riposo, riscaldamento, raffreddamento |
test_gradino_sotto_soglia_ignorato |
un salto di 10 °C (< soglia) non è un gradino |
test_domini_toml_andata_e_ritorno |
scrivere e rileggere domini.toml dà gli stessi domini |
test_domini_toml_non_contigui_rifiutati |
domini non contigui → ValueError |
test_domini_toml_tipo_non_valido |
tipo sconosciuto → ValueError |
test_fit.py — fit e analisi (A7, A8, A13, A18, A22, A23)
| Test | Verifica |
|---|---|
test_modelli_valutazione |
valori dei modelli; il registro contiene esattamente costante, lineare, esp_decad |
test_esp_decad_recupera_parametri (5 seed) |
\tau entro il 2 %, c entro 0.2, A entro il 2 %, \mathrm{RMSE} \approx \sigma, fit valido |
test_parametri_fissi_restano_fissi |
c e \tau fissi restano invariati, k = 1, A recuperata entro il 3 % |
test_tau_libero_non_identificabile_su_tratto_corto_e_rumoroso (5 seed) |
su 3 s con disturbi di 2 °C, \tau libero è «non identificabile» (motivo del fissaggio) |
test_analisi_completa_sintetico |
7 domini; finale con \tau entro il 3 % e nessun parametro fisso; intermedi con c, tau fissi uguali al finale; ampiezze A degli intermedi entro il 5 % dal valore atteso |
test_riscaldamento_descritto_come_salto_non_fittato |
fit vuoto, scelta assente, \Delta entro il 15 % dell'ampiezza vera, ≤ 3 campioni |
test_un_solo_raffreddamento_resta_libero |
un solo gradino → il raffreddamento (finale) non ha parametri fissi |
test_dominio_troppo_corto_indeterminato |
5 campioni → indeterminato |
test_riproducibile |
due esecuzioni identiche danno risultati identici |
test_selezione.py — regola di scelta (algoritmi.md §6)
Su fit finti costruiti a mano: vince il modello con meno parametri entro \Delta\mathrm{AICc}; vince il migliore oltre la soglia; si scartano non
convergenti, a limite, non identificabili; nessun valido → indeterminato; si preferiscono i modelli adeguati anche con AICc peggiore; nessun adeguato →
scelto ma segnalato.
test_config_dati.py — errori di configurazione e CSV (A1, A2)
config.toml reale valido; chiave mancante; lista dei modelli vuota per un tipo; file di configurazione inesistente; CSV valido (conversione
ms → s); colonna mancante; tempo non crescente.
test_integrazione.py — su gen_data e CLI
| Test | Verifica |
|---|---|
test_domini_su_csv_gen (3 seed) |
7 domini nell'ordine atteso |
test_raffreddamento_tau_nominale (3 seed) |
raffreddamento finale: esp_decad, \tau entro il 10 % di 15.9 s |
test_raffreddamenti_intermedi_ereditano_costanti (3 seed) |
intermedi con c, tau fissi uguali al finale, A > 0 |
test_cli_domini_e_analizza |
fitseg domini scrive solo 01_domini/; analizza --domini scrive sovrapposizione e report; il report rimanda alle immagini giuste; formule principali in LaTeX e $ bilanciati su ogni riga |
test_cli_errori |
CSV inesistente → exit 4; configurazione inesistente → exit 3 |
Cosa non è coperto
Seed oltre i tre di gen_data; rumore e gradini molto diversi dalla configurazione d'esempio; dati reali; i grafici (si controllano a vista, output.md).
Prova manuale dopo una modifica: fitseg analizza input/gen_1.csv e controllare in report.md i 7 domini e \tau \approx 16 s nel finale.