Warum sollte ich Asserts verwenden?

Lesezeit: 11 Minuten

Ich bin nie auf die Idee von Asserts gekommen – warum sollte man sie jemals verwenden?

Ich meine, sagen wir, ich wäre ein Formelfahrer und alle Asserts waren Dinge wie Sicherheitsgurt, Helm usw.

Die Tests (im Debug) waren alle in Ordnung, aber jetzt wollen wir Rennen fahren (Release)! Sollten wir alle Sicherheitsvorkehrungen fallen lassen, weil es beim Testen keine Probleme gab?

Ich werde sie niemals entfernen. Ich denke, die meisten Leute, die behaupten, dass das Entfernen von etwas, das mit Asserts vergleichbar ist, nie ihren Code profiliert haben oder die Asserts absolut verschoben wurden. Ich habe noch nie einen wirklichen Leistungsvorteil gesehen, insbesondere in Bezug auf die 80/20-Regel.

Also, verfehle ich irgendwie den Punkt, oder könnte mir jemand sagen, warum ich Asserts verwenden sollte? Übrigens verwende ich Unit-Tests.

  • Sie sind nie auf die Idee gekommen, und doch werden Sie sie niemals entfernen? Scheint, als ob Sie gleichzeitig zustimmen und nicht zustimmen.

    – ralphtheninja

    4. Juli 2009 um 9:42 Uhr

  • Zusicherungen werden nur von faulen Programmierern verwendet, die keine Fehlerbehandlung programmieren wollen. Wenn Sie wissen, dass ein Fehler möglich ist, behandeln Sie ihn. Wenn dies nicht möglich ist, besteht kein Grund zur Geltendmachung.

    – Justin

    7. August 2009 um 17:09 Uhr

  • Justin, dafür sind Behauptungen nicht da. Asserts sind dazu da, hart in die Luft zu jagen, wenn etwas passiert, das buchstäblich niemals passieren sollte (weil es auf einen Programmierfehler hinweist). Sie sind nicht für den Umgang mit alltäglichen, vorhersehbaren Fehlerbedingungen gedacht.

    – Mike Daniels

    7. August 2009 um 17:17 Uhr

Benutzer-Avatar
jalf

Erstens der Leistungsunterschied kann riesig sein. In einem Projekt verursachten unsere Behauptungen buchstäblich eine 3-fache Verlangsamung. Aber sie haben uns geholfen, einige wirklich lästige Fehler aufzudecken.

Genau das ist der Punkt.

Asserts sind da, um Ihnen zu helfen, Fehler zu finden. Und Weil Da sie in Release-Builds entfernt werden, können wir es uns leisten, viele davon einzubauen, ohne uns Gedanken über die Leistung machen zu müssen. Wenn Sie nicht da sind, um auf fehlgeschlagene Behauptungen tatsächlich zu reagieren, werden sie wertlos, also können wir sie genauso gut entfernen.

Auch das Abfangen des Fehlers und das Auslösen einer Ausnahme ist keine wirkliche Lösung. Die Programmlogik ist fehlerhaft, und selbst wenn wir die Ausnahme behandeln, ist das Programm immer noch kaputt.

Was Behauptungen im Grunde darauf hinauslaufen, ist “Warum sollten Sie sich die Mühe machen, Fehler abzufangen, mit denen Sie nicht umgehen können?”

Einige Fehler müssen während der Entwicklung abgefangen werden. Wenn sie über das Testen hinaus in den von einem Kunden verwendeten Release-Build schlüpfen, ist das Programm einfach kaputt, und keine noch so große Laufzeitfehlerprüfung wird es beheben.

Ich bin nie auf die Idee von Asserts gekommen – warum sollte man sie jemals verwenden?

Ich meine, sagen wir, ich wäre ein Formelfahrer und alle Asserts waren Dinge wie Sicherheitsgurt, Helm usw.

Ja, das ist ein gutes Beispiel dafür, wann nicht ein Assertion verwenden. Dies sind Dinge, die zur Laufzeit tatsächlich schief gehen können und die überprüft werden müssen. Ihr Formel-1-Fahrer könnte einige Sicherheitsvorkehrungen vergessen, und wenn er dies tut, wollen wir die ganze Sache stoppen, bevor jemand verletzt wird.

Aber was ist mit der Prüfung, ob der Motor eingebaut ist? Müssen wir das überprüfen während des Rennens?

Natürlich nicht. Wenn wir ohne Motor ins Rennen gehen, sind wir am Arsch, und selbst wenn wir den Fehler entdecken, ist es zu spät, etwas dagegen zu unternehmen.

Stattdessen ist dies ein Fehler, der während der Entwicklung abgefangen werden muss oder gar nicht. Wenn die Designer vergessen, einen Motor in ihr Auto einzubauen, müssen sie diesen Fehler während der Entwicklung erkennen. Das ist eine Behauptung. Es ist für die Entwickler während der Entwicklung relevant, aber danach darf der Fehler nicht mehr vorhanden sein, und wenn doch, können wir nichts tun.

Das ist im Grunde der Unterschied. Eine Ausnahme soll dem Benutzer helfen, Fehler zu behandeln, die behandelt werden können.

Ein Assertion ist da, um zu helfen Sieindem Sie auf Fehler aufmerksam gemacht werden, die gar nicht erst auftreten dürfen und vor dem Produkt behoben werden müssen kann versendet werden. Fehler, die nicht von Benutzereingaben abhängen, sondern davon, dass Ihr Code das tut, was er tun soll.

Die Quadratwurzel aus vier muss noch nie auf drei auswerten. Der Fehler ist einfach unmöglich. Wenn es auftritt, ist Ihre Programmlogik einfach kaputt. Es spielt keine Rolle, wie viel Fehlerbehandlung wir darum wickeln, es ist etwas, das während der Entwicklung abgefangen werden muss oder überhaupt nicht. Wenn wir die Ausnahmebehandlung verwenden, um nach diesem Fehler zu suchen und ihn zu behandeln, was wird die Ausnahme tun? Sagen Sie dem Benutzer: “Das Programm ist grundlegend kaputt. Verwenden Sie es niemals”?

Eine E-Mail des Entwicklers hätte das erreichen können. Warum sollte man es in den Programmcode einbauen? Das ist ein Beispiel für ein Problem, das einfach nicht auftreten darf. Wenn ja, müssen wir zurückgehen und das Programm reparieren. Eine andere Form der Fehlerbehandlung ist nicht möglich.

Einige Fehler, wie z. B. das Öffnen einer Datei zum Lesen, sind jedoch vorhanden möglich. Auch wenn es schlimm sein kann, wenn es passiert, müssen wir es akzeptieren kann passieren. Also müssen wir damit umgehen, wenn es so ist.

Asserts dienen dazu, die Fehler abzufangen, die unmöglich passieren können.

  • Ich denke, dass viele Beiträge hier wahr sind, aber dieser kommt meiner Philosophie sehr nahe. Asserts helfen mir beim Entwickeln, beim Erstellen meiner Anwendung. Ich ziehe es vor, dass es stoppt und einen Crash-Dump generiert, sobald ein Fehler auftritt, den ich nicht erwarte, während ich meine Entwicklung durchführe.. Rennen 🙂 . +1 !

    – Yves Baumes

    7. August 2009 um 17:26 Uhr

  • Das ist wahrscheinlich das, was ein Formel-1-Team tut, wenn es zum Beispiel einen neuen Motor entwickelt. Sie haben ihren Motor auf einer Rennstrecke mit vielen Sensoren und anderem Zeug getestet. Wenn die Leute in der Box Fehler entdecken, bitten sie den Fahrer, an der Box anzuhalten, um Korrekturen vorzunehmen usw. usw. Bis sie ihr Ziel erreicht haben: ein produktionsreifer Motor. 🙂

    – Yves Baumes

    7. August 2009 um 17:30 Uhr

  • „Wenn wir ohne Motor ins Rennen gehen, sind wir am Arsch“ Aber wie wäre es mit „Wir sind ohne Bremse ins Rennen gegangen“? Das Auto startet immer noch gut, aber der Fahrer wäre am Arsch mitten im Rennen, wenn sich beim Start des Rennens niemand darum kümmern wollte. In diesem Fall, wenn wir den Fehler entdecken, ist er es nicht zu spät, um etwas dagegen zu unternehmen – wir können die Sache abbrechen und das Leben des Fahrers nicht gefährden. Genau genommen – wenn etwas die Assertion (in der Produktion) umgangen hat, könnte das Programm alles tun, einschließlich des Löschens sensibler Dateien.

    – kizzx2

    5. Dezember 2010 um 13:52 Uhr


  • @kizzx2: “vor dem Rennen” ist analog zu beim Testen/Kompilierenwo Asserts praktisch sind. während des Rennens entspricht zur Laufzeit. Ich verstehe also nicht wirklich, wie dies irgendetwas widerspricht, was ich gesagt habe. Das Auto darf nicht ohne Bremsen ins Rennen gehen. Ein solcher Fehler muss abgefangen werden Vor das Auto wird gestartet. Genauso wie bestimmte Fehler in der Software abgefangen werden müssen Vor das Programm wird gestartet: während des Kompilierens/Testens, zum Beispiel über ein Assert. Wenn Sie ohne Bremsen ins Rennen gehen, hilft das Signalisieren eines Fehlers nicht wirklich. Es ist zu spät, um das Problem sicher zu behandeln.

    – jalf

    5. Dezember 2010 um 15:37 Uhr


  • Ich entschuldige mich – Analogien reichen nur so weit. Ich denke, meine Punkte lassen sich wie folgt zusammenfassen: 1) Wir wissen nie, was unmöglich ist – wenn wir es wüssten, würde keine Software abstürzen. Als was wir dachten unmöglich (Behauptungen) könnten genauso gut in der Produktion passieren. 2) Wenn eine fehlgeschlagene Assertion nicht gestoppt wird – das Programm ist in ein undefiniertes Verhalten eingetreten. Ich finde es unverantwortlich, das Programm ohne weiterlaufen zu lassen irgendein Art der Fehlerbehandlung. ——- Natürlich ist es nicht die absolute Wahrheit. Einige Programme (geschäftskritisch) erfordern strengere Sicherheitsüberprüfungen und für einige „muss die Show weitergehen“ (z. B. Videospiele).

    – kizzx2

    5. Dezember 2010 um 23:48 Uhr

Benutzer-Avatar
klar

Andrew Koenig hatte früher eine gute philosophische Diskussion über die Verwendung von Ausnahmen und Behauptungen im Versandkodex. Schlussendlich, Sie hüten sich davor, wilde Dinge zu tun, wenn das Programm in einem irreparabel kaputten Zustand ist.

Ich glaube daher, dass es besser ist, wenn ein Programm etwas entdeckt, das mit seinem internen Zustand unwiderlegbar falsch ist, es sofort zu beenden, anstatt seinem Aufrufer die Gelegenheit zu geben, so zu tun, als wäre nichts falsch.

Wenn Sie möchten, denke ich, dass Ausnahmen für Situationen reserviert sein sollten, in denen es möglich ist, nach dem Abfangen der Ausnahme etwas Vernünftiges zu tun. Wenn Sie einen Zustand entdecken, den Sie für unmöglich hielten, ist es schwer, viel darüber zu sagen, was danach passieren könnte.

  • Beachten Sie, dass der Artikel noch verfügbar ist das Internetarchiv.

    – Qantas 94 Schwer

    31. August 2014 um 1:05 Uhr


Aus Code Complete 2: „Verwenden Sie die Fehlerbehandlung für Bedingungen, von denen Sie erwarten, dass sie eintreten; verwenden Sie Zusicherungen für Bedingungen, die niemals eintreten sollten.“

Ein häufig zitiertes Beispiel ist die Prüfung auf Null im Nenner vor einer Division.

Es wird erwartet, dass Sie die Behauptungen aus dem Produktionscode entfernen. Sie sind während der Entwicklung vorhanden, um Ihnen zu helfen, Fehler zu erkennen.

Unit-Tests sind kein Ersatz für Behauptungen.

  • “Verwenden Sie Zusicherungen für Bedingungen, die niemals eintreten sollten.” Ich dachte immer, das klang sehr nach Ausnahmebehandlung.

    – geowa4

    4. Juli 2009 um 3:29 Uhr

  • Die Ausnahmebehandlung ist für Dinge gedacht, von denen Sie wissen, warum sie auftreten, und die Sie innerhalb des Programms behandeln können. Wenn eine Assertion fehlschlägt, ist etwas so falsch, dass Sie nicht wissen, was Sie tun sollen, und das Programm sollte beendet werden.

    – Janusz

    4. Juli 2009 um 3:36 Uhr

  • @ George IV: Der Unterschied besteht darin, dass Behauptungen für Dinge gelten, von denen Sie glauben, dass sie unmöglich sind, wenn Ihr Programm korrekt ist. Ausnahmen gelten für Dinge, die nicht passieren sollten, in dem Sinne, dass Ihre Routine/Ihr Programm nicht funktionieren kann, wenn sie es tun. Daher lösen Bibliotheken manchmal Ausnahmen für Dinge aus, bei denen eine Anwendung behaupten würde, da die Bibliothek nicht weiß, ob das Problem aus dem POV des Programms nicht vorstellbar ist (z andere können Sie nicht).

    – Steve Jessop

    4. Juli 2009 um 13:08 Uhr

  • Unit-Tests sind kein Ersatz für Behauptungen. Können Sie weitere hinzufügen, um sie zu unterscheiden?

    – mfaani

    1. Mai 2018 um 18:20 Uhr

Weil sie das Debuggen erleichtern.

Der zeitaufwändige Teil des Debuggens besteht darin, ein Problem von dem Symptom, das Sie zuerst bemerken, bis zum Fehler im Code zurückzuverfolgen. Gut geschriebene Behauptungen lassen das Symptom, das Sie bemerken, viel näher an das eigentliche Codeproblem heranrücken.

Ein sehr einfaches Beispiel wäre ein Fehler, bei dem Sie über das Ende eines Arrays hinaus indizieren und eine Speicherbeschädigung verursachen, die schließlich einen Absturz verursacht. Es kann lange dauern, vom Absturz bis zur betreffenden Indexoperation zurückzuverfolgen. Wenn Sie jedoch neben dieser Indexoperation eine Assertion haben, die Ihren Index überprüft, schlägt Ihr Programm direkt neben dem Fehler fehl, sodass Sie das Problem schnell finden können.

Es ist ein umstrittenes Thema. Viele Leute, wie ich, ziehen es tatsächlich vor, sie im Produktionscode aktiviert zu lassen. Wenn Ihr Programm sowieso ins Unkraut gerät, können Sie die Assertion genauso gut darin haben, damit Ihr Kunde Ihnen zumindest die Zeilennummer und den Dateinamen geben kann (oder welche Informationen oder Aktionen Sie auch immer für die Assertion konfigurieren). Wenn Sie die Behauptung weggelassen haben, konnte der Kunde Ihnen nur sagen: „Es ist abgestürzt“.

Das bedeutet, dass Sie wahrscheinlich keine teuren Operationen in Ihren Assert-Prüfungen durchführen oder zumindest profilieren sollten, um zu sehen, ob sie Leistungsprobleme verursachen werden.

Sie ermöglichen es Ihnen, Ihre Annahmen zu testen. Angenommen, Sie möchten die Geschwindigkeit berechnen. Sie möchten wahrscheinlich behaupten, dass Ihre Berechnung weniger als die Lichtgeschwindigkeit ist.

Behauptungen sind für die Entwicklung, um sicherzustellen, dass Sie nichts vermasseln.

Benutzer-Avatar
Larry Watanabe

Aus Ihrem Beitrag geht hervor, dass Sie der Idee, Assertionen zu verwenden, nicht widersprechen, sondern eher der Idee, Assertionen im Debug zu haben und sie nicht in der Produktion aktiv zu haben.

Der Grund dafür ist, dass Sie beim Debuggen möglicherweise möchten, dass der Prozess katastrophal fehlschlägt – dh eine Ausnahme auslöst und beendet wird, damit der Fehler behoben werden kann. In der Produktion könnte sich dies auf Ihr gesamtes System auswirken, und die Fehlerbedingung könnte nur in sehr wenigen Fällen auftreten. In der Produktion möchten Sie also wahrscheinlich den Fehler protokollieren, aber den Prozess am Laufen halten.

Mithilfe von Zusicherungen können Sie das Verhalten zwischen Debug und Release ändern.

Ich stimme Ihnen zu, dass die Zusicherungen nicht nur im Produktionscode zum Schweigen gebracht werden sollten – viele Fehler werden in Testumgebungen nicht aufgedeckt, und es ist wichtig zu wissen, wann Zusicherungen in der Produktion fehlschlagen.

  • Behauptungen verlangsamen den Code. Wir haben sie in Videospielen verwendet und sie waren während vieler Tests dabei. Sie mussten danach ausgezogen werden. Sie behaupten nicht auf einem GameCube.

    – Nosredna

    4. Juli 2009 um 13:36 Uhr

1015650cookie-checkWarum sollte ich Asserts verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy