Je ne veux pas dire des outils externes. Je pense aux modèles architecturaux, aux constructions linguistiques, aux habitudes. Je suis surtout intéressé par C ++ P>
28 Réponses :
Utiliser une IDE comme Intellij qui inspecte mon code alors que je l'écris et des drapeaux du code dodgy comme je l'écris. P>
Malheureusement, il vous indique uniquement des erreurs de syntaxe ou des constructions suspectes; Un compilateur vous en parlerait de ceux-ci. Il faut des humains pour repérer le reste.
Il ne lis pas les esprits ou n'édoque pas de code pour vous, mais il est bien meilleur qu'un outil d'inspection de code statique comme Findbugz qui vérifie après ce fait. Mieux vaut obtenir les commentaires immédiatement.
Test de l'unité automatisé. P>
J'ai trouvé cela mieux pour vous assurer de ne pas casser la fonctionnalité déjà existante, plus vous aidez à éviter les bugs.
@WindFinder: Je suis surtout d'accord. Mais si vous codez des tests qui collent à la spécification avant le codage, vous pouvez trouver des bugs liés à la conformité de la spécification
Qui obtient des spécifications précises et complètes?
@duffy: Je suis d'accord aussi :) Mais vous pouvez avoir (presque) des spécifications précises et (presque) pour une partie du softare. Par exemple, c'est le cas lorsque vous concevez un «protocole» personnalisé entre sous-système.
Je trouve le suivant plutôt pratique. P>
1) affirme.
2) Un enregistreur de débogage pouvant générer sur le débogage, la console ou le fichier.
3) Outils de suivi de la mémoire.
4) Test de l'unité.
5) Pointeurs intelligents.
P>
Je suis sûr qu'il y a des tonnes d'autres mais je ne peux pas penser à eux du haut de la tête :) p>
Oui, affirmer est un économiseur de vie lorsqu'il est utilisé correctement.
Programmation par contrat. En C ++, cela se fait généralement avec des affirmations (au moins c'est comme ça que j'ai vu cela).
Modèle-View-contrôleur et, en général, rien avec des contrats et des interfaces pouvant être testés automatiquement. P>
Je trouve beaucoup de problèmes avant que je commence à tester du tout à l'aide de p>
affirme fort> p>
+1 Mais je crois qu'il est assez difficile de déclencher une affirmation d'exécution sans courir (test) votre code ...
Comme vous semblez avoir remarqué: je distingue "la course" de "tester" ici. De nombreuses affirmations échouent immédiatement lorsque vous exécutez de nouvelles fonctions la première fois. Test en revêtement ici signifie des tests approfondis.
Il y a une technique de l'OFT-inadéquate que j'aime appeler l'équipe QA EM> qui peut faire des merveilles pour déshabiller des bugs avant d'atteindre la production. P>
Cela a été mon expérience (et est souvent citée dans des manuels) que les programmeurs ne font pas les meilleurs testeurs, malgré ce qu'ils pourraient penser, car ils ont tendance à tester le comportement qu'ils savent déjà être véridiques de leur codage. En plus de cela, ils ne sont souvent pas très bons pour me mettre des témoignages dans les chaussures de l'utilisateur final (si c'est ce genre d'application), et sont donc susceptibles de négliger les problèmes de mise en forme / alignement d'interface utilisateur / d'utilisation. P>
Oui, le test unitaire est immensément important et je suis sûr que d'autres peuvent vous donner de meilleurs conseils que moi, mais ne négligez pas vos tests système / intégration. :) p>
.. et hé, c'est une technique indépendante de la langue! p>
Oui! Et il peut être si difficile de faire comprendre aux programmeurs de ne pas faire de bon travail de tester leur propre code.
Vous pouvez obtenir des développeurs pour tester le code des autres, cela fonctionne bien. À l'exception de la convivialité de l'interface utilisateur, peut-être.
Testez-le avec des données réelles réelles du début. Et les tests sont nécessaires non seulement lors de la rédaction du code, mais il devrait commencer tôt dans la phase de conception. Découvrez quels seront vos pires cas d'utilisation et assurez-vous que votre conception peut le gérer. Si votre conception se sent bien et élégante, même contre ces cas d'utilisation, cela pourrait être bien. P>
Les tests automatisés sont parfaits pour vous assurer que le code que vous écrivez est correct. Cependant, avant d'arriver à écrire du code, vous devez vous assurer que vous construisez les bonnes choses. P>
+1 Je suis fortement d'accord. Les tests contre les simulateurs ou les données idéalisées conviennent parfaitement comme un démarrage, mais cela ne devrait pas être même dans des tests unitaires. Et je vois que les exigences deviennent insatisfaises ou mal interprétées trop souvent, alors peut-être "parler au côté de la entreprise plus" devrait être un autre conseil. Tout est très bien livrant du code sans faille, mais pas si c'est la mauvaise solution.
Raii pour éviter les erreurs de fuite de ressources. P>
Bien, vrai. Bien que je dirais que la ressource la plus couramment divulguée est la mémoire. Merci pour la correction cependant :)
J'utilise la pensée. P>
Ceci est en effet rarement utilisé et technique couramment sous-estimé.
@DAVID: Ce n'est que les programmes derrière elle sont étroitement associés et de faible cohésion et de course à une impasse.
Je trouve que le programmage par pairs a tendance à éviter de nombreuses erreurs stupides, et tout le temps génère des discussions qui découvrent des défauts. De plus avec quelqu'un libre de penser à la raison pour laquelle vous faites quelque chose, il a tendance à faire tout ce qui est propre. P>
Réduire la portée des variables aussi étroites que possible. Moins de variables dans la portée extérieure - moins de chances de planter et de masquer une erreur. P>
L'un des meilleurs ici. Grandement sous-estimé.
Apprentissage de la programmation fonctionnelle aide en quelque sorte.
ici strong>
WOW, que le 2e lien est un excellent didacticiel i> Haskell. Intuitif, divertissant écrit et à peine une trace de la smugueur de la FP. Il y a même une barre latérale écrite par le Fonz! Aaay!
Test unitaire suivi d'une intégration continue. p>
Suggestions de livres: "Code complet" et "Libérer" sont deux livres à lire sur ce sujet. p>
+1 pour tous, mais surtout (2). D'après mon expérience, pour quelque chose de plus d'un script Perl de 5 lignes, cela paye toujours. Chaque fois que vous pouvez prendre 10 minutes de 10 minutes et vous convaincre que votre fonction gère tous les cas possibles, y compris les états d'erreur, saisissez-le! Vous venez de claquer la porte fermée sur un labyrinthe de passages venteux que vous n'aurez plus à vous promener. (Ce n'est pas toujours possible de bien sûr, par exemple avec le code de l'interface utilisateur.)
Content de voir que vous avez donné une simplicité la première place. Il est triste de voir que cela semble être perdu sur la majorité des programmeurs (le modèle de vote sur cette question illustre cela bien). +1
Mettez des liens dans les références sur ces sujets, ce qui pourrait obtenir plus de votes!
La peste était un changement de dernière minute? Je suppose que cela explique que Bug!
J'ai constaté que, plus cela est fait et vérifié à l'heure de la compilation, le moins peut éventuellement aller mal au moment de l'exécution. J'essaie donc de tirer parti des techniques qui permettent une vérification plus stricte à la compilation. C'est l'une des raisons pour lesquelles je suis allé dans la programmation du modèle-méta. Si vous faites quelque chose de mal, cela ne compile pas et ne quitte donc jamais votre bureau (et ne arrive donc jamais chez le client). p>
+1. Il est regrettable que C ++ rend la métaprogrammation si douloureuse et qu'il reste des classes d'erreurs qui devraient être compilées - empêchent-être évitables mais ne sont pas encore (par exemple, éviter la tranchage d'objet), mais j'espère que les choses vont évoluer.
99% des choses ont une solution. La tranchée d'objet est évitée en appliquant "la classe non-feuillette est abstraite" et / ou tous les constructeurs de copie de la classe de base / les opérateurs d'affectation de copie sont protégés.
Bonne Points Richard, mais j'ai toujours envie d'une solution qui ne repose pas si fortement sur la discipline du programmeur.
Je suis d'accord avec beaucoup d'autres réponses ici. P>
spécifique à C ++, l'utilisation de «const» et d'éviter les pointeurs bruts (en faveur des références et des pointeurs intelligents) lorsque cela m'a permis de trouver des erreurs lors de la compilation. P>
Aussi, avoir une politique "Aucun avertissement" aide à trouver des erreurs. P>
En plus des éléments déjà mentionnés, je crois que certaines fonctionnalités introduites avec C ++ 0x contribueront à éviter certains bugs. Les caractéristiques telles que les énums, les boucles pour les boucles pour les boucles et la suppression des fonctions standard d'objets sont à l'esprit. P>
En général, le typing fort est le moyen d'aller imho p>
Cohérence de style de codage dans un projet. P>
Pas seulement des espaces par rapport aux problèmes d'onglets, mais la façon dont ce code est utilisé. Il y a toujours plus d'une façon de faire des choses. Lorsque la même chose se fait différemment dans différents endroits, il rend plus difficile les erreurs courantes. P>
Il a déjà été mentionné ici, mais je vais le répéter parce que je crois que cela ne peut pas être suffisant: p>
La complexité inutile est l'arcade em> Nemesis de bon ingénierie. P>
Gardez-le simple. Si les choses commencent à chercher compliquée, arrêtez-vous et demandez-vous pourquoi et ce que vous pouvez faire pour casser le problème dans des morceaux plus simples et plus simples. P>
Toutes sortes de "trace". p>
Exigences. P>
De mon expérience, avoir des exigences complètes et complètes est la première étape dans la création d'un logiciel sans bogue. Vous ne pouvez pas écrire un logiciel complet et correct si vous ne savez pas ce que c'est censé faire. Vous ne pouvez pas écrire des tests appropriés pour les logiciels si vous ne savez pas de quoi il est censé faire; Vous manquerez une bonne quantité de choses que vous devriez tester. En outre, le processus simple d'écriture des exigences vous aide à les échapper. Vous trouvez tant de problèmes et de problèmes avant d'écrire la première ligne de code. p>
Nous avons un gars qui utilise notre logiciel avant l'un de nos clients. Il trouve des bugs que nos processus de tests automatisés ne trouvent pas, car il pense en tant que client non pas en tant que développeur de logiciels. Ce gars apporte également un soutien à nos clients, car il sait très bien le logiciel du point de vue du client. inestimable fort>. p>
Quelque chose n'est pas encore mentionné - quand il y a même une logique semi-complexe, nommez vos variables et fonctionne aussi précisément que possible (mais pas trop long). Cela rendra des incongruances dans leurs interactions les uns avec les autres, et avec ce qu'ils sont censés faire se démarquer mieux. La «signification» ou une partie d'analyse de la langue de votre cerveau aura davantage à saisir. Je trouve cela avec des choses vaguement nommées, votre cerveau genre de glosses sur ce qui est vraiment là et voit ce qui est / supposé / se passer au lieu de ce qui est réellement. p>
Aussi, faites nettoyer le code, il aide à garder votre cerveau de devenir flou. p>
Avis de code; J'ai personnellement trouvé beaucoup de bugs dans le code de mes collègues et ils ont trouvé des bugs dans la mienne. P>
Les critiques de code, tôt et souvent, vous aideront à comprendre le code de chaque autre (qui aide à la maintenance) et aux bogues comptent. P>
Le plus tôt vous repérez un bogue plus facile à réparer. Alors faites-les dès que vous le pouvez. P>
Bien sûr, la programmation paire prend cela à un extrême. p>
Le développement axé sur les tests combinés à une programmation de paires semble fonctionner assez bien sur la réduction des bugs. Obtenir les tests créés tôt aident à déterminer une partie de la conception ainsi que de donner une certaine confiance si quelqu'un d'autre doit travailler avec le code. P>
Création d'une représentation de chaîne de l'état de classe et d'imprimer ceux de la console. Notez que dans certains cas, une chaîne de ligne unique ne suffira pas, vous devrez coder une petite boucle d'impression, ce qui créerait une représentation multiligne de l'état de classe. Une fois que vous avez "visualisé" votre programme de telle manière que vous pouvez commencer à effectuer des erreurs de recherche. Lorsque vous savez quelle variable contenait une mauvaise valeur à la fin, il est facile de placer des affirmations partout où cette variable est attribuée ou modifiée. De cette façon, vous pouvez signaler le lieu d'erreur exact, puis le réparer sans utiliser le débogage étape par étape (qui est plutôt lent pour trouver des bogues imo).
Hier trouvé un bug vraiment désagréablement sans déboguer une seule ligne: p> Je viens de placer des déclarations d'affirmation et de redémarrer le programme, jusqu'à ce que la représentation multiligne du programme l'état était correct. p> p>
Wiki, s'il vous plaît.
"Éviter C ++" compte comme une technique?
Ouais, parce que ce n'est pas comme si seulement les applications C ++ ont des bugs dans eux.
Que diriez-vous de "débogage"? Je n'ai pas encore de vue une meilleure technique pour résoudre des bugs. ;)
Les examens des exigences, de la conception, de l'architecture et du code récoltent de grandes récompenses.