Ist der Verfahrenscode für Komponententests wirksam?

13

Bei einem aktuellen Projekt sollten die Kräfte, die Unit-Tests wünschen, in unseren Entwicklungszyklus einbezogen werden, um die konstante Anzahl von Fehlern zu vermeiden, die in unseren Code zu sickern scheinen. Das Problem ist, dass der Spaghetti-Code zu 95% prozedural ist, mit dem ich noch nie Unit-Tests durchgeführt habe (alle meine Erfahrungen mit Unit-Tests waren mit OOP-Code).

Meine Frage in aller Kürze lautet also, ob es ratsam ist, mit dem Testen von Einheiten auf unserer aktuellen Codebasis fortzufahren, oder ob es verschoben wird, bis die Anwendung auf ein geeignetes OOP-Framework migriert wurde.

PS: Während ich versuchte, diese Frage als sprachunabhängig zu bezeichnen, habe ich das Gefühl, dass die Angabe, dass die betreffende Anwendung PHP und Javascript verwendet, spezifischere Antworten liefert, die diese Frage beantworten könnten, da dieses Vorkommen erfahrungsgemäß am häufigsten bei solchen Anwendungen auftritt.

Kanadierkraut
quelle
13
Unit-Tests verhindern keine neuen Bugs, sie verhindern Regressionen.
Daenyth
2
Mögliches Duplikat von Haben Ihnen Unit-Test-Generatoren bei der Arbeit mit altem Code geholfen? und ein Dutzend andere Fragen. Suche nach "Legacy Unit Test"
mattnz
4
Ihr Problem ist, dass es sich bei dem Code um Spaghetti / Big Ball Of Mud handelt, nicht um "prozedural" (guter prozeduraler Code ist gut testbar - BTDTGTTS). Ihre Kräfte werden lieber (mehr) Tester bekommen und eine gründliche professionelle Qualitätssicherung im Projekt veranlassen, wenn sie wirklich "die konstante Menge an Fehlern vermeiden" wollen.
gnat
@ l0b0 ja habe ich gemacht. Ich entschuldige mich, werde den Test aktualisieren, um klarer zu sein
canadiancreed
@mattnz Ya Ich habe nach prozeduralem Unit-Test gesucht, aber nicht nach Legacy. Stellte fest, dass prozedural! = Legacy ist, da immer noch neuer Code in diesem Format erstellt wird
canadiancreed

Antworten:

14

Unit-Tests eignen sich gut für Objekte, zumal sie viele ausgefallene Funktionen bieten, wie zum Beispiel Scheinobjekte, mit denen Sie schneller bessere Tests erstellen können.

Unter diesen Umständen ist es nicht verboten, Komponententests auf einer prozeduralen Codebasis durchzuführen . In OOP sind die meisten Komponententests Testmethoden, bei denen einige Parameter übergeben und entweder ein Ergebnis oder eine Ausnahme eines bestimmten Typs erwartet werden. Dies kann auch mit Prozedurcode durchgeführt werden. nur dass anstelle von Testmethoden, werden Sie Funktionen testen .

Beachten Sie, dass Sie Folgendes tun müssen:

  • Isolieren Sie die Funktionen, die Sie testen müssen, und diejenigen, die Sie nicht benötigen. In OOP ist dies einfach: Private Methoden müssen nicht getestet werden, da die Aufrufer niemals direkt darauf zugreifen können. Möglicherweise sind einige Funktionen in Ihrem Verfahrenscode so und erfordern keine Tests.

  • Denken Sie über den globalen Geltungsbereich nach . Das Problem besteht auch in OOP, aber wenn Sie sagen , dass Sie Spaghetti - Code zu testen, stehen die Chancen, dass die Leute , die diesen Code geschrieben haben schlechte Gewohnheiten, wie globale Reichweite zu viel verwenden, und einige tun verrückte Dinge wie das Ändern $_GEToder $_POSTArrays innerhalb funktionen.

  • Code außerhalb von Funktionen behandeln. Dies ist ein komplizierterer Fall, aber immer noch möglich. Entweder Sie rufen require_onceeine Seite auf, um zu sehen, was passiert, und erfassen die Ausgabe über ob_start/ob_get_clean , oder Sie führen eine HTTP-Anforderung aus der Testsuite aus und analysieren die Antwort, indem Sie den HTML-Code analysieren. Dies ist kein wirklicher UI-Test: Hier ist es Ihnen egal, ob eine Schaltfläche auf einer Seite links oder rechts angezeigt wird oder ob ein Link in großen roten Großbuchstaben oder in kleinen blauen angezeigt wird. Ihnen ist es wichtig, einige HTML-Elemente über DOM zu finden und ihren Inhalt mit dem erwarteten zu vergleichen.

  • Testen Sie die Antwortcodes . require_oncemit Ausgabepufferung ist gut, aber Sie müssen auch testen, wie die Webanwendung mit Fehlern umgeht. Wenn das erwartete Ergebnis eines Tests beispielsweise 404 Not Found lautet, müssen Sie eine HTTP-Anforderung ausführen, um die Antwort zu ermitteln.

Arseni Mourzenko
quelle
5

schlagen vor, dass es verschoben wird, bis die Anwendung auf ein ordnungsgemäßes OOP-Framework migriert wurde

Richten Sie einige automatische Tests ein, bevor Sie auf eine andere Plattform migrieren, und nicht danach. Fügen Sie während der Migration weitere Tests hinzu, nicht danach. Wenn es sich bei diesen Tests um "Integrationstests" oder Unit-Tests handelt, müssen Sie selbst entscheiden. In der Regel können Sie jedoch Ihr bevorzugtes xUnit-Testframework für beide Arten verwenden.

Doc Brown
quelle
5

Die effektivste Methode zum Starten von Komponententests besteht darin, die am häufigsten auftretenden oder die höchsten Kosten verursachenden Fehlerklassen zu ermitteln. Erstellen Sie dann Tests, die auf diese Fehler abzielen.

Wie diese Tests implementiert werden, unterscheidet sich zwischen Paradigmen und Sprachen. Das Wichtigste, was Ihre Fähigkeit zum Testen von Einheiten beeinträchtigt, ist die Qualität des Codes. weniger das verwendete Paradigma. Denken Sie daran, beim Unit-Testen geht es darum, eine "Unit" Code für sich zu testen. Alles, was sich auf Ihre Fähigkeit auswirkt, "Code-Einheiten" zu isolieren, erschwert das Testen.

  • Verwendung von Globalen
  • Nebenwirkungen
  • eng gekoppelter Code
  • schlecht gekoppelter Code
  • eine große Anzahl von Bedingungen
  • schlecht gestaltete "Einheiten"

All dies wird sich stärker auf die Schwierigkeit des Testens auswirken als das Sprachparadigma.

dietbuddha
quelle
4

Wann immer Sie eine Situation haben, in der Sie Teile Ihres Codes automatisch testen können, können Unit-Tests effektiv sein. Die Frage ist also nicht, ob der prozedurale Code effektiv als Einheit getestet werden kann, sondern ob DIESER Code als Einheit getestet werden kann. Das hängt davon ab, wie viel Status es liest und wie viel Status es festlegt. Idealerweise ist die Antwort auf beide Fragen Null. Wenn dies nicht der Fall ist, können Sie sie trotzdem testen.

Wie immer müssen Sie das Vertrauen, dass der Code korrekt ist, gegen die Kosten für das Erreichen dieses Vertrauens abwägen. Denken Sie daran, dass ein Teil des Gewinns für Unit-Tests darin besteht, die Abhängigkeiten explizit zu identifizieren. In diesem Sinne ist es im Vergleich zu OOP-Code noch effektiver, prozeduralen Code für Unit-Tests zu verwenden.

jmoreno
quelle
-4

Ich glaube nicht, dass es möglich ist, echte Komponententests gegen prozeduralen Code durchzuführen. Das Hauptproblem besteht darin, dass jede Prozedur wahrscheinlich viele Abhängigkeiten aufweist, die nicht ausgeschlossen werden können. Bestenfalls handelt es sich um Integrationstests. Ähnliches habe ich vor vielen Monden mit VB6-Modulen und VBA-Modulen in MS Access gemacht.

Das heißt, wenn Sie die Methoden, die die meisten Schmerzen verursachen, auf ein Testgerüst setzen können, muss das von Wert sein, oder?

Rob Gray
quelle
5
-1: Schlechtes Design und Implementierung sind das Problem, nicht Verfahrenscode. So wie Sie schreckliches OP schreiben können, können Sie großartigen prozeduralen Code schreiben.
Mattnz
@mattnz - Ich bin mir nicht sicher, in welcher Beziehung Ihr Kommentar zu dem steht, was ich über das Sein oder Nicht-Können von Unit-Test-Prozedurcode gesagt habe.
Rob Gray
7
Der Verfahrenscode ist nicht gleich Spaghetti. Es ist sehr gut möglich, gut gestalteten, modularen, sauber getrennten Code mit hoher Kohäsion und niedriger Kopplung prozedural zu schreiben.
Marjan Venema
2
Ein gutes Design führt zu Unit-Testbarkeit in jedem Code, ob prozedural oder nicht.
Doc Brown