Java Unit Tests, Verzeichnislayout [geschlossen]

76

Gibt es beim Erstellen einer Reihe von Komponententests für Java-Code eine Konvention, wo Testcode in Bezug auf den Quellcode platziert werden soll?

Wenn ich beispielsweise ein Verzeichnis habe /java, das eine Reihe von .javaQuelldateien enthält , ist es besser, die Testfälle in sich /javaselbst zu platzieren oder so etwas zu verwenden /java/test.

Wenn letzteres bevorzugt wird, wie testen Sie die Interna des Codes, wenn die private / protectedMitglieder einer Klasse außerhalb des Pakets nicht verfügbar sind?

Mike
quelle

Antworten:

73

Sie können die Tests in dasselbe Paket wie die ursprünglichen Klassen einfügen, auch wenn sich der Quellcode in einem eigenen Verzeichnisstamm befindet:

PROJECT_ROOT
    +--- src/
    +----test/

Sie können eine Klasse com.foo.MyClassunter srcund ihren Test com.foo.MyClassTestunter deklarieren test.

Für den Zugriff auf private Mitglieder können Sie Reflection verwenden , um die Methoden aufzurufen (ihre Zugänglichkeit über zu ändern Class.getDeclaredMethod.setAccessible), oder Sie können so etwas wie testng / junit5 verwenden, um einige annotationsgesteuerte Tests für den Quellcode selbst durchzuführen (ich persönlich denke, dies ist eine schlechte Idee).

Schauenjava.net Sie sich einige Projekte an, um zu sehen, wie sie die Dinge organisiert haben, zum Beispiel Swinglabs (das SVN-Repository ist leider ziemlich langsam).

oxbow_lakes
quelle
117

Ich empfehle, die Standardverzeichnisstruktur der Apache Software Foundation zu befolgen , die Folgendes ergibt:

module/
  src/
    main/
      java/
    test/
      java/

Dadurch werden Tests von der Quelle getrennt, jedoch auf derselben Ebene in der Verzeichnisstruktur. Wenn Sie durchlesen, wie Apache ihre Struktur definiert, werden Sie feststellen, dass dies auch dazu beiträgt, andere Probleme wie Ressourcen, Konfigurationsdateien, andere Sprachen usw. aufzuteilen.

Diese Struktur ermöglicht es Unit-Tests auch, Paket- und geschützte Level-Methoden der zu testenden Einheiten zu testen, vorausgesetzt, Sie platzieren Ihre Testfälle in demselben Paket wie das, was sie testen. In Bezug auf das Testen privater Methoden würde ich mich nicht darum kümmern. Etwas anderes, entweder öffentlich, paketiert oder geschützt, ruft sie auf, und Sie sollten in der Lage sein, eine vollständige Testabdeckung zu erhalten, in der diese Dinge getestet werden.

Der obige Link führt übrigens zu Maven, dem Standard-Build-Tool von Apache. Jedes Java-Projekt, das sie haben, entspricht diesem Standard sowie jedes Projekt, auf das ich gestoßen bin und das mit Maven erstellt wurde.

Einzelner Schuss
quelle
6
+1 Auch wenn Sie keinen Maven verwenden, ist es eine gute Idee, diesem Layout zu folgen (eine Art De-facto-Standard, der auf Best Practices der Branche basiert).
Pascal Thivent
7
Der einzige Grund, warum Maven hier erwähnt wird, ist, dass seine Website ein Ort ist, an dem das Apache-Standardverzeichnislayout dokumentiert ist. Ihre Meinung oder Abneigung ist irrelevant, wenn es darum geht, ob die betreffende Verzeichnisstruktur gut ist. Vielleicht können Sie eine Antwort kommentieren, die Ihrer Meinung entspricht, um anzugeben, warum diese Verzeichnisstruktur überlegen ist.
SingleShot
1
Wenn Sie in reinem Java codieren, ist das javaVerzeichnis eine unnötige Ergänzung
oxbow_lakes
6
Nun, es sollte erwähnt werden, dass normalerweise sowohl der mainals auch der testOrdner einen resourcesQuellordner haben, der in denselben Ausgabeordner kompiliert wird, den der javaOrdner erstellt, was eine einfache Trennung von Java-Code und Ressourcendateien auf der Quellenebene ermöglicht. Ich mag diese Struktur auch, weil sie die oberste Ebene frei von mehreren Quellordnern hält ... es ist eine sehr logische Organisation. Und ja, das hat nichts damit zu tun, ob man Maven mag oder nicht.
ColinD
3
Ich habe diesen Kommentar vor acht Jahren abgegeben. Seitdem habe ich Maven verstanden und geliebt. Ich werde jetzt nicht ohne arbeiten. Menschen können sich ändern.
Duffymo
8

Meistens wird so vorgegangen:

<SOME_DIR>/project/src/com/foo/Application.java
<SOME_DIR>/project/test/com/foo/ApplicationTest.java

Sie halten sie also getrennt und können das Paket / die geschützte Funktionalität weiterhin testen, da sich der Test im selben Paket befindet.

Sie können private Inhalte nur testen, wenn sie innerhalb der Klasse selbst deklariert sind.

Bei Lieferung packen Sie nur die .classvon src generierten, nicht die Tests

OscarRyz
quelle
1
Test sollte sich im Ordner src befinden. maven.apache.org/guides/introduction/…
Philip Rego
5

Tatsächlich ist es sehr sinnvoll, Ihre Produktions- und Testprojekte in zwei separate Einheiten aufzuteilen, aber in beiden Projekten dieselbe Paketstruktur zu haben.

Wenn ich also ein Projekt 'mein-Projekt' habe, erstelle ich auch 'mein-Projekt-Test', also habe ich die folgende Verzeichnisstruktur:

my-project
  +--- src/com/foo
my-project-test
  +---test/com/foo

Dieser Ansatz stellt sicher, dass Testcode-Abhängigkeiten den Produktionscode nicht verschmutzen.

Meiner persönlichen Meinung nach sollten sowohl private als auch geschützte Paketmethoden sowie öffentliche Methoden getestet werden. Daher möchte ich meine Testklassen im selben Paket wie die Produktionsklassen.

Alexander Pogrebnyak
quelle
2

So haben wir es eingerichtet und es gefällt uns.

build/
src/
test/build/
test/src/

Der gesamte Testcode wird in ein eigenes Build-Verzeichnis kompiliert. Dies liegt daran, dass die Produktion nicht versehentlich Testklassen enthalten soll.

Christian
quelle
1

Beim Erstellen eines Java-Bibliotheksmoduls in Android Studio wird eine Standardklasse erstellt unter:

[module]
   + src/main/java/[com/foo/bar]

Wenn Sie in eine [module].imlDatei schauen , finden Sie diesen Pfad sowie den Pfad für Tests, den Sie verwenden können. Das Folgende ist eine Zusammenfassung:

<module>
  <component>
    <content>
      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
    </content>
  </component>
</module>

Sie können insbesondere ein Verzeichnis für Tests erstellen, das die folgende Struktur aufweist:

[module]
   + src/main/java/[com/foo/bar]
   + src/test/java/[com/foo/bar]

Die obige Struktur wird von Android Studio erkannt und Ihre darunter liegenden Dateien werden in das Modul aufgenommen.

Ich gehe davon aus, dass diese Struktur ein empfohlenes Layout für Code und Tests ist.

Ryszard Dżegan
quelle