Was ist der richtige Weg, um während Unit-Tests mit Maven in temporäre Dateien zu schreiben?
Lesezeit: 7 Minuten
Brett Ryan
Ich habe einen Komponententest geschrieben, der eine Datei in das Dateisystem schreibt, ohne dass ein Pfad in das Arbeitsverzeichnis geschrieben wird. Wenn es also aus dem Projektverzeichnis ausgeführt wird, schreibt es in das Projektstammverzeichnis, wenn es sich im übergeordneten Projektverzeichnis befindet, schreibt es in das übergeordnete Stammverzeichnis.
Was ist also der richtige Weg, um in das Zielverzeichnis zu schreiben? Möglicherweise ein Verzeichnis innerhalb des Zielverzeichnisses?
Wenn ich ganz einfach angeben target/ Mit der Datei wird in das Ziel des übergeordneten Projekts geschrieben, anstatt in das Ziel des Projekts.
AKTUALISIEREN: Ich möchte die Datei tatsächlich nach Abschluss des Tests. Die Datei ist für ein Extraktionsformat für Drittanbieter, das an die Drittanbieter gesendet werden muss. Der Test kann ein-/ausgeschaltet werden, damit ich ihn nur ausführen kann, wenn sich das Format der Datei zur erneuten Genehmigung ändert. Es ist kein großes Problem, wohin die Datei geht, aber ich hätte gerne etwas, das leicht zu finden ist.
Mama
Sie könnten versuchen, zu verwenden Temporärer Ordner JUnit @Rule wie beschrieben hier
Das Temporärer Ordner erstellt einen Ordner im Standardverzeichnis für temporäre Dateien, das durch die Systemeigenschaft java.io.tmpdir angegeben ist. Die Methode newFile erstellt eine neue Datei im temporären Verzeichnis und newFolder erstellt einen neuen Ordner.
Wenn die Testmethode beendet ist, löscht JUnit automatisch alle Dateien und Verzeichnisse in und einschließlich des TemporaryFolder. JUnit garantiert, dass die Ressourcen gelöscht werden, unabhängig davon, ob der Test bestanden wird oder fehlschlägt.
Sie können dieses Arbeitsverzeichnis in alles ändern, was Sie für Ihre Tests benötigen, z ${project.build.directory}/my_special_dir/.
Das Arbeitsverzeichnis im Surefire-Plugin wirkt sich nur auf Tests aus, die ausgeführt werden, und NUR auf Tests, die von Maven durchgeführt werden. Wenn Sie Ihre Tests innerhalb einer IDE ausführen, ist das Arbeitsverzeichnis etwas anderes.
Danke maba, das ist ein ähnliches Problem wie Bohemian, die Datei landet an einem obskuren Ort. Ich möchte die Datei tatsächlich nach Abschluss des Tests.
– Brett Ryan
13. September 2012 um 6:38 Uhr
@BrettRyan OK, aktualisiert mit der Änderung des Arbeitsverzeichnisses für das todsichere Plugin. Das sollte reichen.
– Mama
13. September 2012 um 6:50 Uhr
Fantastisch, danke maba, das ist perfekt und wird auf allen Maschinen, auf denen der Test ausgeführt wird, immer konsistent sein.
– Brett Ryan
13. September 2012 um 8:22 Uhr
Vielen Dank, dass Sie die ursprüngliche Antwort hinterlassen haben. Das habe ich gebraucht.
– Yellavon
17. April 2014 um 16:40 Uhr
JUNIT garantiert kein automatisches Löschen, Sie müssen es tun @Rule public TemporaryFolder folder = TemporaryFolder.builder().assureDeletion().build();
– Vimal-Krishna
11. Januar 2017 um 15:05 Uhr
Bohemien
Man muss das Rad nicht neu erfinden…
Das JDK bietet eine Möglichkeit, eine temporäre Datei zu erstellen und sie beim Beenden automatisch zu löschen:
Verwenden Sie die Datei und sie wird automatisch gelöscht, wenn Ihr Test beendet ist. Das ist alles dazu.
Verwenden Sie die überladene Methode, um das Verzeichnis anzugeben, das für temporäre Dateien verwendet werden soll:
File file = File.createTempFile( "prefix", "ext", new File("/some/dir/path"));
Danke Bohemian, ich möchte eigentlich, dass die Datei nach dem Beenden erhalten bleibt, damit ich sie an den Anbieter weiterleiten kann. Ich nehme an, das temporäre Verzeichnis des Systems ist in Ordnung, obwohl ich gehofft hatte, es im Zielverzeichnis zu haben.
– Brett Ryan
13. September 2012 um 6:32 Uhr
Ich habe das gerade versucht und es stellt sich heraus, dass sich die Datei an einem so obskuren Ort befindet, dass es nicht ratsam wäre, sie zu verwenden. Endete in /var/folders/xf/scvh7yr11m1glr4b663n1hcsnv5lf0/T/test2614442099335581603.xml
– Brett Ryan
13. September 2012 um 6:35 Uhr
@BrettRyan Kein Problem – Sie können das Verzeichnis angeben, das für temporäre Dateien verwendet wird – siehe bearbeitete Antwort
– Böhmisch ♦
13. September 2012 um 7:13 Uhr
Danke Bohemian, ich sehe einen Vorteil darin, das temporäre Verzeichnis festlegen zu können, obwohl ich die Möglichkeit mag, dies an einem zuverlässigen Ort unter dem Zielverzeichnis zu haben, anstatt einen bestimmten Ort auf dem Computer zu benötigen.
– Brett Ryan
13. September 2012 um 8:24 Uhr
CloudyMarble
Ich würde eine Routine schreiben, die bestimmt, wohin die Datei geschrieben werden soll, die ich danach vereinige, im Allgemeinen versuche ich (möglichst) den Zugriff auf persistente Daten in Unittests zu vermeiden, wie Datei-IO oder Datenbankzugriff, dies hat Performance-Gründe und andere auch .
Sehen Sie sich diese Antwort an: https://stackoverflow.com/a/8032504/395659
Danke OD, so etwas musste ich bis jetzt noch nie machen. Ich habe den Test geschrieben, um eine Datei zu schreiben, die im Produktionscode an andere Anbieter gesendet wird. Mein Test schreibt die Datei auf die Festplatte, damit ich sie an die Anbieter senden kann, um die Genehmigung zu erhalten. Nach der Genehmigung wird der Test nicht mehr benötigt, kann aber später nützlich sein, wenn sich etwas ändert und die Ausgabe “erneut genehmigt” werden muss.
– Brett Ryan
13. September 2012 um 6:19 Uhr
aber warum verwenden Sie zu diesem Zweck einen “Einheitentest”? Ich denke, sogar eine separate Klasse mit main () -Methode für diesen Zweck zu haben, ist noch angemessener, als den Unit-Test zu missbrauchen
– Adrian Schum
13. September 2012 um 6:42 Uhr
Sie möchten Ihre Tests sowohl von einer IDE als auch von Maven ausführen können, daher ist es am besten, Ihre Tests so zu schreiben, dass sie nicht davon ausgehen, dass sie in Maven ausgeführt werden.
Eine der besten Möglichkeiten, mit temporären Dateien umzugehen, ist die Verwendung von Junit-Regeln. Auf diese Weise können Sie sich darauf verlassen, dass die Regel für Sie aufräumt.
Um es vorweg zu sagen, ich bin strikt dagegen, solche Dinge in Unit-Tests zu tun. Ich habe das nicht wirklich ausprobiert, aber es sollte funktionieren:
Angenommen, Sie verwenden das todsichere Plugin aus dem zitierten Dokument, mit dem Sie auf das Basisverzeichnis des zu testenden Projekts zugreifen können System.getProperty("basedir"). Holen Sie es und erstellen Sie Dateien unter basedir/target.
Ein “angemessenerer” Weg (da wir möglicherweise das Ausgabeverzeichnis auf etwas anderes konfiguriert haben, können Sie die todsichere Plugin-Konfiguration in etwa so ändern:
Dann können Sie das tatsächliche Ausgabeverzeichnis erhalten System.getProperty("myOutDir") in deiner Prüfung.
AlexR
Temporäre Dateien sollten im temporären Verzeichnis erstellt werden. Rufen Sie es mit Anruf ab System.getProperty("java.io.tmpdir")
Temporäre Dateien sollten temporär sein, dh entfernt werden, wenn sie nicht benötigt werden. Um dies zu erreichen, vergessen Sie nicht, es zu löschen finally Block oder in Code, der nach dem Test ausgeführt wird, dh:
public class MyTestCase {
private File tmpFile = null;
@Before
public void setUp() {
tmpFile = ...;
}
@Test
public void setUp() {
// deal with tmpFile
}
@After
public void setUp() {
tmpFile.delete();
}
}
Verwenden File.createTempFile(String prefix, String suffix) wenn es möglich ist, dh Sie können dann eine Datei mit speziellem Namen verwenden, die von generiert wird createTempFile().
Verwenden file.deleteOnExit(). Dadurch wird ein Hook erstellt, der die Datei automatisch entfernt, wenn JVM beendet wird. Die Datei bleibt nur erhalten, wenn JVM damit beendet wurde kill -9also hatte es keine Chance, Shutdown-Code auszuführen.
dpelisek
Seit JUnit 5 können Sie verwenden @TempDir. Sie wird (einschließlich ihres Inhalts) nach dem/den Test(s) gelöscht.
entweder ein temporäres Verzeichnis für jeden Test: