Frage

Ich habe vor kurzem angefangen mit code-coverage-tools (besonders Emma und EclEmma), und ich mag die Aussicht, dass es mich gibt-für die Vollständigkeit meiner unit-tests - und die Fähigkeit, zu sehen, welche Bereiche der code meiner unit-tests sind nicht zum schlagen überhaupt.Ich arbeite derzeit in einer Organisation, die nicht eine Menge von unit-Tests, und ich plan auf die wirklich drängt jeder sich auf unit-Tests und code-coverage-und TDD-und hoffentlich konvertieren der Organisation.

Aber ein Problem, ich bin mir nicht sicher, mit diesem Thema ist genau wie weit sollte ich nehmen meine code-coverage.Zum Beispiel, wenn ich eine Klasse wie diese:

//this class is meant as a pseudo-enum - I'm stuck on Java 1.4 for time being
public final class BillingUnit {

    public final static BillingUnit MONTH = new BillingUnit("month");
    public final static BillingUnit YEAR = new BillingUnit("year");

    private String value;

    private BillingUnit(String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

    public boolean equals(Object obj) {
        return value.equals(((BillingUnit) obj).getValue());

    }

    public int hashCode() {
        return value.hashCode();
    }
}

Ich schrieb einige einfache unit-tests, um sicherzustellen, dass equals() korrekt funktioniert, ist, dass getValue() gibt zurück, was ich erwartet habe, etc.Aber Dank der visuellen Natur von EclEmma, das hashcode() Methode zeigt sich als helle rot für "nicht getestet".

Lohnt es sich, einmal die Mühe, Sie zu testen hashCode(), in diesem Beispiel, wenn man bedenkt, wie einfach die Umsetzung ist?Ich habe das Gefühl, ich würde das hinzufügen einen Komponententest für diese Methode einfach zu stoßen, die code-coverage -%, und loszuwerden, die grell rote Markierung, dass EclEmma fügt diese Zeilen.

Vielleicht bin ich neurotisch und OCD-like, aber ich finde, dass Sie so etwas wie EclEmma, das macht es so einfach zu sehen, was ist noch ungetestet - die plugin-highlights, die source-code in rot und bedeckt code in grün - macht mich wirklich wollen zu schieben, um so viele Klassen, 100% grün als ich kann - auch wenn es nicht viel hinzuzufügen von Vorteil.

War es hilfreich?

Lösung

Ich verwende die code-coverage zu geben mir Hinweise auf Orte, wo ich eventuell eine unvollständige Reihe von tests.Zum Beispiel, kann ich einen test schreiben, um Funktionen gehen, dann entwickeln Sie den code erfüllt, die Funktionalität, aber dabei tatsächlich code schreiben, der nicht mehr als es soll-sagen, es könnte fangen eine Ausnahme, die in einem alternativen Fall, dass der test nicht ausüben.Wenn ich die coverage analyzer, kann ich sehen, dass ich vorgestellt habe code, der nicht über eine zugeordnete test.Es hilft mir zu wissen, wenn ich geschrieben habe nicht genug tests.

Auf der anderen Seite, coverage-Analyse führen kann, um Sie in falscher Sicherheit.Nachdem alle von Ihren code bedeckt, bedeutet nicht, dass Sie haben genug tests.Sie müssen darüber nachdenken, tests aus der Perspektive von was soll der code machen und tests schreiben, um sicherzustellen, dass er es tut.Vorzugsweise durch das schreiben des test-first.Nur weil Ihr code vollständig bedeckt ist, bedeutet nicht, dass der code das tut, was es tun soll.

In Ihrem Beispiel würde ich geschrieben haben, den test für hashCode definieren, was die Funktionalität der Methode, bevor ich schrieb den code.Daher würde ich es bedeckt.Das bedeutet nicht, dass ich immer 100% Deckkraft.Ich bin nicht übermäßig eifrig über das schreiben von tests für einfache Zugriffsfunktionen, zum Beispiel.Ich kann auch nicht testen Methoden der übergeordneten Klasse, wo ich Erben von einem Rahmen, da ich nicht das Bedürfnis verspüren, zu testen, anderer Leute code.

Andere Tipps

Ich denke, es lohnt sich, verwenden Sie eine Bibliothek, wo Sie können wählen, zu ignorieren, bestimmte Arten von Aussagen.Zum Beispiel, wenn Sie haben eine Menge:

if(logger.isDebugEnabled()) {
    logger.debug("something");
}

Es ist nützlich, wenn Sie schalten Sie die Abdeckung Berechnungen für die Arten von Linien.Es kann auch sein (wohl) gültig zu deaktivieren Abdeckung Berechnungen für triviale Getter und setter (diejenigen, die einfach festlegen oder zurückgeben eine member-variable mit keinem anderen Prüfungen oder Nebenwirkungen).Ich weiß allerdings denken, dass, wenn Sie überschrieben haben, equals und hashcode, diejenigen, die getestet werden sollen.Sie fügte nicht-triviale Funktionen, und es sollte geprüft werden.

Nur um klar zu sein, der Grund, warum ich denke, dass die oben genannten Situationen sollten von der Deckung ausgeschlossen ist, dass:

  • Nicht die Prüfung, dass die Funktion ist ok.Sie sollten sich nicht durch die gesamte suite von tests 5 mal, mit der logging-Bibliothek setzen zu jedem logging-level, nur um sicherzugehen, dass alle Ihre Aussagen getroffen werden.
  • Wenn Sie haben die oben genannten, würde es zu verzerren Abdeckung in die andere Richtung.Wenn 90% der Filialen sind if(log.isDebugEnabled()), und testen Sie Sie alle, aber keine andere Zweige, wird es so Aussehen, wie Sie 90% branch coverage (gut), wenn in Wirklichkeit haben Sie 0% nicht-triviale Zweig Abdeckung (schlecht!).

Es gibt einen Unterschied zwischen code-coverage und Test-coverage.Sie sollten versuchen, um sicherzustellen, dass Sie Ihren code ausreichend getestet, anstatt 100% code-Abdeckung.

Betrachten Sie den folgenden code:

public float reciprocal (float ex)
{
    return (1.0 / ex) ;
}

Wenn Sie lief, eine Prüfung, die bestanden in einem Wert von 1,0 ist, dann hätte man 100% code-coverage - (Verzweigung und Verlustrechnung) mit allen Durchläufen.Der code hat offensichtlich einen defekt.

Messung der test-coverage-ist schwieriger und man kommt zu einem besseren Entwickler und tester.

Mit Bezug auf hashCode genauer gesagt, ein truist würde sagen, Sie haben ein separates Komponententest für diese Methode.Ich persönlich würde sicherstellen, dass es ist enthalten in mindestens einem unit-integration-test und würde nicht testen jeden accessor/modifier direkt.Der return on investment ist oft zu gering, um den Aufwand zu rechtfertigen.Dies ist natürlich vorausgesetzt, dass Sie havea unit-Tests stellen sicher, dass Sie sind in die Erstellung der richtigen hash-code.

Erreicht 100% code-Abdeckung mit sinnvolle tests, die möglicherweise nicht den Aufstieg Wert, und, wie schon erwähnt, 100% Code-Abdeckung bedeutet nicht unbedingt, dass Sie alle möglichen Bedingungen in der Anwendung getestet wurden.

Wie für die Prüfung equals, hashCode und einige andere Vertrag Schnittstellen, wie Comparable und Serializable, Ich weiß sind diese tests.Es ist wichtig, dass die equals/hashCode Vertrag ist korrekt implementiert, ebenfalls mit equals/Comparable.

Finden JUnit-Addons, vor allem

Es ist vielleicht nicht allzu kompliziert, jetzt aber eine einfach zu überprüfen, um sicherzustellen, dass es funktioniert immer noch wie erwartet sehr nützlich sein kann, später auf, wenn die Methode bekommt geändert.

Da überprüft werden soll, wirklich einfach zu schreiben, warum nicht so?Es hilft den stats, und auch hilft Ihnen, eine überprüfung später nur, falls es bricht.

Auch für TDD, die Sie möchten, 100% Deckung, denn dann können Sie sicher sein (oder sehr nahe), dass man nicht etwas kaputt zu machen wenn Sie umgestalten.

A fellow programmer stecken, wie ich in alte Java1.4 ;)

Wie gesagt in meinem Vorherige Antwort, code bedeckt code ist nicht getestet.Und die Schlussfolgerung war:ab einem gewissen Punkt, ist der einzige Weg zur Verbesserung der code-Abdeckung ist...löschen code!

Nun, in Bezug hashCode, es ist interessant, Sie zu haben es abgedeckt in einer unit-test-design zu überprüfen, die erwartete sortiert Mechanismus eingehalten wird (und nicht für die Abdeckung einer Funktion)

Wie ich schon an anderer Stelle, low-code-coverage ist ein problem, aber hohe code-Abdeckung bedeutet nicht, dass Sie schreiben reinem gold.

Wenn Sie nicht besorgt über die code-Abdeckung, dann würde ich vorschlagen, dass Sie müssten tests für equals() und getValue() - je nachdem, wie und wo hashCode() verwendet wird (sorry, ich bin ein C# - Entwickler), dann Sie könnte möchten testen.

Der wichtigste Teil ist, dass die tests geben Ihnen das Vertrauen, dass Sie geschrieben haben die richtigen code und der code funktioniert wie erwartet.

In diesem speziellen Fall, würde ich sagen, dass seit Sie sind Tests, die equals-Methode können Sie auch testen, dass gleiche Objekte müssen gleichen hashcodes:fügen Sie einfach einen zusätzlichen test auf alle die Fälle, in denen gleich wird erwartet, dass der Wert true zurückgegeben.

Geben Sie die code-coverage -, und obendrein wird es Ihnen an zuversicht, dass hashCode tatsächlich erfüllt seinen Vertrag :-)

Es ist nur geringfügig lohnt sich, da Sie offensichtlich Vertrauen in die hashCode-Methode von Strings, und Sie erwarten Sie nicht, jemals ändern dieser Klasse.Aber wenn Sie misstrauisch sind genug für Ihre equals-Methode, um es zu testen, dann sollten Sie misstrauisch werden genug dabei, um zu testen, dass es und hashCode konsistent bleiben.Und Sie sollten immer misstrauisch sein, der Annahmen, dass Sie in Zukunft nicht zu verwirren wollen mit dem, was Sie getan haben, bevor.Zum Beispiel, wenn jemand vorbeikommt und beschließt, Sie zu "optimieren", indem ein Zeiger-Gleichheit zu überprüfen, können Sie auch einen kompletten Satz von tests für den von Ihnen angepassten code vor.Andernfalls werden Sie verschwenden Zeit auf die gleiche Sorge, die Sie haben - es ist OK, dass ich nicht die code-coverage?

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