Frage

Als unerfahrener Entwickler, der gerade in den Rhythmus meines ersten professionellen Projekts kommt, versuche ich, so schnell wie möglich gute Gewohnheiten zu entwickeln.Allerdings habe ich festgestellt, dass ich den Test oft vergesse, ihn verschiebe oder eine ganze Reihe von Tests am Ende eines Builds durchführe, anstatt einen nach dem anderen.

Meine Frage ist, welchen Rhythmus Sie bei der Arbeit an großen Projekten bevorzugen und wo das Testen dazu passt.

War es hilfreich?

Lösung

Nun, wenn Sie den TDD-Leuten folgen möchten, bevor Sie mit dem Codieren beginnen ;)

Ich bin in der gleichen Situation wie Du.Ich möchte mich mehr mit dem Testen befassen, aber ich befinde mich derzeit in einer Situation, in der wir daran arbeiten, „den Code herauszubekommen“ und nicht „den Code richtig herauszubekommen“, was mir eine Heidenangst einjagt.Deshalb versuche ich langsam, Testprozesse in meinen Entwicklungszyklus zu integrieren.

Momentan, Ich teste, während ich programmiere, und versuche, den Code zu zerstören, während ich ihn schreibe.Es fällt mir schwer, mich in die TDD-Denkweise hineinzuversetzen.Es braucht Zeit, aber so würde ich es tun wollen arbeiten..

BEARBEITEN:

Ich dachte, ich sollte das wahrscheinlich näher erläutern, das ist mein grundlegender „Arbeitsprozess“ ...

  1. Planen Sie, was ich vom Code will, möglicher Objektdesign, was auch immer.
  2. Erstellen Sie meine erste Klasse und fügen Sie einen riesigen Kommentar zum Top hinzu, in dem sie darstellen, was meine "Vision" für die Klasse ist.
  3. Skizzieren Sie die grundlegenden Testszenarien.Diese werden im Grunde die Einheitstests.
  4. Erstelle meine erste Methode.Schreiben Sie auch einen kurzen Kommentar, in dem erklärt wird, wie es ist erwartet arbeiten.
  5. Schreiben Sie einen automatisierten Test, um zu sehen, ob er das tut, was ich erwarte.
  6. Wiederholen Sie die Schritte 4–6 für jede Methode (beachten Sie, dass sich die automatisierten Tests in einer riesigen Liste befinden, die mit F5 ausgeführt wird).
  7. Anschließend erstelle ich einige umfangreiche Tests, um die Klasse in der Arbeitsumgebung zu emulieren und dabei natürlich alle Probleme zu beheben.
  8. Wenn danach neue Fehler ans Licht kommen, gehe ich zurück und schreibe den neuen Test ein, stelle sicher, dass er fehlschlägt (dies dient auch als Proof-of-Concept für den Fehler) und behebe ihn dann.

Ich hoffe das hilft..Ich bin offen für Kommentare dazu, wie man das verbessern kann, da es mir, wie gesagt, ein Anliegen ist.

Andere Tipps

Bevor Sie den Code einchecken.

Zuerst und oft.Wenn ich neue Funktionen für das System erstelle, möchte ich zunächst die Schnittstellen definieren und dann Komponententests für diese Schnittstellen schreiben.Um herauszufinden, welche Tests geschrieben werden müssen, berücksichtigen Sie die API der Schnittstelle und die von ihr bereitgestellte Funktionalität, holen Sie Stift und Papier heraus und denken Sie eine Weile über mögliche Fehlerbedingungen oder Möglichkeiten nach, um zu beweisen, dass sie die richtige Aufgabe erfüllt.Wenn dies zu schwierig ist, ist Ihre API wahrscheinlich nicht gut genug.Sehen Sie in Bezug auf die Tests nach, ob Sie das Schreiben von „Integrationstests“, die mehr als ein bestimmtes Objekt testen, vermeiden und diese als „Einheiten“-Tests behalten können.

Erstellen Sie dann eine Standardimplementierung Ihrer Schnittstelle (die nichts tut, Müllwerte zurückgibt, aber keine Ausnahmen auslöst), und fügen Sie sie in die Tests ein, um sicherzustellen, dass die Tests fehlschlagen (dies testet, ob Ihre Tests funktionieren!:) ).Schreiben Sie dann die Funktionalität ein und führen Sie die Tests erneut aus.Dieser Mechanismus ist nicht perfekt, deckt jedoch viele einfache Codierungsfehler ab und bietet Ihnen die Möglichkeit, Ihre neue Funktion auszuführen, ohne sie in die gesamte Anwendung einbinden zu müssen.

Anschließend müssen Sie es in der Hauptanwendung mit der Kombination vorhandener Funktionen testen.Hier ist das Testen schwieriger und sollte, wenn möglich, teilweise an einen guten QA-Tester ausgelagert werden, da dieser das Talent hat, Dinge kaputt zu machen.Obwohl es hilfreich ist, wenn Sie auch über diese Fähigkeiten verfügen.Das richtige Testen ist ein Talent, das man sich aneignen muss, um ehrlich zu sein.Meine eigene Erfahrung beruht auf meinen eigenen naiven Einsätzen und den daraus resultierenden Fehlern, die von den Benutzern gemeldet wurden, als sie es im Zorn benutzten.

Als mir das passierte, fand ich es zunächst irritierend, dass der Benutzer absichtlich versuchte, meine Software zu beschädigen, und ich wollte alle „Fehler“ als „Trainingsprobleme“ markieren.Nachdem ich darüber nachgedacht hatte, wurde mir jedoch klar, dass es unsere Aufgabe (als Entwickler) ist, die Anwendung selbst für Idioten so einfach und zuverlässig wie möglich zu machen.Es ist unsere Aufgabe, Idioten zu stärken, und dafür bekommen wir den Dollar.Umgang mit Idioten.

Um einen solchen Test effektiv durchführen zu können, muss man sich darauf einstellen, alles kaputt zu machen.Übernehmen Sie die Rolle eines Benutzers, der auf die Schaltflächen drückt und im Allgemeinen versucht, Ihre Anwendung auf seltsame und wunderbare Weise zu zerstören.Gehen Sie davon aus, dass, wenn Sie keine Mängel finden, diese in der Produktion entdeckt werden, was zu einem ernsthaften Gesichtsverlust Ihres Unternehmens führt.Übernehmen Sie die volle Verantwortung für all diese Probleme und verfluchen Sie sich selbst, wenn in der Produktion ein Fehler entdeckt wird, für den Sie verantwortlich (oder sogar teilweise verantwortlich) sind.

Wenn Sie die meisten der oben genannten Schritte ausführen, sollten Sie damit beginnen, viel robusteren Code zu erstellen. Dies ist jedoch eine Art Kunstform und erfordert viel Erfahrung, um darin gut zu sein.

Ein guter Schlüssel, den man sich merken sollte, ist

„Testen Sie früh, testen Sie oft und testen Sie erneut, wenn Sie denken, dass Sie fertig sind.“

Wann testen?Wenn es wichtig ist, dass der Code korrekt funktioniert!

Wenn ich etwas für mich selbst zusammenhacke, teste ich es am Ende.Schlechte Praxis, aber das sind normalerweise kleine Dinge, die ich ein paar Mal verwende, und das war's.

Bei einem größeren Projekt schreibe ich Tests, bevor ich eine Klasse schreibe, und führe die Tests nach jeder Änderung an dieser Klasse aus.

Ich teste ständig.Nachdem ich auch nur eine Schleife innerhalb einer Funktion beendet habe, führe ich das Programm aus, erreiche einen Haltepunkt am Anfang der Schleife und führe sie dann durch.Dies alles dient nur dazu, sicherzustellen, dass der Prozess genau das tut, was ich möchte.

Sobald eine Funktion fertig ist, testen Sie sie vollständig.Sie möchten wahrscheinlich kurz vor dem Aufruf der Funktion einen Haltepunkt festlegen und Ihren Debugger überprüfen, um sicherzustellen, dass er einwandfrei funktioniert.

Ich schätze, ich würde sagen:„Testen Sie oft.“

Ich habe Unit-Tests erst kürzlich zu meinem regulären Arbeitsablauf hinzugefügt, aber ich schreibe Unit-Tests:

  • um die Anforderungen für jedes neue Codemodul auszudrücken (direkt nachdem ich die Schnittstelle geschrieben habe, aber bevor ich die Implementierung geschrieben habe)
  • Jedes Mal, wenn ich denke: „Es wäre besser...“bis ich fertig bin“
  • Wenn etwas kaputt geht, um den Fehler zu quantifizieren und zu beweisen, dass ich ihn behoben habe
  • Wenn ich Code schreibe, der explizit Speicher zuweist oder freigibt, hasse ich es, nach Speicherlecks zu suchen ...

Ich führe die Tests bei den meisten Builds durch und zwar immer, bevor ich den Code ausführe.

Beginnen Sie mit Unit-Tests.Schauen Sie sich insbesondere TDD (Test Driven Development) an.Das Konzept hinter TDD besteht darin, dass Sie zuerst die Komponententests schreiben und dann Ihren Code schreiben.Wenn der Test fehlschlägt, gehen Sie zurück und überarbeiten Ihren Code.Wenn die Prüfung bestanden wird, fahren Sie mit der nächsten fort.

Ich verfolge einen hybriden Ansatz für TDD.Ich schreibe nicht gerne Tests gegen nichts, deshalb schreibe ich normalerweise zuerst einen Teil des Codes und füge dann die Komponententests ein.Es ist ein iterativer Prozess, mit dem man nie wirklich fertig ist.Sie ändern den Code, Sie führen Ihre Tests durch.Wenn Fehler auftreten, beheben Sie diese und wiederholen Sie den Vorgang.

Die andere Art von Tests sind Integrationstests, die später im Prozess erfolgen und normalerweise von einem QA-Testteam durchgeführt werden.In jedem Fall geht es bei Integrationstests um die Notwendigkeit, die Teile als Ganzes zu testen.Es geht um das funktionierende Produkt, das Sie testen möchten.Dies ist schwieriger zu handhaben, da normalerweise automatisierte Testtools (z. B. Robot) erforderlich sind.

Schauen Sie sich auch ein Produkt wie CruiseControl.NET an, um kontinuierliche Builds durchzuführen.CC.NET ist nett, weil es Ihre Unit-Tests bei jedem Build durchführt und Sie sofort über etwaige Fehler benachrichtigt.

Wir machen hier kein TDD (obwohl einige es befürwortet haben), aber unsere Regel ist, dass Sie Ihre Unit-Tests mit Ihren Änderungen einchecken sollen.Das passiert nicht immer, aber es ist einfach, noch einmal einen Blick auf einen bestimmten Änderungssatz zu werfen und zu sehen, ob Tests geschrieben wurden oder nicht.

Ich stelle fest, dass ich, wenn ich mit dem Schreiben einer neuen Funktion zum Testen warte, viele Randfälle vergesse, von denen ich dachte, dass sie die Funktion zerstören könnten.Das ist in Ordnung, wenn Sie Dinge tun, um für sich selbst zu lernen, aber in einem beruflichen Umfeld ist mein Ablauf meiner Meinung nach die klassische Form von:Rot, Grün, Refaktor.

Rot:Schreiben Sie Ihren Test so, dass er fehlschlägt.Auf diese Weise wissen Sie, dass der Test die richtige Variable überprüft.

Grün:Machen Sie Ihren neuen Test auf einfachste Weise erfolgreich.Wenn das bedeutet, dass es fest codiert werden muss, ist das in Ordnung.Das ist ideal für diejenigen, die einfach nur wollen, dass etwas sofort funktioniert.

Umgestalten:Nachdem Ihr Test nun bestanden ist, können Sie beruhigt zurückgehen und Ihren Code ändern.Ihre neue Veränderung hat Ihren Test bestanden?Großartig, Ihre Änderung hatte eine Auswirkung, von der Sie nicht wussten, dass es Ihnen jetzt Ihr Test verrät.

Dieser Rhythmus hat dazu geführt, dass ich meine Entwicklung im Laufe der Zeit beschleunigt habe, da ich im Grunde einen History-Compiler für alle Dinge habe, von denen ich dachte, dass sie überprüft werden müssen, damit eine Funktion funktioniert!Dies wiederum führt zu vielen weiteren Vorteilen, auf die ich hier nicht näher eingehen werde...

Viele tolle Antworten hier!

Ich versuche, auf der niedrigsten Ebene zu testen, die Sinn macht:

  • Wenn eine einzelne Berechnung oder Bedingung schwierig oder komplex ist, fügen Sie beim Schreiben Testcode hinzu und stellen Sie sicher, dass jedes Teil funktioniert.Kommentieren Sie den Testcode aus, wenn Sie fertig sind, aber belassen Sie ihn dort, um zu dokumentieren, wie Sie den Algorithmus getestet haben.

  • Testen Sie jede Funktion.

    • Trainieren Sie jeden Zweig mindestens einmal.
    • Üben Sie die Randbedingungen – Eingabewerte, bei denen der Code sein Verhalten ändert – um „um eins“-Fehler abzufangen.
    • Testen Sie verschiedene Kombinationen gültiger und ungültiger Eingaben.
    • Suchen Sie nach Situationen, die den Code beschädigen könnten, und testen Sie sie.
  • Testen Sie jedes Modul mit der gleichen Strategie wie oben.

  • Testen Sie den Code als Ganzes, um sicherzustellen, dass die Komponenten ordnungsgemäß interagieren.Wenn Sie bei Tests auf niedrigerer Ebene sorgfältig vorgegangen sind, handelt es sich im Wesentlichen um einen „Vertrauenstest“, um sicherzustellen, dass beim Zusammenbau nichts kaputt geht.

Da der Großteil meines Codes für eingebettete Geräte bestimmt ist, achte ich besonders auf Robustheit, Interaktion zwischen verschiedenen Threads, Aufgaben und Komponenten sowie unerwartete Ressourcennutzung:Arbeitsspeicher, CPU, Dateisystemspeicherplatz, usw.

Im Allgemeinen gilt: Je früher Sie auf einen Fehler stoßen, desto einfacher ist es, ihn zu isolieren, zu identifizieren und zu beheben – und desto mehr Zeit haben Sie für die Erstellung, anstatt ihm nachzujagen.*

**Ich weiß, -1 für die unnötige Pufferzeigerreferenz!*

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top