Quelles sont les meilleures pratiques pour tester des programmes avec un comportement stochastique?


14

En faisant du travail de R&D, je me retrouve souvent à écrire des programmes qui ont un certain degré d'aléatoire dans leur comportement. Par exemple, lorsque je travaille en programmation génétique, j'écris souvent des programmes qui génèrent et exécutent du code source aléatoire arbitraire.

Un problème avec le test d'un tel code est que les bogues sont souvent intermittents et peuvent être très difficiles à reproduire. Cela va au-delà de la définition d'une valeur de départ aléatoire à la même valeur et du redémarrage de l'exécution.

Par exemple, le code peut lire un message à partir du tampon d'anneau kernal, puis effectuer des sauts conditionnels sur le contenu du message. Naturellement, l'état du tampon en anneau aura changé lorsque l'on tentera ultérieurement de reproduire le problème.

Même si ce comportement est une fonctionnalité, il peut déclencher d'autres codes de manière inattendue et révèle ainsi souvent des bogues que les tests unitaires (ou les testeurs humains) ne trouvent pas.

Existe-t-il des meilleures pratiques établies pour tester des systèmes de ce type? Si oui, certaines références seraient très utiles. Sinon, toute autre suggestion est la bienvenue!


5
Vous ne pouvez pas vous moquer du tampon d'anneau du noyau aussi? Et d'autres aspects aléatoires de votre code?
Jonathan Merlet

1
@JonathanMerlet Potentiellement, mais le problème est que, une fois déployé, le code aura accès au véritable tampon en anneau (en fait, à un véritable système d'exploitation). Donc, si je teste uniquement sur une version maquette, je ne fais que reporter la découverte de ces bugs à plus tard.
John Doucette

Il me semble que le problème n'est pas lié au comportement aléatoire du programme (car cela peut être contrôlé par la graine aléatoire) mais à des états particuliers de ce «tampon d'anneau de noyau». Donc, votre question est en fait «comment puis-je tester un programme qui dépend de l'état externe», non?
AakashM

@AakashM, oui, c'est une meilleure façon de le formuler. Pour être plus spécifique, un programme avec un état externe, qui accède ou modifie stochastiquement l'état externe.
John Doucette

Réponses:


7

Il est utile d'ajouter des crochets, comme suggéré, pour recréer des états exacts. Instrumentez également le système afin qu'il puisse vider ses "graines" (dans votre cas, y compris la graine PRNG ainsi que le tampon d'anneau du noyau, et toute autre source d'entrée non déterministe.)

Ensuite, exécutez vos tests avec une véritable entrée aléatoire et un style de régression avec tous les cas intéressants précédemment découverts.

Dans le cas particulier de votre accès au noyau, je vous recommande de faire une maquette dans tous les cas. Utilisez la simulation pour forcer les classes d'équivalence qui sont moins susceptibles d'apparaître dans la pratique, dans l'esprit de "vide" et de "plein" pour les conteneurs, ou "0, 1, 2 ^ n, 2 ^ n + 1, many" pour choses dénombrables. Ensuite, vous pouvez tester avec la maquette et avec la réalité, sachant que vous avez manipulé et testé les cas auxquels vous avez pensé jusqu'à présent.

Fondamentalement, ce que je propose équivaut à un mélange d'entrées déterministes et non déterministes, les déterministes étant un mélange de ceux auxquels vous pouvez penser et de ceux qui vous ont surpris.


6

Une chose raisonnable à faire est d'amorcer le générateur de nombres aléatoires avec une valeur constante pour les tests, afin d'obtenir un comportement déterministe.


1
cette; ou se moquer entièrement du prng
jk.

1
Merci pour la suggestion! Je le fais déjà pour les tests unitaires, mais je ne peux pas tester tous les programmes possibles à la main.
John Doucette

2
mais cela signifie que vous ne pouvez pas tester si le caractère aléatoire fonctionne correctement ..
Louis Rhys

2

Je pense que les tests statistiques sont le seul moyen. Tout comme les nombres aléatoires sont «testés» pour le caractère aléatoire par des tests statistiques, il faut donc qu'il s'agisse d'algorithmes qui utilisent un comportement aléatoire.

Exécutez simplement l'algorithme plusieurs fois avec une entrée identique ou différente et comparez-le. Le problème avec cette approche est l'augmentation considérable du temps de calcul nécessaire pour terminer les tests.


Pas nécessairement, car vous pouvez choisir un petit ensemble d'entrées "s'étendant" et les exécuter plusieurs fois - le nombre d'entrées nécessaires pour vérifier la fiabilité peut être plus petit. Cet ensemble "couvrant" devrait entrer dans chaque branche du code, initialiser tous les objets, etc.
Daniel Moskovich

2

Je ne suis pas un spécialiste dans ce domaine, mais il existe une littérature scientifique relative aux tests de programmes stochastiques.

Si vous ne pouvez pas facilement créer des classes de test, un test statistique peut être utilisé, comme l'a dit #Euphoric. Borning et al. comparer une approche traditionnelle et une approche statistique. Une généralisation des tests statistiques suggérés par @Euphoric pourrait être celle discutée par Whittaker. Il a suggéré de créer un modèle stochastique du comportement souhaité (stochastique, dans votre cas) puis de générer des cas de test spécifiques à partir de ce modèle (voir son article dédié ).


Merci! Semble très utile. Pour ceux qui ne font pas partie des établissements universitaires, une version préimprimée du document peut être extraite du référentiel de codes Google de l'auteur ici: team4model.googlecode.com/svn/trunk/resources/paper/…
John Doucette
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.