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!
la source
Réponses:
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.
la source
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.
la source
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.
la source
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é ).
la source