Skip to content

Latest commit

 

History

History
228 lines (149 loc) · 5.75 KB

File metadata and controls

228 lines (149 loc) · 5.75 KB

🧪 Guideline de Tests – Version ECS/DOD/AOT

1. Invariants Structuraux

  1. Tester toujours la data, jamais les objets. Un test valide opère sur structures de données brutes (components, chunks de composants, tables), pas sur des surcouches orientées objets.

  2. Isolation stricte des systèmes. Un système est une transformation Data_in → Data_out. Les tests vérifient la transformation, pas l’environnement.

  3. Exécution déterministe. Aucun test ne doit dépendre d’un timer, de MonoGame, du rendu, d’un scheduler non déterministe, ou d’une API système.

  4. Zéro allocation dans les tests système-critiques. Les tests détectent indirectement les allocations parasites via la structure des API :

    • Systèmes stateless
    • Collections pré-allouées
    • Pas de LINQ, pas de yield, pas de boxing
  5. Tests orientés pipeline. Chaque test valide un segment d’un pipeline ECS (lecture → processing → écriture), jamais le pipeline complet en une fois.


2. Test-Driven Development (Réinterprétation DOD)

2.1 Red / Green / Refactor (version data-oriented)

  • Red : Écrire un test échouant qui décrit une transformation de données attendue. Pas de mocks complexes. Pas d’objets. Juste des buffers et des components.

  • Green : Implémenter le minimum de logique fonctionnelle pour faire passer la transformation. Priorité : accès séquentiels, aucun branchement inutile.

  • Refactor : Nettoyer les accès mémoire, réduire les branches, éliminer les allocations, aligner les structures. Tant que les tests restent strictement déterministes.


3. Types de Tests (Version ECS)

3.1. Tests Unitaires (Systèmes ECS)

Un test unitaire valide la logique d’un unique système ECS :

  • Input : un World, des entities, des components initiaux
  • Process : appel system.Update()
  • Output : validation des components modifiés

Contraintes :

  • Pas de MonoGame
  • Aucun accès API externe
  • Pas d’interaction avec un autre système
  • Temps d’exécution < 1 ms

3.2. Tests d’Intégration ECS (Pipeline)

Ici on teste une séquence ordonnée de systèmes, jamais tout l’écosystème.

Exemple : InputSystem → MovementSystem → CollisionSystem

On valide :

  • cohérence des données entre étapes
  • invariants mémoire (pas d’écrasement illégal, pas de sortie de range)
  • comportement déterministe entre runs identiques

4. Construction des Tests ECS/DOD

4.1. Initialisation minimale du World

Chaque test crée un World minimal, sans dépendances, sans services mono.

var world = new World();
var entity = world.CreateEntity();
entity.Set(new Position { X = 0, Y = 0 });
entity.Set(new Velocity { X = 1, Y = 0 });

Règle : Tout ce qui n’est pas utilisé par le système testé est exclu.

4.2. Instanciation des systèmes

Un système doit être construit uniquement via sa signature de production.

var system = new MovementSystem(world);
system.Update(deltaTime);

Interdit :

  • passer un EntitySet manuellement
  • injecter des mocks
  • altérer le flux normal de construction du système

4.3. Validation par lecture directe du composant

ref var pos = ref entity.Get<Position>();
Assert.Equal(1, pos.X);

Pas de wrappers, pas de helpers, pas de méthodes « utilitaires » cachant l’accès aux données.


5. Mocking et I/O

En DOD, le mocking est limité aux interfaces contraintes par le runtime.

5.1. Mocking autorisé

Uniquement pour les systèmes consommant :

  • input clavier
  • input souris
  • horloge
  • filesystem

Règle : Wrap obligatoire. Le test injecte une version déterministe d’un wrapper (pas de dépendance OS/MonoGame).

5.2. Interdit

  • Mocker un système ECS.
  • Mocker un component.
  • Mocker la logique interne d’un pipeline.

6. Organisation Mémoire-Centric des Tests

6.1. Structure miroir stricte

RPG/
├── Components/
│   └── Position.cs
│   └── Velocity.cs
├── Systems/
│   └── MovementSystem.cs
└── Tests/
    ├── Components/
    │   └── PositionTests.cs
    └── Systems/
        └── MovementSystemTests.cs

Règles :

  • Chaque fichier de production → un fichier de test miroir
  • Namespace miroir : RPG.Tests.Systems

6.2. Nommage orienté transformation

Update_WhenVelocityApplied_PositionMoves

Format : Transformation_Condition_Resultat


7. Tests DOD Spécifiques

7.1. Tests de Layout Mémoire

Valident le caractère POD-like des components.

Assert.Equal(sizeof(float) * 2, Unsafe.SizeOf<Position>());

Détecte :

  • padding non désiré
  • champs parasites
  • struct non blittable

7.2. Tests d’Invariants ECS

Vérifier qu’un système :

  • n’écrit qu’aux components qu’il possède
  • ne lit pas hors scope
  • ne crée/détruit pas d’entities non prévues

7.3. Tests de Branch Minimization

Vérifier que les conditions restent scalaires :

  • aucune dépendance runtime superflue
  • branches prévisibles
  • aucune complexité cachée

(Souvent indirect via la structure de code, pas instrumentation.)


8. Anti-Patterns (Version DOD/ECS)

❌ Tester les appels méthodes internes ❌ Tester les systèmes via des états objets (OO) ❌ Mettre des mocks partout ❌ Laisser un système dépendre d’un autre ❌ Valider du comportement gameplay hors de son pipeline ECS ❌ Utiliser LINQ dans les tests ou la production testée

✔ Tester uniquement les données et leur transformation ✔ Mesurer toujours le chemin data → data ✔ Traiter les systèmes comme des passeurs de flux


9. Gestion des Tests Incomplets

Si un système n’existe pas encore :

  • utiliser Skip
  • ne pas créer de stub vide
  • ne pas adapter la prod aux tests, jamais