Les affirmations ne survivent pas à la réalité
Habituellement, les assertions ne survivent pas au contact avec des données réelles. Cela fait partie du processus de génie logiciel de décider, avec quelles données vous voulez traiter et lesquelles sont hors de portée.
Graphes de famille cycliques
Concernant les "arbres" de famille (en fait ce sont des graphiques à part entière, y compris des cycles), il y a une belle anecdote:
J'ai épousé une veuve qui avait une fille adulte. Mon père, qui nous rendait souvent visite, est tombé amoureux de ma belle-fille et l'a épousée. En conséquence, mon père est devenu mon fils et ma fille est devenue ma mère. Quelque temps plus tard, j'ai donné à ma femme un fils, qui était le frère de mon père et mon oncle. La femme de mon père (qui est aussi ma fille et ma mère) a eu un fils. En conséquence, j'ai eu un frère et un petit-fils dans la même personne. Ma femme est maintenant ma grand-mère, car elle est la mère de ma mère. Je suis donc le mari de ma femme et en même temps le beau-petit-fils de ma femme. En d'autres termes, je suis mon propre grand-père.
Les choses deviennent encore plus étranges lorsque l'on tient compte des substituts ou de la "paternité floue".
Comment y faire face
Définir les cycles comme hors champ
Vous pourriez décider que votre logiciel ne devrait pas traiter de tels cas rares. Si un tel cas se produit, l'utilisateur doit utiliser un produit différent. Cela rend le traitement des cas les plus courants beaucoup plus robuste, car vous pouvez conserver plus d'assertions et un modèle de données plus simple.
Dans ce cas, ajoutez de bonnes fonctionnalités d'importation et d'exportation à votre logiciel, afin que l'utilisateur puisse facilement migrer vers un autre produit si nécessaire.
Autoriser les relations manuelles
Vous pouvez autoriser l'utilisateur à ajouter des relations manuelles. Ces relations ne sont pas des «citoyens de première classe», c'est-à-dire que le logiciel les prend telles quelles, ne les vérifie pas et ne les gère pas dans le modèle de données principal.
L'utilisateur peut alors gérer les rares cas à la main. Votre modèle de données restera assez simple et vos affirmations survivront.
Soyez prudent avec les relations manuelles. Il y a une tentation de les rendre complètement configurables et donc de créer un modèle de données entièrement configurable. Cela ne fonctionnera pas: votre logiciel ne sera pas redimensionné, vous obtiendrez d'étranges bugs et enfin l'interface utilisateur deviendra inutilisable. Cet anti-modèle est appelé "codage logiciel" , et "Le WTF quotidien" est plein d'exemples pour cela.
Rendez votre modèle de données plus flexible, ignorez les assertions, testez les invariants
Le dernier recours consisterait à rendre votre modèle de données plus flexible. Vous devez ignorer presque toutes les assertions et baser votre modèle de données sur un graphique complet. Comme le montre l'exemple ci-dessus, il est facilement possible d'être votre propre grand-père, vous pouvez donc même avoir des cycles.
Dans ce cas, vous devez tester en profondeur votre logiciel. Vous avez dû ignorer presque toutes les assertions, il y a donc de bonnes chances pour des bogues supplémentaires.
Utilisez un générateur de données de test pour vérifier les cas de test inhabituels. Il existe des bibliothèques de vérification rapide pour Haskell , Erlang ou C . Pour Java / Scala, il y a ScalaCheck et Nyaya . Une idée de test serait de simuler une population aléatoire, de la laisser se croiser au hasard, puis de laisser votre logiciel d'abord importer puis exporter le résultat. On s'attendrait à ce que toutes les connexions dans la sortie soient également dans l'entrée et vice versa.
Un cas où une propriété reste la même est appelé invariant. Dans ce cas, l'invariant est l'ensemble des «relations amoureuses» entre les individus de la population simulée. Essayez de trouver autant d'invariants que possible et testez-les avec des données générées aléatoirement. Les invariants peuvent être fonctionnels, par exemple:
- un oncle reste un oncle, même lorsque vous ajoutez plus de "relations amoureuses"
- chaque enfant a un parent
- une population à deux générations a au moins un grand-parent
Ou ils peuvent être techniques:
- Votre logiciel ne plantera pas sur un graphique jusqu'à 10 milliards de membres (quel que soit le nombre d'interconnexions)
- Votre logiciel évolue avec O (nombre de nœuds) et O (nombre d'arêtes ^ 2)
- Votre logiciel peut enregistrer et recharger chaque graphique de famille jusqu'à 10 milliards de membres
En exécutant les tests simulés, vous trouverez de nombreux cas de coins étranges. Les réparer prendra beaucoup de temps. Vous perdrez également beaucoup d'optimisations, votre logiciel fonctionnera beaucoup plus lentement. Vous devez décider si cela en vaut la peine et si cela est dans la portée de votre logiciel.