Wie kann ich herausfinden, ob Code innerhalb eines JUnit-Tests ausgeführt wird oder nicht?

Lesezeit: 8 Minuten

In meinem Code muss ich bestimmte Korrekturen nur vornehmen, wenn er in einem JUnit-Test ausgeführt wird. Wie kann ich herausfinden, ob Code innerhalb eines JUnit-Tests ausgeführt wird oder nicht? Gibt es so etwas wie JUnit.isRunning() == true ?

  • Sie verletzen wirklich die Idee von TDD, wenn Ihr Code etwas anderes für den Test macht. Warum müssen Sie es nur im Test ändern?

    – StrgShiftBryan

    26. Februar 2010 um 13:43 Uhr

  • Das ist eine schreckliche Idee

    – KitsuneYMG

    26. Februar 2010 um 13:49 Uhr


  • FWIW, ich finde es oft sinnvoll, das zu tun beim Entwickeln. Setzen Sie eine Prüfung auf jUnit in die äußerste Methode einer API, die am Ende eine Laufzeitausnahme auslöst, wenn sie im Container ausgeführt wird. Auf diese Weise können Sie Komponententests ausführen und ein gültiges Ergebnis erhalten und auch den gesamten Stack einfach über die Benutzeroberfläche testen, aber Ihre Transaktion wird aufgrund der RTE verworfen.

    – Sophistifunk

    25. Februar 2013 um 23:28 Uhr

  • Ich denke, ich habe einen ziemlich gültigen Anwendungsfall dafür: Ich möchte eine E-Mail in der Produktion senden, wenn etwas ernsthaft schief geht, und ich möchte diese E-Mail nicht, wenn sie sich in einem Testfall befindet (der Entwickler, im Gegensatz zur Produktion Support-Mitarbeiter, wird die fehlgeschlagenen Ergebnisse selbst sehen). Wir haben über hundert JUnit-Tests und ich möchte nicht jeden ändern, um so etwas wie EmailService.dontSendEmailsToProductionTeam() aufzurufen.

    – Ryan Shillington

    8. Oktober 2013 um 19:19 Uhr

  • Ich möchte gerne wissen, ob Code innerhalb eines Komponententests ausgeführt wird, damit ich ihm beispielsweise sagen kann, dass er einen anderen S3-Bucket verwenden soll. Auf diese Weise kann ich immer noch testen, ob alles verkabelt ist, ohne S3 komplett verspotten zu müssen.

    – Aaron Silbermann

    8. Juli 2014 um 22:34 Uhr

Benutzer-Avatar
Janning

Es kann eine gute Idee sein, wenn Sie programmgesteuert entscheiden möchten, welches “Profil” ausgeführt werden soll. Denken Sie bei der Konfiguration an Federprofile. Innerhalb eines Integrationstests möchten Sie vielleicht gegen eine andere Datenbank testen.

Hier ist der getestete Code, der funktioniert

public static boolean isJUnitTest() {  
  for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
    if (element.getClassName().startsWith("org.junit.")) {
      return true;
    }           
  }
  return false;
}

  • Für JUnit-Tests müssen wir die Datenbankumgebung anders konfigurieren.

    – Audrius Meškauskas

    2. April 2013 um 7:32 Uhr

  • Diese Lösung erfordert auch nicht, dass junit im Klassenpfad im Produktionscode enthalten ist! Perfekt!

    – Italo Borsatto

    26. Mai 2018 um 15:49 Uhr

  • Ich habe einen Dienst geschrieben, der für immer läuft – ich möchte, dass er nach einer Iteration beendet wird, wenn er auf Einheiten getestet wird. Das ist großartig, danke.

    – David

    23. April 2019 um 9:14 Uhr

  • for (StackTraceElement-Element: aktuellerThread().getStackTrace()) {

    – Mike

    11. Juli 2019 um 10:24 Uhr

  • Sie sollten das Ergebnis auch zwischenspeichern, da sich der Wert für eine bestimmte Ausführung nie ändert.

    – Samuel Neff

    21. Dezember 2021 um 3:38 Uhr

Zunächst einmal ist dies wahrscheinlich keine gute Idee. Sie sollten den tatsächlichen Produktionscode testen, nicht etwas anderen Code.

Wenn Sie das wirklich wollen, könnten Sie sich den Stacktrace ansehen, aber da Sie Ihr Programm sowieso dafür ändern, können Sie genauso gut ein neues statisches boolesches Feld einführen isUnitTesting in Ihrem Code, und lassen Sie JUnit dies auf true setzen. Halte es einfach.

  • Ja, Sie könnten beispielsweise ein Singleton-Objekt in Ihrer Klasse haben, das das isUnitTesting-Feld enthält, und es in einer [email protected] auf true setzen.

    – Jim Ferrans

    26. Februar 2010 um 13:59 Uhr

  • Wenn ich darüber nachdenke, ist dies ein bisschen wie eine Abhängigkeitsinjektion. Er sollte Scheinobjekte für die Abhängigkeiten einfügen, die zu schwer zu testen sind, aber ich nehme an, dass es immer noch besser ist, einen booleschen Wert explizit auf wahr zu setzen, als zu versuchen, die Klasse es selbst herausfinden zu lassen.

    – Thilo

    26. Februar 2010 um 14:05 Uhr

  • Leute, ihr habt mich überzeugt und ermutigt, diese Frage neu zu formulieren. stackoverflow.com/questions/2351293/…

    – Dr. Max Völkel

    28. Februar 2010 um 14:19 Uhr

  • “Sie sollten den tatsächlichen Produktionscode komponententesten”. Niemand tut dies. Unit-Tests verwenden fast immer eine Form von Mocking, die typischerweise durch Polymorphismus (dh Schnittstellen) implementiert wird. Die Verwendung eines Flags ist nur eine andere Möglichkeit, dasselbe zu tun. Der Unterschied ist stilistisch und relativ unbedeutend.

    – Elliott-Strand

    25. September 2019 um 12:27 Uhr


Benutzer-Avatar
Alain Désilets

Viele Leute in diesem Thread sagen, dass es keine gute Idee ist, wenn Code unter JUnit etwas anders läuft. Ich stimme im Allgemeinen zu, aber ich denke, es gibt einige Ausnahmen.

Zum Beispiel schreibe ich gerade INTEGRATION-Tests (im Gegensatz zu Unit-Tests) für eine App, die eine Verbindung zu einer Datenbank herstellt.

Diese Abnahmetests müssen oft die DB mit spezifischen Testdaten komplett neu initialisieren.

Natürlich möchte ich NIEMALS, dass dies NIEMALS in einer tatsächlichen Produktions-DB durchgeführt wird, da dies wertvolle Produktionsdaten vollständig löschen könnte.

Der einfachste Weg, um sicherzustellen, dass dies niemals passiert, besteht darin, es dem Code unmöglich zu machen, eine Verbindung zu einer Produktions-DB herzustellen, wenn er unter JUnit ausgeführt wird. Dies kann wiederum erfolgen, wenn beispielsweise die Factory, die eine Verbindung generiert, erkennen kann, dass sie unter JUnit läuft, und in diesem Fall eine Nullverbindung zurückgibt, es sei denn, die Datenbank, zu der wir eine Verbindung herstellen möchten, hat einen bekannten Namen eine Testdatenbank sein (z. B. “testdatabase”).

  • Dies kann gelöst werden, indem Sie dafür sorgen, dass Ihr Code die Produktionsdatenbank nicht kennt. Es wird die Konfiguration verwenden, die sich in Umgebungsvariablen oder an einem bestimmten Ort befindet. Die Produktionskonfiguration könnte eine unbekannte Konfiguration sein (dh existiert nur in Bereitstellungen, nicht in der Versionskontrolle). Dies ist nicht nur sicherer, sondern löst auch das Testproblem und es ist keine Änderung des Produktionscodes erforderlich.

    – TWiStErRob

    13. Januar 2018 um 15:37 Uhr


Das hat bei mir funktioniert:

private Boolean isRunningTest = null;

private boolean isRunningTest() {
    if (isRunningTest == null) {
        isRunningTest = true;
        try {
            Class.forName("org.junit.Test");
        } catch (ClassNotFoundException e) {
            isRunningTest = false;
        }
    }
    return isRunningTest;
}

Es kann in Maven-Tests sowie in der Eclipse-IDE verwendet werden, solange junit als Abhängigkeit mit dem Bereich “test” enthalten ist, z.

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

Wenn Sie die Dinge anders machen, weil Sie einen Komponententest durchführen, verfehlen Sie den Zweck eines Komponententests. Ein Komponententest soll genau wie die Produktion funktionieren (mit Ausnahme des Auf- und Abbaus aller erforderlichen Daten und solcher, die Sie benötigen … aber das ist im JUnit-Test selbst enthalten und nicht in Ihrem Code).

Wenn Sie jedoch wirklich einen guten Grund dafür haben, würde ich mir den Stapel ansehen und sehen, ob JUnit dort ist.

  • Ich weiß, das klingt ein bisschen gegen TDD, aber das Testen von Code für GoogleAppengine mit Jersey/Jetty führt mehr als einen Thread auf meinem lokalen Computer ein, was wiederum dazu führt, dass die neuen Threads nicht die richtige Mock-Testumgebung von Google initialisiert haben, also brauche ich um viele Punkte meines potenziellen zweiten Threads zu überprüfen, ob meine AppEngine-Mockup-Umgebung bereits ordnungsgemäß initialisiert ist, was ich nicht tun möchte, wenn ich mich auf einem Produktionsserver befinde. Es ist eindeutig ein bisschen chaotisch und es wäre besser, wenn ich die AppEngine-Umgebung auf meinem lokalen Computer genauer nachahmen könnte (dh nur einen Thread habe).

    – Dr. Max Völkel

    26. Februar 2010 um 14:17 Uhr

  • Ich denke, das sollte Ihre eigentliche Frage sein. Wie bekomme ich meine Komponententests dazu, sich genauso zu verhalten wie die bereitgestellte Umgebung? Dies könnte Ihnen helfen, Ihre Probleme tatsächlich zu lösen, ohne Code einzuführen, um tatsächlich zu überprüfen, ob Sie einen Komponententest ausführen oder nicht.

    – Robin

    26. Februar 2010 um 14:35 Uhr

  • Warum nicht mit dem GAE-Entwicklungsserver auf GAE testen? Es kommt der Realität ziemlich nahe, und ich glaube, sie haben jetzt sogar JUnit-Unterstützung.

    – Thilo

    26. Februar 2010 um 16:13 Uhr

  • für GAE: if (SystemProperty.environment.value() == null) { // im Unit-Test }

    – Computertoaster

    21. August 2019 um 9:15 Uhr

Benutzer-Avatar
Derrops

Wie wäre es mit der Überprüfung, ob sich das Junit-Jar im Klassenpfad befindet?

  • Ich weiß, das klingt ein bisschen gegen TDD, aber das Testen von Code für GoogleAppengine mit Jersey/Jetty führt mehr als einen Thread auf meinem lokalen Computer ein, was wiederum dazu führt, dass die neuen Threads nicht die richtige Mock-Testumgebung von Google initialisiert haben, also brauche ich um viele Punkte meines potenziellen zweiten Threads zu überprüfen, ob meine AppEngine-Mockup-Umgebung bereits ordnungsgemäß initialisiert ist, was ich nicht tun möchte, wenn ich mich auf einem Produktionsserver befinde. Es ist eindeutig ein bisschen chaotisch und es wäre besser, wenn ich die AppEngine-Umgebung auf meinem lokalen Computer genauer nachahmen könnte (dh nur einen Thread habe).

    – Dr. Max Völkel

    26. Februar 2010 um 14:17 Uhr

  • Ich denke, das sollte Ihre eigentliche Frage sein. Wie bekomme ich meine Komponententests dazu, sich genauso zu verhalten wie die bereitgestellte Umgebung? Dies könnte Ihnen helfen, Ihre Probleme tatsächlich zu lösen, ohne Code einzuführen, um tatsächlich zu überprüfen, ob Sie einen Komponententest ausführen oder nicht.

    – Robin

    26. Februar 2010 um 14:35 Uhr

  • Warum nicht mit dem GAE-Entwicklungsserver auf GAE testen? Es kommt der Realität ziemlich nahe, und ich glaube, sie haben jetzt sogar JUnit-Unterstützung.

    – Thilo

    26. Februar 2010 um 16:13 Uhr

  • für GAE: if (SystemProperty.environment.value() == null) { // im Unit-Test }

    – Computertoaster

    21. August 2019 um 9:15 Uhr

Benutzer-Avatar
Milanka

Bei Verwendung von Spring kann man eine Bean definieren, die diesen Wert enthält.

Im Anwendungskontext:

@Bean
public boolean isRunningTests() {
    return false;
}

Im Kontext der Testanwendung:

@Bean
public boolean isRunningTests() {
    return true;
}

Fügen Sie den Wert in eine Spring-Komponente ein:

@Resource
private boolean isRunningTests;

private void someMethod() {
    if (isRunningTests()) {
        ....

1282910cookie-checkWie kann ich herausfinden, ob Code innerhalb eines JUnit-Tests ausgeführt wird oder nicht?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy