Wie können Sie TDD für einen Fehler durchführen, der erst getestet werden kann, nachdem er behoben wurde?

13

Hier ist ein Beispiel: Meine Webanwendung enthält ziehbare Elemente. Beim Ziehen eines Elements erzeugt der Browser ein "Geisterbild". Ich möchte das "Geisterbild" beim Ziehen entfernen und schreibe einen Test für dieses Verhalten.

Mein Problem ist, dass ich zunächst keine Ahnung habe, wie ich diesen Fehler beheben kann. Ich kann einen Test nur schreiben, nachdem ich ihn behoben habe.

In einer einfachen Funktion wie let sum = (a, b) => a - bkönnen Sie einen Test schreiben, warum sum(1, 2)nicht gleich ist, 3bevor Sie Code schreiben.

In dem Fall, den ich beschreibe, kann ich nicht testen, da ich nicht weiß, was die Überprüfung ist (ich weiß nicht, wie die Behauptung lauten soll).

Eine Lösung für das beschriebene Problem ist:

let dataTransfer = e.dataTransfer
let canvas = document.createElement('canvas');
canvas.style.opacity = '0';
canvas.style.position = 'absolute';
canvas.style.top = '-1000px';
dataTransfer.effectAllowed = 'none';

document.body.appendChild(canvas);
dataTransfer.setDragImage(canvas, 0, 0);

Ich hätte nicht wissen können, dass dies die Lösung war. Ich hätte den Test nicht einmal schreiben können, nachdem ich die Lösung online gefunden hatte, denn ich hätte nur dann wissen können, ob er wirklich funktioniert, wenn ich diesen Code in meine Codebasis aufgenommen und mit dem Browser überprüft hätte, ob er den gewünschten Effekt hat. Der Test musste nach dem Code geschrieben werden, der gegen TDD geht.

Was wäre der TDD-Ansatz für dieses Problem? Ist das Schreiben des Tests vor dem Code obligatorisch oder optional?

maximedupre
quelle
2
Dann recherchiere. Eine Lösung finden ... Dann schreiben Sie Ihren Test, Fix und Refactor. Tests sollen nicht (nur) überprüfen, ob Ihr Code funktioniert, sondern Ihre gesamte Lösung zukunftssicher machen. Zunächst erstellen Sie einen Test, der fehlschlägt. Welche Eigenschaft werden Sie testen? Das ist ein Weg, um zu beginnen.
Juan Carlos Eduardo Romaina Ac
@Kilian Foth: Ich sehe deine guten Absichten, indem ich den Fragentitel ändere, aber deine Bearbeitung macht Teile meiner Antwort ungültig. Außerdem passte Ihr neuer Titel meiner Meinung nach nicht gut zum Fragenkörper. Also habe ich einen Rollback gemacht, keine Beleidigung.
Doc Brown

Antworten:

26

Wenn ich Sie richtig verstanden habe, können Sie nicht einmal einen zuverlässigen automatisierten Test für Ihr "Geisterbild" -Beispiel schreiben, nachdem Sie eine Lösung gefunden haben, da die einzige Möglichkeit zur Überprüfung des korrekten Verhaltens darin besteht, auf den Bildschirm zu schauen und zu überprüfen, ob kein Geisterbild vorhanden ist nicht mehr. Das gibt mir den Eindruck, dass Ihre ursprüngliche Überschrift die falsche Frage gestellt hat. Die eigentliche Frage sollte sein

  • Wie teste ich automatisch ein bestimmtes Verhalten einer grafischen Benutzeroberfläche?

Und die Antwort ist - für einige Arten von UI-Problemen tun Sie das nicht . Natürlich kann man versuchen, die Anzeige des Problems in der Benutzeroberfläche zu automatisieren und so etwas wie einen Screenshot-Vergleich zu implementieren. Dies ist jedoch häufig fehleranfällig, spröde und nicht kosteneffektiv.

Insbesondere das "Testfahren" der Benutzeroberfläche oder Verbesserungen der Benutzeroberfläche durch automatisierte Tests, die im Voraus geschrieben wurden, sind buchstäblich unmöglich. Sie "fahren" das UI-Design, indem Sie eine Verbesserung vornehmen, das Ergebnis einem Menschen (Ihnen, einigen Testern oder einem Benutzer) zeigen und um Feedback bitten.

Akzeptieren Sie also die Tatsache, dass TDD kein Wundermittel ist, und für einige Probleme ist das manuelle Testen sinnvoller als automatisierte Tests. Wenn Sie einen systematischen Testprozess haben, vielleicht mit einigen engagierten Testern, ist das Beste, was Sie tun können, den Fall zu ihrem Testplan hinzuzufügen.

Doc Brown
quelle
Im Allgemeinen ist das Testen der Benutzeroberfläche nicht trivial. Sie können ein generiertes Bild pinnen, dh hashen, Sie können simulieren / automatisieren, Sie können Makros aufzeichnen, Sie können eine proprietäre Lösung verwenden, Sie können manuelle Tests verwenden, dies hängt von der Situation ab und davon, wie notwendig automatisierte UI-Tests für Ihr Projekt sind.
Esoterik
1
@esoterik: yep, und all diese automatisierten Techniken sind fehleranfällig und spröde, wie ich bereits schrieb. Der einzige Ansatz, den ich kenne, ist das manuelle Testen.
Doc Brown
3
Danke für die Antwort. Ich denke, Sie haben Recht, ich hoffe zu Unrecht, in TDD eine Silberkugel zu finden. Es scheint keinen effizienten Weg zu geben, um zu testen, was ich testen möchte - Screenshot-Vergleich und all die oben genannten scheinen keinen ausreichenden ROI zu bieten. Insbesondere der Screenshot-Vergleich scheint sehr zeitaufwändig und, wie Sie sagten, fehleranfällig zu sein.
Maximedupre
1
@maximedupre: habe diese werbung für ein tool gefunden, das versucht das problem anzugehen, aber der artikel scheint trotzdem mit meiner antwort im allgemeinen übereinzustimmen .
Doc Brown
5

Was wäre der TDD-Ansatz für dieses Problem? Ist das Schreiben des Tests vor dem Code obligatorisch oder optional?

Eine Möglichkeit besteht darin, ein Analogon einer Spike-Lösung anzuwenden .

James Shore beschrieb es so:

Wir führen kleine, isolierte Experimente durch, wenn wir weitere Informationen benötigen.

Die Grundidee ist, dass Sie die Entwurfswerkzeuge ablegen , während Sie herausfinden, was vor sich geht. Sobald Sie sich orientiert haben, greifen Sie wieder zu den Konstruktionswerkzeugen.

Der Trick: Sie bringen das Wissen aus Ihrer Untersuchung zurück in Ihre Produktionscodebasis, aber Sie bringen den Code nicht mit . Stattdessen erstellen Sie es mit disziplinierten Designtechniken neu.

Pferde für Kurse.

BEARBEITEN:

Wie können Sie einen Test automatisieren, wenn der Defekt nur vom menschlichen Auge gesehen werden kann?

Ich möchte eine etwas andere Schreibweise vorschlagen: "Wie können Sie einen Test automatisieren, wenn die Automatisierung des Tests nicht kostengünstig ist?"

Die Antwort lautet natürlich "Sie nicht". Versuchen Sie stattdessen, Ihre Implementierung in zwei Teile zu unterteilen - einen großen Teil, bei dem das Testen kostengünstig ist, und einen kleineren Teil, der zu einfach zu zerlegen ist.

Es gibt zwei Möglichkeiten, ein Software-Design zu erstellen: Eine Möglichkeit besteht darin, es so einfach zu gestalten, dass es offensichtlich keine Mängel gibt - CAR Hoare

Wenn wir also mit Code von Drittanbietern arbeiten, haben wir eine sehr dünne Codeshell, die als Proxy für die Bibliothek von Drittanbietern fungiert. Im Test ersetzen wir diese Shell durch ein "Test-Double", das das Protokoll überprüft , ohne sich darum zu sorgen, dass es die gewünschten Effekte erzeugt.

Für den Test unserer Code-Integration mit dem echten Code von Drittanbietern stützen wir uns auf andere Techniken (visuelle Verifizierung, Anrufe beim technischen Support, Optimismus ...).

Es kann nützlich sein, einige Demonstrationsartefakte in der Nähe zu halten, damit Sie überprüfen können, ob Ihre Annahmen beim Upgrade der Bibliothek von Drittanbietern noch gültig sind.

VoiceOfUnreason
quelle
Ich liebe, was James Shore zu sagen hat. Ich verfolge derzeit den Screencast www.letscodejavascript.com und lerne viel. Ich werde die Links lesen, auf die Sie mich verwiesen haben.
Maximedupre
Sie haben recht, ich habe mehr über TDD und Spikes gelesen. Sie müssen tatsächlich wissen, wie der zu überprüfende Code aussieht, bevor Sie versuchen, ihn zu testen. TDD kann Ihnen nichts beibringen, was Sie noch nicht wissen, aber es kann Ihnen möglicherweise einige Dinge zeigen, die Sie lernen müssen, indem Sie James Shore umschreiben. In diesem Sinne möchte ich einen zusätzlichen Schritt in TDD vorschlagen: Spike, Test, Fail, Pass, Refactor.
Maximedupre
0

Aus einer anderen Perspektive kann das Testen rund um die Benutzeroberfläche / GUI in Bezug auf Akzeptanztests (funktions- / workflowzentrierte Tests) etwas besser durchgeführt werden.

Für das Web denke ich, dass Frameworks wie Selenium Webdriver das Potenzial haben, sich dem richtigen Test anzunähern, aber der Aufwand für den Einstieg könnte ein bisschen hoch sein, und es ist eine Verschiebung des Flusses bei TDD in Bezug auf nur Unit-Tests .

Der Teil, der speziell für Ihre Situation hilfreich ist, heißt Seitenobjektmodell ( https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html ). Dadurch wird eine explizite Zuordnung der Laufzeit-GUI zu einem bestimmten Code erreicht, entweder durch Benennen von Methoden / Ereignissen / Klassenmitgliedern.

Die Hauptargumente dagegen wären der Overhead, und dieser Overhead könnte normalerweise am Ende des Entwicklungszyklus gesehen werden. Der Overhead besteht darin, dass für die Tests ein Wrapper erforderlich ist, der anscheinend doppelte Arbeit erzeugt.

Künftig hängt dies von den Kosten und dem Nutzen des Teams und des Unternehmens ab, sodass es ein nützliches Thema sein könnte, über das diskutiert werden kann, um die Erwartungen und Ansichten zu bestimmen.

eparham7861
quelle
Ich habe kürzlich e2e / Funktionstests (mit Selenium-Web-Treiber) in TDD ausprobiert, aber der Overhead ist definitiv viel zu groß, wie Sie sagten. Sie können kein effizienter Entwickler sein und TDD mit e2e-Tests durchführen. Ich habe POM verwendet, aber der einzige Vorteil war eine verbesserte Architektur in meiner Test-Codebasis.
Maximedupre
Ja, ich denke, eine praktikablere Option, die ich von verschiedenen Unternehmen zu verschiedenen Teams gesehen habe, wäre die Integration eines manuelleren SQA-Prozesses, bei dem ein Team / Teammitglied nur dazu bestimmt ist, manuelle Tests über die Benutzeroberfläche durchzuführen. Die Tests bestehen hauptsächlich aus Screenshots und einer schrittweisen Dokumentation. Zumindest würde so etwas Anzeichen dafür liefern, dass Tests für eine Anwendung durchgeführt wurden.
eparham7861
0

Wie sieht ein Geisterbild aus? Wenn Sie eine Dummy-Benutzeroberfläche mit einer bekannten Farbe erstellt haben, wo haben Sie Ihre ziehbare Komponente abgelegt? Wäre eine bestimmte Farbe vorhanden, wenn es ein Geisterbild gäbe?

Dann könnte der Test auf das Fehlen der Farbe des Geisterbildes testen.

Ein solcher Test wäre vernünftig langlebig und machbar.

Esben Skov Pedersen
quelle
Machbar - ja. Haltbar - hängt davon ab. Wenn Sie nur die Farbe / das Thema Ihrer Benutzeroberfläche ändern, kann dies zu Problemen bei den Tests führen, die für mich nicht besonders dauerhaft klingen.
Sean Burton
1
Sie würden Ihre gesamte Benutzeroberfläche nicht testen. Sie würden eine Dummy-Benutzeroberfläche für die Drag & Drop-Komponente erstellen.
Esben Skov Pedersen
Ich bin nicht sicher, wie ich das erreichen soll, was Sie vorschlagen. Ein Geisterbild wäre in meinem Fall eine halbopake Kopie des Elements, das gezogen wird. Das Geisterbild folgt zu jeder Zeit dem Cursor, während Drag & Drop ausgeführt wird.
Maximedupre
Ja. Sie müssten das Ziehen automatisieren. Es wäre kein Unit-Test, sondern ein e2e-Test.
Esben Skov Pedersen