2009-08-24 3 views

Antwort

16

Ich finde das folgende ziemlich praktisch.

1) ASSERTs.
2) Ein Debug-Logger, der die Debug-Spucke, Konsole oder Datei ausgeben kann.
3) Speicherverfolgungstools.
4) Gerätetest.
5) Intelligente Zeiger.

Ich bin sicher, es Tonnen andere sind, aber ich kann die Spitze von meinem Kopf von ihnen weg :)

+0

Ja, behauptet, sind ein Lebensretter bei richtiger Anwendung. – zvrba

+0

Programmierung per Vertrag. In C++ wird das normalerweise mit ASSERTs gemacht (zumindest habe ich es so gesehen). – David

1

Verwenden einer IDE wie IntelliJ, die meinen Code prüft, wie ich es schreibe und zweifelhaften Code kennzeichnet, wie ich es schreibe.

+0

Leider sagt es Ihnen nur über Syntaxfehler oder verdächtige Konstrukte; Ein Compiler würde dir davon erzählen. Es braucht Menschen, um den Rest zu erkennen. – MarkR

+0

Es liest nicht Gedanken oder schreibt Code für Sie, aber es ist viel besser als ein statisches Code-Inspektionswerkzeug wie FindBugz, das nach dieser Tatsache überprüft. Lieber das Feedback sofort erhalten. – duffymo

31

Automatisierte Gerätetests.

+2

Ich habe das besser gefunden, um sicher zu stellen, dass Sie nicht bereits existierende Funktionen unterbrechen, sondern mehr, als Sie Bugs zu vermeiden. – Alex

+1

@windfinder: Ich stimme größtenteils zu. Aber wenn Sie Tests codieren, die sich vor der Codierung an die Spezifikation halten, können Sie Fehler finden, die sich auf die Spezifikationskonformität beziehen. – neuro

+2

Wer erhält genaue, vollständige Spezifikationen? – duffymo

4

Model-View-Controller und in der Regel nichts mit Verträgen und Schnittstellen nicht denken, die Einheit sein kann - automatisch getestet

5

finde ich viele Probleme, bevor ich Tests überhaupt starten

behauptet

+0

Eine weitere Abstimmung für den König von debug. – Pod

+4

+1, aber ich glaube, es ist ziemlich schwierig, eine Runtime Assertion auszulösen, ohne Ihren Code auszuführen (zu testen) ... – bltxd

+1

Wie Sie anscheinend bemerkt haben: Ich unterscheide "running" von "testing" hier. Viele Assertionen schlagen sofort fehl, wenn Sie beim ersten Mal neue Funktionen ausführen. Testen dagegen bedeutet gründliches Testen. –

20

Es gibt eine oft unbeachtete Technik, die ich gerne nennen möchte. Das QA-Team kann Wunder tun, um Fehler auszusortieren, bevor sie die Produktion erreichen.

Es ist meine Erfahrung (und wird oft in Lehrbüchern zitiert), dass Programmierer nicht die besten Tester machen, trotz was sie denken, weil sie dazu tendieren, Verhalten zu testen, von dem sie bereits wissen, dass es wahr ist. Darüber hinaus sind sie oft nicht sehr gut darin, Themen in die Hände des Endbenutzers zu stellen (wenn es diese Art von App ist), und so werden sie wahrscheinlich die Formatierung/Ausrichtung/Usability-Probleme der Benutzeroberfläche vernachlässigen.

Ja, Komponententests sind immens wichtig, und ich bin mir sicher, dass andere Ihnen bessere Tipps geben können als ich, aber vernachlässigen Sie nicht Ihre System-/Integrationstests. :)

..und hey, es ist eine Sprache unabhängige Technik!

+0

+1: Ist nicht "vermeiden oder beheben Sie Fehler" was QA ist? –

+2

Ja! Und es kann so schwer sein, Programmierer dazu zu bringen zu erkennen, dass sie ihren eigenen Code nicht gut testen. – Nathan

+0

@nathan: so wahr – neuro

5

Testen Sie es mit tatsächlichen, realistischen Daten von Anfang an. Und das Testen ist nicht nur während des Schreibens des Codes notwendig, sondern sollte früh in der Entwurfsphase beginnen. Finden Sie heraus, wie Ihre schlimmsten Anwendungsfälle aussehen werden, und stellen Sie sicher, dass Ihr Design damit umgehen kann. Wenn sich Ihr Design auch gegen diese Anwendungsfälle gut und elegant anfühlt, könnte es sogar gut sein.

Automatische Tests eignen sich hervorragend, um sicherzustellen, dass der von Ihnen geschriebene Code korrekt ist. Bevor Sie jedoch Code schreiben, müssen Sie sicherstellen, dass Sie die richtigen Dinge erstellen.

+3

+1 stimme ich voll und ganz zu. Das Testen gegen Simulatoren oder idealisierte Daten ist ein guter Anfang, aber das sollte nicht einmal bei Komponententests der Fall sein. Und ich sehe, dass die Anforderungen viel zu oft nicht erfüllt oder falsch interpretiert werden, daher sollte vielleicht "mehr mit der Geschäftsseite sprechen" ein weiterer Ratschlag sein. Es ist alles sehr gut, fehlerfreien Code zu liefern, aber nicht, wenn es die falsche Lösung ist. – Xiaofu

15

RAII um Ressourcenverluste zu vermeiden.

+3

RAII, um * Ressourcen * Leckfehler zu vermeiden. – avakar

+0

Nun, wahr. Obwohl ich behaupten würde, dass die am häufigsten geleakte Ressource die Erinnerung ist. Danke für die Korrektur :) –

13

Ich benutze denken.

+0

Dies ist in der Tat selten und häufig unterschätzte Technik. –

+1

kann auch nicht automatisiert werden. –

+0

@david: Es ist aber die Programme dahinter sind eng gekoppelt und von geringer Kohäsion und Rennen bis zum Stillstand. – Sam

3

Ich finde, dass Peer-Progamming dazu beiträgt, viele der dummen Fehler zu vermeiden, und altert der Zeit erzeugt Diskussionen, die Fehler aufdecken. Und mit jemandem, der frei darüber nachdenkt, warum Sie etwas tun, neigt es dazu, alles sauberer zu machen.

8

Reduzierung des Variablenbereichs auf so eng wie möglich. Weniger Variablen im äußeren Bereich - weniger Möglichkeiten, einen Fehler einzubauen und zu verbergen.

+0

Einer der besten hier. Stark unterschätzt. –

5

Lernen funktionale Programmierung hilft irgendwie. HERE
Learn you a haskell for great good.

+0

Wow, dieser zweite Link ist ein * exzellentes * Haskell-Tutorial. Intuitiv, unterhaltsam geschrieben und kaum eine Spur von FP-Selbstgefälligkeit. Es gibt sogar eine Seitenleiste von The Fonz! Aaay! –

1

Unit Testing von Continious Integration gefolgt.

1

Buchvorschläge: "Code Complete" und "Release it" sind zwei Pflichtlektüre zu diesem Thema.

+0

Sowie "Clean Code". – Reunanen

14
  1. Streben Sie nach simplicity and conciseness.
  2. Lassen Sie niemals Fälle, wo Ihr Code behavior is undefined.
  3. Suchen Sie nach Möglichkeiten, das Typsystem zu nutzen, und lassen Sie den Compiler zur Kompilierungszeit so viel wie möglich überprüfen. Vorlagen und Code-Generierung sind Ihre Freunde, solange Sie Ihren gesunden Menschenverstand behalten.
  4. Minimieren Sie die Anzahl der Singletons und globalen Variablen.
  5. Verwenden Sie RAII!
  6. Verwenden Sie assertions!
  7. Automatisches Testen einiger nominaler und aller Eckfälle.
  8. Vermeiden Sie Änderungen in letzter Minute wie die Pest.
+0

+1 für sie alle, aber vor allem (2). Meiner Erfahrung nach zahlt sich dies für etwas länger als ein 5-zeiliges Perl-Skript aus. Wann immer Sie weitere 10 Minuten brauchen und sich davon überzeugen, dass Ihre Funktion alle möglichen Fälle einschließlich Fehlerzustände behandelt, greifen Sie darauf zu!Du hast die Tür in einem Labyrinth aus windigen Passagen einfach zugeschlagen, damit du nicht wieder durchwandern musst. (Dies ist natürlich nicht immer möglich, z. B. mit UI-Code.) –

+1

Schön zu sehen, dass Sie der Einfachheit den ersten Platz gegeben haben. Es ist traurig zu sehen, dass dies bei den meisten Programmierern verloren zu sein scheint (das Abstimmungsmuster in dieser Frage veranschaulicht dies gut). +1 –

+0

Fügen Sie Links zu Referenzen zu diesen Themen hinzu und dies könnte mehr Stimmen erhalten! –

6

Ich fand, dass je mehr zur Kompilierungszeit getan und überprüft wird, desto weniger kann zur Laufzeit möglicherweise schief gehen. Also versuche ich Techniken zu nutzen, die eine strengere Überprüfung zur Kompilierungszeit erlauben. Das ist einer der Gründe, warum ich in Template-Meta-Programmierung ging. Wenn Sie etwas falsch machen, kompiliert es nicht und verlässt somit nie Ihren Schreibtisch (und kommt somit nie beim Kunden an).

+3

+1. Es ist bedauerlich, dass C++ die Metaprogrammierung so schmerzhaft macht und dass es immer noch Fehlerklassen gibt, die zur Kompilierungszeit vermeidbar sein sollten, aber noch nicht sind (z. B. das Vermeiden von Objekt-Slicing), aber hoffentlich werden sich die Dinge weiterentwickeln. –

+2

99% der Dinge haben eine Lösung. Objekt-Slicing ist vermeidbar, indem "non-leaf-Klasse ist abstrakt" und/oder alle Basisklassen-Kopierkonstruktoren/Kopierzuweisungsoperatoren geschützt werden. –

+1

Gute Punkte Richard, aber ich sehne mich immer noch nach einer Lösung, die sich nicht so sehr auf Programmiererdisziplin verlässt. –

4

Ich stimme mit vielen der anderen Antworten hier überein.

Spezifisch für C++, die Verwendung von 'const' und die Vermeidung von rohen Zeigern (für Referenzen und Smart Pointer), wenn möglich, hat mir geholfen, Fehler bei der Kompilierung zu finden.

Auch hilft eine "keine Warnungen" Politik Fehler zu finden.

1

Zusätzlich zu den bereits erwähnten Dingen glaube ich, dass einige mit C++ 0x eingeführte Funktionen dazu beitragen, bestimmte Fehler zu vermeiden. Features wie stark typisierte Enums, For-In-Schleifen und das Löschen von Standardfunktionen von Objekten kommen mir in den Sinn.

Im Allgemeinen starke Typisierung ist die Art und Weise imho über ein Projekt

1

Coding Stil Konsistenz zu gehen.

Nicht nur Leerzeichen vs. Tab Probleme, sondern auch die Art und Weise, wie Code verwendet wird. Es gibt immer mehr als eine Möglichkeit, Dinge zu tun. Wenn dasselbe an verschiedenen Stellen anders gemacht wird, erschwert es das Auffinden häufiger Fehler.

1

Es ist hier bereits erwähnt worden, aber ich sage es noch einmal, weil ich das glauben kann nicht oft genug gesagt werden:

Unnötige Komplexität ist die Bogennemesis guter Technik.

Halten Sie es einfach. Wenn die Dinge kompliziert erscheinen, hören Sie auf und fragen Sie sich, warum und was Sie tun können, um das Problem in kleinere, einfachere Stücke zu zerlegen.

3

Anforderungen.

Aus meiner Erfahrung ist die vollständige und vollständige Anforderungen die Nummer eins beim Erstellen von fehlerfreier Software. Sie können keine vollständige und korrekte Software schreiben, wenn Sie nicht wissen, was sie tun soll. Sie können keine richtigen Tests für Software schreiben, wenn Sie nicht wissen, was es tun soll; Du wirst eine Menge Dinge vermissen, die du testen solltest. Auch der einfache Prozess des Schreibens der Anforderungen hilft Ihnen, sie zu konkretisieren. Sie finden so viele Probleme und Probleme, bevor Sie überhaupt die erste Codezeile schreiben.

1

Stellen Sie jemanden ein, der Ihre Software testet/validiert.

Wir haben einen Mann, der unsere Software vor jedem unserer Kunden verwendet. Er findet Fehler, die unsere automatisierten Testprozesse nicht finden, weil er als Kunde nicht als Softwareentwickler denkt. Dieser unterstützt auch unsere Kunden, weil er die Software aus Kundensicht sehr gut kennt. INVALUIERBAR.

0

Etwas, das noch nicht erwähnt wurde - wenn es sogar halbkomplexe Logik gibt, benennen Sie Ihre Variablen und Funktionen so genau wie möglich (aber nicht zu lang). Dies wird Inkongruenzen in ihren Interaktionen verursachen, und mit dem, was sie tun sollen, stehen sie besser heraus. Der "Sinn" oder Sprachparts-Teil deines Gehirns wird mehr haben, an dem du dich festhalten kannst. Ich finde, dass dein Gehirn mit vage benannten Dingen über das, was wirklich da ist, schweift und sieht, was geschieht/geschehen soll und nicht, was tatsächlich ist.

Auch Code sauber machen, es hilft, Ihr Gehirn davon abzuhalten, unscharf zu werden.

2

Codeüberprüfungen; Ich habe persönlich viele Fehler im Code meiner Kollegen gefunden und sie haben Fehler in meinem gefunden.

Code-Überprüfungen, früh und oft, werden Ihnen helfen, den Code jedes anderen zu verstehen (was für die Wartung hilft) und Fehler zu erkennen.

Je früher Sie einen Fehler finden, desto einfacher ist es zu beheben. Mach es so schnell wie möglich.

Natürlich Paar-Programmierung nimmt dies zu einem Extrem.

0

Testgetriebene Entwicklung kombiniert mit Paarprogrammierung scheint ziemlich gut zu funktionieren, um einige Fehler zu vermeiden. Das frühzeitige Erstellen der Tests hilft bei der Entwicklung des Designs und gibt ein gewisses Vertrauen, wenn jemand anders mit dem Code arbeiten muss.

0

Erstellen einer Zeichenfolgendarstellung des Klassenstatus und Ausdrucken dieser auf der Konsole. Beachten Sie, dass in einigen Fällen eine einzelne Zeile nicht ausreicht. Sie müssen eine kleine Druckschleife codieren, die eine mehrzeilige Darstellung des Klassenstatus erzeugt. Sobald Sie Ihr Programm so "visualisiert" haben, können Sie damit beginnen, Fehler darin zu suchen.Wenn Sie am Ende wissen, welche Variable einen falschen Wert enthält, können Sie leicht überall Behauptungen platzieren, wo diese Variable zugewiesen oder geändert wird. Auf diese Weise können Sie die genaue Stelle des Fehlers lokalisieren und beheben, ohne das schrittweise Debuggen zu verwenden (was eine ziemlich langsame Art ist, Bugs imo zu finden).

Erst gestern fand einen wirklich fiesen Fehler ohne eine einzige Zeile zu Debuggen:

vector<string> vec; 
vec.push_back("test1"); 
vec.push_back(vec[0]); // second element is not "test1" after this, it's empty string 

Ich behauptet-Aussagen nur Platzierung gehalten und das Programm neu zu starten, bis mehrzeiligen Darstellung des Zustandes des Programms richtig war.

Verwandte Themen