46 votes

Test unitaire du traitement de la pile réseau dégradée, de la corruption des fichiers et d'autres imperfections

Je suis principalement un codeur C++, et jusqu'à présent, ont géré sans vraiment l'écriture de tests pour l'ensemble de mon code. J'ai décidé que c'est une Mauvaise Idée(tm), après l'ajout de nouvelles fonctionnalités qui subtilement cassé anciennes fonctionnalités, ou, selon la façon dont vous voulez regarder, introduit quelques nouvelles "fonctionnalités" de leur propre.

Mais, tests unitaires semble extrêmement fragile mécanisme. Vous pouvez tester quelque chose de "parfait" les conditions, mais vous n'obtenez pas de voir comment votre code effectue lorsque les choses se casse. Un, par exemple, est un robot, disons qu'il analyse quelques sites spécifiques, pour les données X. Faire, il vous suffit de sauvegarder des pages d'exemple, test contre ces, et on espère que les sites ne jamais changer? Ce serait bien fonctionner en tant que tests de régression, mais, ce genre de tests écririez-vous de vérifier en permanence les sites en direct et vous permettent de savoir quand l'application n'est pas fait son travail parce que le site a changé quelque chose, qui est maintenant à l'origine de votre application crash? Vous ne voudriez pas que votre suite de tests pour surveiller l' intention de le code?

L'exemple ci-dessus est un peu artificiel, et quelque chose que je n'ai pas rencontré (dans le cas où vous ne l'avez pas deviné). Permettez-moi de prendre quelque chose que j'ai, cependant. Comment faites-vous tester une application fera son travail face à une dégradation de la pile réseau? Qui est, disons que vous avez une quantité modérée de la perte de paquets, pour une raison ou l'autre, et vous avez une fonction DoSomethingOverTheNetwork() qui est censé dégrader gracieusement lorsque la pile ne fonctionne pas comme il est censé le faire; mais n'est ce pas? Les tests réalisés par le développeur personnellement dessein par la configuration d'une passerelle qui tombe paquets pour simuler un mauvais réseau quand il écrit d'abord. Quelques mois plus tard, quelqu'un vérifie dans le code qui modifie quelque chose de subtilement, de sorte que la dégradation n'est pas détecté à temps, ou, l'application n'a même pas reconnaître la dégradation, ce n'est jamais pris, parce que vous ne pouvez pas exécuter le monde réel des tests de ce genre à l'aide de tests unitaires, pouvez-vous?

De plus, comment au sujet de la corruption de fichiers? Disons que vous êtes stocker une liste de serveurs dans un fichier, et la somme de contrôle semble correct, mais les données n'est pas vraiment le cas. Vous voulez que le code de poignée, vous écrire un peu de code que vous pensez que le fait que. Comment tester que c'est exactement ce que fait pour la vie de l'application? Pouvez-vous?

Par conséquent, la fragilité. Les tests unitaires semblent tester le code que dans des conditions parfaites(et c'est favorisée, avec les objets fantaisie et par exemple), et non pas ce qu'ils feront face à l'état sauvage. Ne vous méprenez pas, je pense que les tests unitaires sont grands, mais une suite de test composé uniquement d'entre eux semble être une bonne manière d'introduire des bogues dans le code tout en se sentant trop confiants à ce sujet de la fiabilité.

Comment puis-je corriger les situations ci-dessus? Si les tests unitaires ne sont pas la réponse, c'est quoi?

Edit: je vois beaucoup de réponses que de dire "juste mock". Eh bien, vous ne pouvez pas "juste mock", voici pourquoi: En prenant mon exemple de la dégradation de la pile réseau, supposons que votre fonction est bien définie NetworkInterface, que nous allons simuler. L'application envoie des paquets sur TCP et UDP. Maintenant, laissez-nous dire, hey, nous allons simuler la perte de 10% sur l'interface à l'aide d'un objet fantaisie, et de voir ce qui se passe. Vos connexions TCP à augmenter leurs tentatives, ainsi que d'augmenter leur back-off, toutes les bonnes pratiques. Vous décidez de changer de X% de vos paquets UDP pour réellement faire une connexion TCP, avec perte de l'interface, nous voulons être en mesure d'être en mesure de garantir la livraison de certains paquets, et les autres ne devraient pas perdre trop. Fonctionne très bien. Pendant ce temps, dans le monde réel.. lorsque vous augmentez le nombre de connexions TCP (ou, données sur TCP) sur une connexion avec perte assez, vous finirez par l'augmentation de votre paquet UDP perte de vos connexions TCP sera la fin de la ré-envoi de leurs données de plus en plus et/ou la réduction de leur fenêtre, à l'origine de votre 10% de perte de paquets pour être réellement plus de 90% de perte de paquets UDP maintenant. Whoopsie.

Pas trop grave, on s'attaque en UDPInterface, et TCPInterface. Attendez une minute.. ceux sont interdépendants, contrôle de 10% UDP perte et 10% TCP perte n'est pas différent de ci-dessus.

Donc, la question est maintenant, vous n'êtes pas tout simplement de l'unité de tester votre code, vous introduisez vos hypothèses sur la manière dont le système d'exploitation de la pile TCP fonctionne. Et, c'est une Mauvaise Idée(tm). Une idée encore pire que tout en évitant l'ensemble de ce fiasco.

À un certain moment, vous allez avoir à créer une Maquette de l'OS, qui se comporte exactement comme votre vrai OS, à l'exception, est vérifiable. Cela ne semble pas comme une bonne voie à suivre.

Ce sont des choses que nous avons vécues, je suis sûr que d'autres peuvent ajouter leurs expériences.

J'espère que quelqu'un va me dire que je suis très mal, et le point pourquoi!

Merci!

14voto

Raedwald Points 8862

Vous commencez par parler de tests unitaires, puis par des applications entières; il semble que vous soyez un peu confus quant à la nature des tests unitaires. Par définition, le test unitaire consiste à tester au niveau le plus fin lorsque chaque "unité" du logiciel est testée. En usage courant, une "unité" est une fonction individuelle, pas une application complète. Le style de programmation contemporain a des fonctions courtes, chacune faisant une chose bien définie, qui est donc facile à tester.

12voto

David B Points 53123

ce genre de tests écririez-vous de vérifier en permanence les sites vivre?

UnitTests cible de petites sections de code que vous écrivez. UnitTests ne confirment pas que les choses sont ok dans le monde. En revanche, vous pouvez définir le comportement de l'application pour ceux imparfaite scénarios. Ensuite, vous pouvez UnitTest votre demande dans les imparfaite scénarios.

par exemple, pour un robot

Un robot est un grand corps de code que vous pouvez écrire. Il a quelques différentes parties, une partie peut aller chercher une page web. Une autre partie pourrait analyser le code html. De ces pièces peut être trop grand pour écrire un test unitaire contre.

Comment faites-vous tester une application fera son travail face à une dégradation de la pile réseau? Les tests réalisés par le développeur personnellement dessein par la configuration d'une passerelle qui tombe paquets pour simuler un mauvais réseau quand il écrit d'abord.

Si un test utilise le réseau, ce n'est pas un UnitTest.

Un UnitTest (qui doit cibler votre code) ne peut pas communiquer avec le réseau. Vous n'avez pas écrit le réseau. Le UnitTest devrait impliquer une simulation de réseau grâce à la simulation (mais cohérente à chaque fois), la perte de paquets.

Les tests unitaires semblent tester le code que dans des conditions parfaites

UnitTests tester votre code dans des conditions définies. Si vous êtes seulement capable de définir des conditions parfaites, votre affirmation est vraie. Si vous êtes capable de définir imparfaite conditions, votre affirmation est fausse.

10voto

Daniel Earwicker Points 63298

De travail à travers tout bon livre sur les tests unitaires - vous trouverez que c'est normal de s'exercer à écrire des tests qui couvrent les cas limites où l'entrée n'est pas l'idéal ou est simplement faux.

L'approche la plus commune dans les langues avec la gestion des exceptions est un "lancer" de spécification, d'où un certain test est prévu à cause d'une exception spécifique type à être jetés. Si ce n'est pas de générer une exception, le test échoue.

Mise à jour

Dans votre mise à jour que vous décrivez complexe de chronométrage-interactions sensibles. Les tests unitaires ne marche tout simplement pas aider à tous. Pas besoin d'introduire de réseau: il suffit de penser à essayer d'écrire un simple thread-safe classe de file d'attente, peut-être sur une plate-forme avec quelques nouvelles de la simultanéité des primitives. Tester sur un 8 core système... ça fonctionne? Vous simplement ne pouvez pas le savoir pour vous de le tester. Il ya tout simplement trop beaucoup de façons différentes que le temps peut causer des opérations de chevauchement entre les cœurs. En fonction de la chance, il pourrait prendre des semaines continues d'exécution avant de vraiment coïncidence improbable se produit. La seule façon d'obtenir de telles choses est à travers une analyse (statique outils de vérification peut aider). Il est probable que la plupart des logiciels concurrents a certains rarement présentes bugs, y compris tous les systèmes d'exploitation.

De retour à la cas, qui peut effectivement être testé, j'ai trouvé des tests d'intégration pour être souvent tout aussi utile que les tests unitaires. Ce peut être aussi élaboré que par l'automatisation de l'installation de votre produit, l'ajout de configurations (telles que vos utilisateurs peuvent créer) puis "piquer" de l'extérieur, par exemple, l'automatisation de votre INTERFACE utilisateur. Ceci trouve une toute autre catégorie de la question distincte de tests unitaires.

5voto

Finglas Points 8645

Il semble que si vous avez répondu à votre propre question.

On se moque de/stubs sont la clé de test difficile de zones de test. Pour tous vos exemples, l'approche manuelle de dire la création d'un site web avec des louches de données, ou de provoquer une panne du réseau qui pourrait être fait manuellement. Cependant, il serait très difficile et fastidieux à faire, pas quelque chose que quelqu'un vous recommande. En fait, de faire quelques voudrait dire que vous ne sont pas réellement des tests unitaires.

Au lieu de cela, vous pourriez utiliser une maquette/talons pour faire semblant de tels scénarios avez passé, vous permettant de les tester. Le bénéfice de l'aide se moque, c'est que contrairement à l'approche manuelle, vous pouvez garantir que chaque fois que vous exécutez vos tests, la même procédure sera effectuée. Les tests à son tour être beaucoup plus rapide et stable à cause de cela.

Edit - en ce qui concerne la mise à jour de question.

Tout comme un avertissement de mon expérience de mise en réseau est très limité, donc je ne peux pas commenter sur le côté technique de vos questions. Cependant, je peux faire des commentaires sur le fait que le son comme si vous testez une de trop. En d'autres termes, vos tests de couverture trop d'une vaste portée. Je ne sais pas ce que votre base de code est comme mais, compte tenu de fonctions/objets à l'intérieur, vous devriez toujours être en mesure de fournir de faux d'entrée qui vous permettra de tester vos objets/fonctions faire la bonne chose dans l'isolement.

Ainsi permet d'imaginer vos zones isolées, beau travail, compte tenu des exigences. Tout simplement parce que vos tests unitaires passent ne signifie pas que vous avez testé votre application. Vous aurez toujours besoin de tester manuellement de tels scénarios, vous décrivez. Dans ce scénario, il semble que si les tests de stress de limitation de ressources réseau et ainsi de suite sont nécessaires. Si votre application fonctionne comme prévu - grand. Si non, vous avez du manque de tests. Les tests unitaires (de plus en cravate avec TDD/BDD) est de s'assurer de petites zones isolées de votre demande de travail. Vous avez encore le besoin d'intégration/manuel/régression etc.. test par la suite. Par conséquent, vous devez utiliser des objets fantaisie/stubs pour tester vos petites zones isolées de la fonction. Le test unitaire est plus apparenté à un processus de conception si quoi que ce soit, à mon avis.

5voto

dietbuddha Points 4031

Les Tests d'intégration vs Tests Unitaires

Je devrais préface cette réponse en disant que je suis biaisé en faveur de l'intégration des tests vs tests unitaires comme le principal type de test utilisé en mode tdd. Au travail, nous avons également des tests unitaires mixte, mais seulement si nécessaire. La raison principale pourquoi nous commençons par un test d'intégration est parce que nous nous soucions plus de ce que l'application est en train de faire plutôt que de ce qu'une fonction particulière. Nous bénéficions également de l'intégration de la couverture qui a été, dans mon expérience, un écart énorme pour des tests automatisés.

Pour se Moquer ou Pas, Pourquoi ne Pas Faire les Deux

Nos tests d'intégration peut s'exécuter entièrement câblé (non géré ressource) ou avec des simulacres. Nous avons constaté que l'aide à couvrir l'écart entre le monde réel vs se moque. Cela nous donne également la possibilité de décider de ne PAS avoir raillé la version parce que le retour sur investissement pour la mise en œuvre de la maquette n'est pas la peine. Vous demandez peut-être pourquoi utiliser des objets fantaisie à tous.

  • série de test s'exécute plus rapidement
  • garanti même réponse à chaque fois (pas de délais d'attente, les imprévus dégradées réseau, etc...)
  • un contrôle précis sur le comportement

Parfois, vous ne devriez pas écrire un test

Tests, tout type de test a des arbitrages. Vous regardez le coût de mise en œuvre de l'essai, le simulacre, la variante de tests, etc et de les peser contre les avantages et parfois il ne fait pas de sens d'écrire le test, le simulacre, ou la variante. Cette décision est également faite dans le contexte de la sorte de logiciel de votre bâtiment, ce qui est vraiment l'un des principaux facteurs pour décider de la façon de profondeur et large de votre suite de tests doit être. Pour le dire d'une autre façon, je vais écrire quelques tests pour le social bacon meetup fonctionnalité, mais je ne vais pas écrire la vérification formelle de test pour le bacon-ami de l'algorithme.

Avez-vous tout simplement enregistrer les pages d'échantillon, d'essai contre ces, et on espère que les sites de ne jamais changer?

Le test n'est pas une panacée

Oui, vous enregistrez des échantillons (comme les luminaires). Vous n'avez pas l'espoir de la page ne change pas, mais vous ne pouvez pas savoir quand et comment il va changer. Si vous avez des idées ou des paramètres de la façon dont il peut changer, alors vous pouvez créer des variantes pour s'assurer que votre code sera de gérer ces variantes. Quand et si il ne change pas, et il se casse, vous ajoutez de nouveaux échantillons, résoudre les problèmes et d'avancer.

ce genre de tests que vous écrivez à constamment vérifier ces sites vivent et vous permettre de savoir quand l'application n'est-ce pas faire le travail parce que le site changé quelque chose, qui est maintenant à l'origine votre demande de crash?

Les tests != Surveillance

Les Tests sont des tests et de développement (et de contrôle de la qualité), pas pour la production. La SURVEILLANCE est-ce que vous utilisez de la production, assurez-vous que votre application fonctionne correctement. Vous pouvez écrire des moniteurs qui doivent vous alerter quand quelque chose est cassé. C'est un tout autre sujet.

Comment tester une application son travail dans le visage de la dégradation de l' la pile de réseau?

Bacon

Si c'était moi, j'aurais une connexion filaire et se moque de mode pour le test (en supposant que la maquette a été assez bon pour être utile). Si la maquette est difficile d'obtenir le droit, ou si ce n'est pas la peine alors je voudrais juste avoir la filaire de test. Cependant, j'ai constaté qu'il n'y a presque toujours un moyen de diviser les variables en jeu dans les différents tests. Ensuite, chacun de ces tests sont destinés à des tests que vecteur de changement, tout en minimisant tous les autres de la variabilité dans le jeu. L'astuce consiste à écrire l'important variantes, et pas à chaque variante possible.

De plus, comment au sujet de la corruption de fichiers?

Comment Beaucoup D'Essais

Vous mentionnez que la somme de contrôle est correcte, mais le fichier fait d'être corrompu. La question est de savoir quelle est la classe de logiciel, je suis en train d'écrire. Ai-je besoin d'être super paranoïaque à propos de la possibilité d'une différence statistiquement petit faux positif ou pas. Si je le fais, alors nous travaillons pour trouver ce que la profondeur et de large pour tester.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X