# Tane — Estrategia de pruebas (casi-TDD, sin depender de pruebas manuales) *Convención del proyecto. Objetivo: **cada comportamiento cubierto por una prueba automática**; las pruebas manuales son la excepción, no la red de seguridad.* ## Principio **Casi-TDD.** Para lógica nueva: test primero (red → green → refactor). Como mínimo innegociable: **ninguna rama se mergea sin tests que cubran lo nuevo.** La "definición de hecho" de cada historia **incluye sus tests**; sin tests, no está hecha. CI en cada push bloquea si algo falla o baja la cobertura. `commons_core` es **Dart puro (sin Flutter)** → la lógica difícil (CRDT, identidad/derivación, cifrado, backup, pledge/WoT) se hace con TDD cómodo y rápido. ## La pirámide (Flutter/Dart) - **Unit** (`dart test` / `flutter test`): lógica pura — CRDT, `Quantity`, derivación de claves, serialización, repositorios. Rápidos; el grueso vive en `commons_core`. - **Widget** (`flutter_test`, `pumpWidget`): pantallas y componentes — interacción, *progressive disclosure*, i18n, accesibilidad (targets grandes). - **Integration** (`integration_test` + `flutter test`): app entera en emulador/dispositivo, con **BD real cifrada (SQLCipher)**. Flujos e2e — **esto es lo que sustituye a las pruebas manuales.** - **Golden** (regresión visual): pantallas clave; vigila que la accesibilidad no se rompa. - **Migration** (Drift): `drift_dev schema generate` + `validateDatabaseSchema` por cada `schemaVersion`. ## Tests que este proyecto necesita sí o sí - **Cifrado en reposo:** abrir el fichero de BD **en crudo** y afirmar que **NO hay texto en claro** (buscar una etiqueta conocida en los bytes y exigir ausencia). Regresión de seguridad clave para el "peor caso legal". - **CRDT — convergencia:** *property-based* — fusionar operaciones en **cualquier orden** converge al mismo estado (LWW, OR-Set, log append-only, tombstones). - **Migraciones:** cada versión migra desde la anterior y valida contra el esquema fresco. - **Backup round-trip:** exportar → borrar → importar → **estado idéntico** (y cifrado). - **Identidad:** derivación secp256k1 **determinista** desde la semilla (mismo input → misma clave) y unidireccional. - **i18n:** ninguna cadena hardcodeada (lint), y todas las locales con las mismas claves. ## Lo difícil de automatizar (y cómo) Cámara, keystore/biométrico, relays reales: **abstraer tras interfaces** y probar con *fakes/mocks*; dejar una capa fina de adaptadores de plataforma con un *smoke test* mínimo. Los *integration tests* en dispositivo cubren la integración real de la BD cifrada. Objetivo: **manual ≈ 0**. ## CI y cobertura - CI en cada push/PR (Forgejo/Codeberg Actions o GitHub Actions): `flutter analyze` + unit + widget + **integration en emulador** + cobertura (lcov). **Merge bloqueado** si falla o baja la cobertura. - Objetivo de cobertura **alto en `commons_core`** (p.ej. ≥ 85%); la UI, con widget + golden. - Tests deterministas y rápidos: sin red real, reloj/UUID/HLC inyectables (para reproducibilidad). ## Flujo de trabajo Dominio (`commons_core`): test primero. UI: al menos un widget test por pantalla/flujo antes de darla por terminada, y un *integration test* por flujo crítico (alta de semilla → persiste cifrada → reabrir → sigue ahí). Regla dura repetida: **sin tests, no se mergea.**