Ich wurde beauftragt, die Codeabdeckung eines vorhandenen Java-Projekts zu erhöhen.
Ich habe festgestellt, dass das Code Coverage Tool ( EclEmma ) einige Methoden hervorgehoben hat, die niemals von irgendwoher aufgerufen werden.
Meine erste Reaktion ist nicht , Unit-Tests für diese Methoden zu schreiben, sondern sie meinem Vorgesetzten / Team vorzustellen und zu fragen, warum diese Funktionen überhaupt vorhanden sind.
Was wäre der beste Ansatz? Schreibe Unit-Tests für sie oder frage dich, warum sie da sind?
java
unit-testing
test-coverage
Lucas T
quelle
quelle
Antworten:
Begründung:
seltenen,einzigartigen Fall, dass jemand später nach diesem Code sucht, dieser abgerufen werden kann.Einschränkung durch Kommentare: In der ursprünglichen Antwort wurde davon ausgegangen, dass Sie gründlich überprüft haben, dass der Code zweifelsohne tot ist. IDEs sind fehlbar, und es gibt verschiedene Möglichkeiten, wie Code, der tot aussieht, tatsächlich aufgerufen werden kann. Wenden Sie sich an einen Experten, es sei denn, Sie sind sich absolut sicher.
quelle
Alle anderen Antworten basieren auf der Annahme, dass die fraglichen Methoden wirklich nicht verwendet werden. In der Frage wurde jedoch nicht angegeben, ob dieses Projekt eigenständig oder eine Bibliothek ist.
Wenn es sich bei dem betreffenden Projekt um eine Bibliothek handelt, können die anscheinend nicht verwendeten Methoden außerhalb des Projekts verwendet werden, und das Entfernen dieser Methoden würde die anderen Projekte beschädigen. Wenn die Bibliothek selbst an Kunden verkauft oder öffentlich zugänglich gemacht wird, kann es sogar unmöglich sein, die Verwendung dieser Methoden zu verfolgen.
In diesem Fall gibt es vier Möglichkeiten:
quelle
filter_name_exists
,ReloadSettings
oderaddToSchema
(zufällig aus drei beliebigen Open - Source - Projekten gepflückt) sollten ein paar Hinweise geben , was das Verfahren es tun sollte. Ein Javadoc-Kommentar kann sogar noch nützlicher sein. Ich weiß, dass dies keine richtige Spezifikation ist, aber es könnte ausreichen, einige Tests zu erstellen, die zumindest Regressionen verhindern könnten.Überprüfen Sie zunächst, ob Ihr Code-Coverage-Tool korrekt ist.
Ich hatte Situationen, in denen sie nicht auf Methoden aufmerksam wurden, die über Verweise auf die Schnittstelle aufgerufen wurden, oder wenn die Klasse dynamisch irgendwo geladen wurde.
quelle
Da Java statisch kompiliert ist, sollte es ziemlich sicher sein, die Methoden zu entfernen. Toten Code zu entfernen ist immer gut. Es besteht eine gewisse Wahrscheinlichkeit, dass es ein verrücktes Reflection-System gibt, das sie zur Laufzeit ausführt. Wenden Sie sich also zuerst an andere Entwickler, und entfernen Sie sie ansonsten.
quelle
invokedynamic
Anweisung, also weißt du ...Das Löschen von Code ist eine gute Sache.
Wenn Sie den Code nicht löschen können, können Sie ihn auf jeden Fall als @Deprecated markieren , um zu dokumentieren, auf welche Hauptversion Sie abzielen, um die Methode zu entfernen. Dann können Sie es "später" löschen. In der Zwischenzeit wird klar sein, dass kein neuer Code hinzugefügt werden sollte, der davon abhängt.
Ich würde nicht empfehlen, in veraltete Methoden zu investieren - also keine neuen Unit-Tests, um nur die Abdeckungsziele zu erreichen.
Der Unterschied zwischen den beiden besteht hauptsächlich darin, ob die Methoden Teil der veröffentlichten Schnittstelle sind oder nicht . Das willkürliche Löschen von Teilen der veröffentlichten Benutzeroberfläche kann für Benutzer, die von der Benutzeroberfläche abhängig waren, eine unangenehme Überraschung sein.
Ich kann nicht mit EclEmma sprechen, aber nach meinen Erfahrungen ist eines der Dinge, auf die Sie achten müssen, das Nachdenken. Wenn Sie zum Beispiel Textkonfigurationsdateien verwenden, um auszuwählen, auf welche Klassen / Methoden zugegriffen werden soll, ist die verwendete / nicht verwendete Unterscheidung möglicherweise nicht offensichtlich (ich bin dadurch ein paar Mal verbrannt worden).
Wenn es sich bei Ihrem Projekt um ein Blatt im Abhängigkeitsdiagramm handelt, wird der Fall für die Nichtbeachtung abgeschwächt. Wenn es sich bei Ihrem Projekt um eine Bibliothek handelt, ist die Begründung für die Nichtbeachtung strenger.
Wenn Ihr Unternehmen ein Mono-Repo verwendet , ist das Risiko beim Löschen geringer als im Multi-Repo-Fall.
Wenn die Methoden bereits in der Quellcodeverwaltung verfügbar sind, ist das Wiederherstellen nach dem Löschen, wie in l0b0 erwähnt , eine einfache Aufgabe . Wenn Sie dies wirklich befürchten, sollten Sie sich überlegen, wie Sie Ihre Commits so organisieren, dass Sie die gelöschten Änderungen bei Bedarf wiederherstellen können.
Wenn die Unsicherheit hoch genug ist, können Sie den Code auskommentieren, anstatt ihn zu löschen. Es ist zusätzliche Arbeit im Happy-Pfad (wo der gelöschte Code nie wiederhergestellt wird), aber es erleichtert die Wiederherstellung. Ich vermute, Sie sollten ein direktes Löschen bevorzugen, bis Sie ein paarmal davon verbrannt wurden, was Ihnen einige Einsichten darüber gibt, wie Sie "Unsicherheit" in diesem Kontext bewerten können.
Zeit, die in das Erfassen der Überlieferungen investiert wird, ist nicht unbedingt verschwendet. Es ist bekannt, dass ich ein Entfernen in zwei Schritten durchführe - erstens indem ich einen Kommentar hinzufüge und festlege, in dem erklärt wird, was wir über den Code gelernt haben, und dann den Code (und den Kommentar) später lösche.
Sie können auch etwas verwenden, das mit Architekturentscheidungsunterlagen vergleichbar ist , um die Überlieferungen mit dem Quellcode zu erfassen.
quelle
Ein Code-Coverage-Tool ist nicht allwissend, allsehend. Nur weil Ihr Tool angibt, dass die Methode nicht aufgerufen wurde, heißt das nicht, dass sie nicht aufgerufen wurde. Es findet eine Reflektion statt, und je nach Sprache kann die Methode auch auf andere Weise aufgerufen werden. In C oder C ++ gibt es möglicherweise Makros, die Funktions- oder Methodennamen konstruieren, und das Tool kann den Aufruf möglicherweise nicht sehen. Der erste Schritt wäre also: Führen Sie eine Textsuche nach dem Methodennamen und verwandten Namen durch. Fragen Sie erfahrene Kollegen. Sie können feststellen, dass es tatsächlich verwendet wird.
Wenn Sie sich nicht sicher sind, setzen Sie am Anfang jeder "nicht verwendeten" Methode ein assert (). Vielleicht wird es gerufen. Oder eine Protokollierungsanweisung.
Vielleicht ist der Code tatsächlich wertvoll. Möglicherweise handelt es sich um einen neuen Code, an dem ein Kollege seit zwei Wochen arbeitet und den er oder sie morgen einschalten würde. Es wird heute nicht angerufen, weil der Anruf morgen hinzugefügt wird.
Vielleicht ist der Code tatsächlich wertvoll Teil 2: Der Code führt möglicherweise einige sehr teure Laufzeitprüfungen durch, bei denen Fehler auftreten können. Der Code wird nur aktiviert, wenn tatsächlich etwas schief geht. Möglicherweise löschen Sie ein nützliches Debugging-Tool.
Interessanterweise ist der schlechteste Rat "Löschen. Festschreiben. Vergessen." ist am höchsten bewertet. (Codeüberprüfungen? Sie führen keine Codeüberprüfungen durch? Was in aller Welt programmieren Sie, wenn Sie keine Codeüberprüfungen durchführen?)
quelle
Abhängig von der Umgebung, in der die Software ausgeführt wird, können Sie sich anmelden, wenn die Methode jemals aufgerufen wird. Wenn es nicht innerhalb eines geeigneten Zeitraums aufgerufen wird, kann die Methode sicher entfernt werden.
Dies ist ein vorsichtigerer Ansatz als nur das Löschen der Methode und kann hilfreich sein, wenn Sie in einer Umgebung mit hoher Fehleranfälligkeit arbeiten.
Wir loggen uns in einen dedizierten
#unreachable-code
Slack-Channel mit einer eindeutigen Kennung für jeden zu entfernenden Kandidaten ein und es hat sich als ziemlich effektiv erwiesen.quelle