Je suis un ardent défenseur du développement piloté par les tests en informatique scientifique. Son utilité dans la pratique est tout simplement stupéfiante et atténue vraiment les problèmes classiques que les développeurs de code connaissent. Cependant, il y a des difficultés inhérentes à tester des codes scientifiques qui ne sont pas rencontrés dans la programmation générale, donc les textes TDD ne sont pas terriblement utiles comme tutoriels. Par exemple:
En général, vous ne connaissez pas a priori une réponse exacte à un problème complexe donné, alors comment pouvez-vous écrire un test?
Le degré de parallélisme change; J'ai récemment rencontré un bogue où l'utilisation de tâches MPI en tant que multiple de 3 échouait, mais un multiple de 2 fonctionnait. De plus, les frameworks de test communs ne semblent pas très compatibles avec MPI en raison de la nature même de MPI - vous devez réexécuter un binaire de test pour modifier le nombre de tâches.
Les codes scientifiques comportent souvent de nombreuses pièces étroitement couplées, interdépendantes et interchangeables. Nous avons tous vu le code hérité, et nous savons combien il est tentant de renoncer à une bonne conception et d'utiliser des variables globales.
Souvent, une méthode numérique peut être une "expérience", ou le codeur ne comprend pas complètement comment il fonctionne et essaie de le comprendre, il est donc impossible d'anticiper les résultats.
Quelques exemples de tests que j'écris pour du code scientifique:
Pour les intégrateurs de temps, utilisez un ODE simple avec une solution exacte et testez que votre intégrateur le résout avec une précision donnée, et l'ordre de précision est correct en testant avec différentes tailles d'étape.
Tests de stabilité zéro: vérifier qu'une méthode avec 0 conditions limites / initiales reste à 0.
Tests d'interpolation: étant donné une fonction linéaire, assurez-vous qu'une interpolation est correcte.
Validation héritée: isolez un morceau de code dans une application héritée connue pour être correcte et extrayez des valeurs discrètes à utiliser pour les tests.
Il arrive souvent que je n'arrive pas à comprendre comment tester correctement un morceau de code donné, à part les essais et erreurs manuels. Pouvez-vous fournir des exemples de tests que vous écrivez pour le code numérique et / ou des stratégies générales pour tester des logiciels scientifiques?
Réponses:
Méthode des solutions fabriquées .
Vérifier par des études de raffinement que la méthode atteint l'ordre théorique de précision.
Conservation de la réponse. Reproduction des solutions au niveau du bit et de la norme.
la source
Bill a déjà énuméré quelques méthodes qui répondent à vos préoccupations.
Pour répondre à votre troisième point, non, il n'y a aucune raison d'introduire un couplage solide entre les pièces. Bien au contraire: si vos fonctions ou classes ont des interfaces bien définies, il sera beaucoup plus facile d'échanger par exemple un solveur linéaire contre un autre, ou un schéma pas à pas. Il suffit de lui résister et vous pourrez ensuite tester ces composants séparément. Nous l'avons fait avec deal.II pendant des décennies.
À votre quatrième point: si votre méthode est une expérience, vos expériences avec la méthode constituent un test. Tant que vous n'aurez pas d'analyse, vous devrez prendre ces résultats de test le mieux possible. Mais généralement, vous avez une attente par exemple pour l'ordre d'une méthode, ou vous savez qu'elle est exacte pour une certaine classe de solutions, par exemple des polynômes jusqu'à un certain degré. Leur vérification devrait faire partie de vos expériences et, à mesure que l'analyse s'améliore, des tests peuvent être ajoutés.
la source
J'ai récemment trouvé cette thèse sur TDD en science informatique. Je ne l'ai pas encore lu, donc je ne sais pas si c'est bon, mais j'espère que cela peut être utile.
http://cyber.ua.edu/files/2014/12/u0015_0000001_0001551.pdf
la source