Codequalität bei Unit-Tests?

23

Lohnt es sich, beim Schreiben von Komponententests die zusätzliche Zeit dafür zu verwenden, dass der Code eine gute Qualität und Lesbarkeit aufweist?

Beim Schreiben von Tests verstoße ich oft gegen das Gesetz von Demeter , um schneller zu schreiben und die Verwendung so vieler Variablen zu vermeiden. Technisch gesehen werden Komponententests nicht direkt wiederverwendet - sie sind strikt an den Code gebunden, sodass ich keinen Grund sehe, viel Zeit damit zu verbringen. Sie müssen nur funktionsfähig sein.

m3th0dman
quelle
5
Lesbarkeit und Wartbarkeit müssen im Mittelpunkt des Unit-Tests stehen.
EL Yusubov
2
Tests sind auch Code!
Grant Palin
Es ist immer noch Teil Ihres Projekts, auch wenn es nicht an Kunden versendet wird. Behandle es entsprechend.

Antworten:

11

Sie sollten Ihre Komponententests in Bezug auf Qualität und Lesbarkeit auf jeden Fall genauso, wenn nicht sogar besser behandeln als Ihren Produktionscode. Die Komponententests sind oft das erste, was Sie sehen, wenn Sie versuchen, die Funktionen eines Codes zu erfassen, und der Leser sollte schnell verstehen, worum es beim Betrachten des Tests geht. Unit-Tests ändern sich auch häufig und brechen häufig, wenn ihr Design nicht robust ist, wodurch die Vorteile von Tests zunichte gemacht werden.

Die Verletzung des Gesetzes von Demeter ist definitiv ein Problem in Ihren Unit-Tests aus diesem Grund sowie in zwei anderen, die mir in den Sinn kommen:

  • Wenn Ihre Tests das Gesetz von Demeter in ihren Abschnitten Arrangieren oder Handeln brechen , ist dies wahrscheinlich ein Zeichen dafür, dass Ihr Produktionscode dies auch tut, da Ihre Komponententests nur ein weiterer Verbraucher Ihres Codes sind und wahrscheinlich die getestete Klasse in derselben aufrufen und betreiben werden Art und Weise, die jeder andere Produktionscode tun würde.

  • Wenn Ihre Tests das Gesetz von Demeter in ihren Assert-Abschnitten verletzen (dh Sie überprüfen den Wert von etwas, das tief im Abhängigkeitsdiagramm des zu testenden Objekts verschachtelt ist), handelt es sich möglicherweise tatsächlich um Integrationstests und nicht um Komponententests. Mit anderen Worten, wenn Sie in TestA behaupten, dass ABCD gleich etwas ist, könnte es sein, dass Sie tatsächlich versuchen, D und A und nicht nur A zu testen .

Übrigens, wenn Sie sagen

Ich breche sehr oft das Gesetz von Demeter, um schneller zu schreiben und nicht so viele Variablen zu verwenden.

Sie sollten sich dieses Schreibens bewusst sein

var grab = myDependency.Grab;
var something = grab.Something;
var very = something.Very;

very.Deep();

ist eigentlich nicht besser Demeter weise als

myDependency.Grab.Something.Very.Deep();

wenn du das meintest

guillaume31
quelle
47

Es lohnt sich absolut, Zeit damit zu verbringen, qualitativ hochwertigen Code für Komponententests zu schreiben:

  • Sie müssen wie jeder andere Code gewartet werden.
  • Unit-Tests sind eine der besten Dokumentationsquellen für Ihr System und wohl die zuverlässigste Form. Sie sollten wirklich zeigen:
    • Absicht: "Was ist das erwartete Verhalten?"
    • Verwendung: "Wie soll ich diese API verwenden?"
  • Sie erfordern das Debuggen wie jeder andere Code.

Der eine Faktor für einen etwas ad-hoceren Ansatz ist, dass Ihre Komponententests niemals eine öffentliche API sein werden, sodass Sie sich keine Gedanken darüber machen müssen, welche Schnittstellen / etc. du machst aus

vaughandroid
quelle
22

Ja, das ist wichtig. Es gibt mehrere Gründe, warum Komponententests nach einem vergleichbaren Standard wie andere Codes durchgeführt werden sollten:

  • Jeder Komponententest dient auch als Dokumentation für den Probanden. Wenn die Tests umfassend sind und so viele Randfälle und Fehlerbedingungen wie möglich abdecken, können sie häufig die Kommentardokumentation einer Klasse oder Funktion ersetzen. Sie können auch als Ausgangspunkt für Personen dienen, die neu in der Codebasis sind.

  • Unit-Tests können auch fehlerhaft sein. Und Fehler sind sichtbarer, wenn der Code gut geschrieben ist.

  • Wenn Sie später aus irgendeinem Grund ein Modul aufteilen müssen, müssen Sie wahrscheinlich auch dessen Komponententests aufteilen. Dies ist einfacher, wenn die Tests so geschrieben sind, dass sie leicht erkennbare Abhängigkeiten aufweisen.

Das heißt, es gibt immer die Frage der Praktikabilität. Abhängig von der Sprache und Art Ihres Codes kann es schwierig sein, "saubere" Komponententests zu schreiben, ohne viel mehr Zeit für die Tests aufzuwenden als für den Code, den sie testen sollen. In diesem Fall greife ich normalerweise auf das Testen des einfachen, schnellen Materials und der wichtigsten Funktionen zurück, ohne mich zu sehr um die vollständige Abdeckung zu sorgen. Immer wenn ein Fehler zu einem späteren Zeitpunkt auftaucht, schreibe ich einen Test dafür und überprüfe, ob ich den neuen Test und die vorhandenen Tests überarbeiten kann, um sie besser zu machen.

Benjamin Kloster
quelle
12

Wenn Sie einen unittest nicht lesen können und beim nächsten Fehlschlagen herausfinden, was er testet, müssen Sie die doppelte Debugging-Zeit aufwenden (einmal, um herauszufinden, worum es beim Test geht, und einmal, um den zu testenden Code zu reparieren).

Ehrlich gesagt, sollten Unittests ein erwartetes Ergebnis haben. Verfahren durchführen; Holen Sie sich das tatsächliche Ergebnis; Test erwartet gegen tatsächliche Art der Struktur, die einfach zu schreiben und zu verstehen ist

Ratschenfreak
quelle
1

Der Testcode sollte genauso viel Liebe erhalten wie Ihr Produktionscode. Zur besseren Lesbarkeit vielleicht noch mehr. Wenn jemand anderes als Sie (einschließlich Sie zwei Wochen nach dem Verlassen des Codes) verstehen soll, was los ist, dann sollten Sie Ihren Code schön knackig machen.

Das heisst:

  • Extrahieren Sie die Erstellung von Testdaten in Builder-Klassen.
  • Extrahieren Sie multible Zusicherungen in separate Zusicherungsmethoden.
  • Seien Sie sehr genau in Ihrer Benennung. Assert.That(x4, Is.EqualTo(y16*2*SOME_VALUE), ASS_ERR_TXT_56)macht für die meisten Leser wenig Sinn.

Im Extremfall können Tests so geschrieben werden, dass sie fast so einfach zu lesen UND zu verstehen sind wie Prosa. Der Extremtester würde wahrscheinlich sagen, dass ein Unit-Test mit mehr als 10 Zeilen eine schlechte ist.

Morten
quelle
1

Der wichtigste praktische Grund ist, dass Sie jedes Mal, wenn Sie den Code ändern, die Komponententests ändern. Und wenn Sie TDD machen, ändern Sie zuerst sogar die Unit-Tests.

Führen Sie in Ihren Tests eine der folgenden Aktionen aus:

  • Doppelter Code
  • Vermindern Sie die Lesbarkeit
  • Enge Kupplung
  • Zeitliche Kopplung
  • Hohe zyklomatische Komplexität (viele Abhängigkeiten)

Und Sie müssen eine ganze Menge arbeiten, wenn eine Änderung erforderlich ist.

Behandeln Sie Ihre Tests so, wie Sie es vorgeschlagen haben, und Sie werden es am Ende bereuen. Sie werden wahrscheinlich sogar die falsche Schlussfolgerung ziehen, dass "TDD nicht funktioniert".

Yam Marcovic
quelle
0

Es hängt davon ab, ob diese Komponententests "vorübergehend" sind oder nicht. Ob

  1. Test wird häufig verwendet;

  2. Entwickler müssen mit Komponententests arbeiten, die von anderen Entwicklern geschrieben wurden.

  3. Die meisten Tests werden durch Unit-Tests durchgeführt

dann sollten die tests richtig geschrieben sein. Falls der Test selbst einen Fehler enthält, ist es schwierig, den Fehler zu finden und zu beheben, insbesondere wenn seit dem Schreiben des Tests einige Zeit vergangen ist.

Auf der anderen Seite, wenn diese Tests nur von den Entwicklern selbst verwendet werden, ist es meiner Meinung nach in Ordnung. Es ist jedoch vorzuziehen, lesbaren Code zu schreiben. Wie der Ratschenfreak sagte, werden Sie mehr Zeit damit verbringen, Ihre Tests zu reparieren, als Sie damit verbringen würden, sie richtig zu schreiben.

superM
quelle
(1) Unit - Tests nie vorübergehender Natur sind (2) , auch wenn sie für sich selbst sind, in einem Monat (oder mehr), werden Sie nicht alle Details erinnern, deshalb ist es wichtig , es richtig zu machen - auch für sich selbst
BЈовић