Je suis en faveur des tests aléatoires et je les écris. Cependant, la question de savoir si elles sont appropriées dans un environnement de construction particulier et dans quelles suites de tests elles doivent être incluses est une question plus nuancée.
Exécutés localement (par exemple, pendant la nuit sur votre boîte de développement), des tests aléatoires ont trouvé des bogues à la fois évidents et obscurs. Les plus obscurs sont suffisamment obscurs pour que je pense que les tests aléatoires étaient vraiment les seuls réalistes pour les éliminer. En guise de test, j'ai pris un bogue difficile à trouver découvert via des tests aléatoires et j'ai demandé à une demi-douzaine de développeurs de crack d'examiner la fonction (environ une douzaine de lignes de code) là où elle s'est produite. Aucun n'a pu le détecter.
Beaucoup de vos arguments contre les données aléatoires sont des saveurs de "le test n'est pas reproductible". Cependant, un test randomisé bien écrit capturera la graine utilisée pour démarrer la graine aléatoire et la produira en cas d'échec. En plus de vous permettre de répéter le test à la main, cela vous permet de créer de manière triviale un nouveau test qui teste le problème spécifique en codant en dur la graine de ce test. Bien sûr, il est probablement plus agréable de coder manuellement un test explicite couvrant ce cas, mais la paresse a ses vertus, et cela vous permet même de générer automatiquement de nouveaux cas de test à partir d'une graine défaillante.
Le seul point que vous faites valoir que je ne peux pas débattre, cependant, c'est que cela brise les systèmes de construction. La plupart des tests de build et d'intégration continue s'attendent à ce que les tests fassent la même chose à chaque fois. Ainsi, un test qui échoue au hasard créera le chaos, échouera au hasard et pointera du doigt des changements qui étaient inoffensifs.
Une solution consiste donc à exécuter vos tests aléatoires dans le cadre des tests de construction et de CI, mais à les exécuter avec une valeur de départ fixe, pour un nombre fixe d'itérations . Par conséquent, le test fait toujours la même chose, mais explore toujours une partie de l'espace d'entrée (si vous l'exécutez pour plusieurs itérations).
Localement, par exemple, lorsque vous changez la classe concernée, vous êtes libre de l'exécuter pour plus d'itérations ou avec d'autres graines. Si les tests aléatoires deviennent de plus en plus populaires, vous pourriez même imaginer une suite spécifique de tests connus pour être aléatoires, qui pourraient être exécutés avec différentes graines (donc avec une couverture croissante au fil du temps), et où les échecs ne signifieraient pas la même chose en tant que systèmes de CI déterministes (c.-à-d., les exécutions ne sont pas associées 1: 1 aux changements de code et vous ne pointez donc pas du doigt un changement particulier lorsque les choses échouent).
Il y a beaucoup à dire sur les tests aléatoires, en particulier ceux bien écrits, alors ne soyez pas trop prompt à les rejeter!