Erste Schritte Unit und Integration-Tests im Java Modul System

sascha-sphw

Top Contributor
Hallo zusammen,

ich habe das Thema lange geschoben, wollte es jetzt aber doch mal anpacken und habe mir dazu mal eine Lib von mir vorgenommen. In dieser Lib habe ich Unit Test und Integration Tests mit TestFx.
Die Struktur ist wie in einem normalen Maven Projekt.
Rich (BB-Code):
src
  - main
    - java
    - resources
  - test
    - java
    - resources

Alle Tests liegen unter test. Wenn ich jetzt die module-info.java anlege, failen sofort alle Integration Tests.
Die module-info.java sieht wie folgt aus.
Java:
module sphw.jfx {
    requires javafx.graphics;
    requires static lombok;
    requires com.fasterxml.jackson.databind;
    requires com.fasterxml.jackson.dataformat.yaml;
    requires org.apache.logging.log4j;
    requires javax.inject;
    requires javafx.controls;
    requires java.desktop;
    requires com.google.guice;
    requires javafx.fxml;
    requires com.google.guice.extensions.assistedinject;

    exports de.sphw.commons.jfx.config;
    exports de.sphw.commons.jfx.controls;
    exports de.sphw.commons.jfx.dialogs;
    exports de.sphw.commons.jfx.exceptions;
    exports de.sphw.commons.jfx.fxml;
    exports de.sphw.commons.jfx.icons;
    exports de.sphw.commons.jfx.styles;
    exports de.sphw.commons.jfx.utils;
}
Die Fehlermeldungen sind wie folgt:
Code:
[ERROR] de.sphw.commons.jfx.dialogs.DialogsFxTest.centerToStageWithFixedSizeBiggerThanDialog(FxRobot)  Time elapsed: 0.008 s  <<< ERROR!
java.lang.reflect.InaccessibleObjectException: Unable to make private void de.sphw.commons.jfx.dialogs.DialogsFxTest.testDialogPosition(org.testfx.api.FxRobot) accessible: module sphw.jfx does not "opens de.sphw.commons.jfx.dialogs" to unnamed module @339bf286
Die Methode testDialogPosition ist eine private Methode, da diese nur von den Test Methoden aufgerufen werden muss, selbst wenn ich diese public mache, geht das gleiche weiter mit Lamda ausdrücken.

Ich habe zum testen mal opens de.sphw.commons.jfx.dialogs; in die module-info.java mit aufgenommen, aber das ist ein Rattenschwanz, danach geht es einfach weiter mit java modulen. Zumal ich das eigentlich auch nur für die Tests brauchen würde und das kommt mir nicht richtig vor.

Dann habe ich was gefunden, bei dem es heißt, einfach eine module-info.[java|test] in das test package zu legen. Wenn ich das mache, bekomme ich einen Fehler in meiner IDE. module-info.java' already exists in the module. Maven tut dennoch, bekomme dann aber einen testCompile error, den ich bei compile nicht bekomme.
Java:
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /F:/repos/sphw-jfx/src/main/java/de/sphw/commons/jfx/dialogs/Dialogs.java:[98,27] cannot find symbol
  symbol:   method builder()
  location: class de.sphw.commons.jfx.dialogs.AboutDialog
[INFO] 1 error
[INFO] -------------------------------------------------------------

Dabei handelt es sich um den Lombok builder, der bei mvn compile ganz normal erstellt wird. Vielleicht stelle ich mich auch gerade an wie der erste Mensch, aber bisher werde ich mit den Modulen noch nicht warm.

Was ich noch nicht versucht habe, die integrations tests wo anders hin zu schieben, aber wohin? Ich hatte die bisher immer im test Ordner. Kennt Maven den Ordner integration-test?

Wie macht ihr das denn?
 
OK, also irgendwie sieht zumindest dieser Fehler so aus, als ob maven-compiler-plugin, den annotationProcessorPath bei testCompile nicht berücksichtigt. Bisher konnte ich aber nicht finden warum nicht, oder wie ich das anders konfigurieren muss.
Code:
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /F:/repos/sphw-jfx/src/main/java/de/sphw/commons/jfx/dialogs/Dialogs.java:[98,27] cannot find symbol
  symbol:   method builder()
  location: class de.sphw.commons.jfx.dialogs.AboutDialog
[INFO] 1 error
[INFO] -------------------------------------------------------------
XML:
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <release>${maven.compiler.target}</release>
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${org.projectlombok.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>
 
Die Fehlermeldung gibt Dir doch die Lösung vor.

Das wirst du auch bekommen, wenn du fxml Dateien mit Controller Eintrag lädst und so ...

Also einfach den Eintrag noch in die module-info.java mit aufnehmen und dann sollte der Fehler weg sein.
Ja, das dachte ich ja auch, aber wie gesagt, wenn ich das mache kommt sofort die nächste. Und eigentlich muss ich dialogs für andere Module außer für den Test nicht öffnen, oder ich habe das mit open auch noch nicht ganz verstanden.
Code:
[ERROR] de.sphw.commons.jfx.dialogs.DialogsFxTest.centerToStageWithFixedSizeBiggerThanDialog(FxRobot)  Time elapsed: 0.038 s  <<< ERROR!
java.lang.RuntimeException: java.lang.IllegalAccessError: superclass access check failed: class com.sun.glass.ui.monocle.MonoclePlatformFactory (in unnamed module @0x5e6319e7) cannot access class com.sun.glass.ui.PlatformFactory (in module javafx.graphics) because module javafx.graphics does not export com.sun.glass.ui to unnamed module @0x5e6319e7
Caused by: java.lang.IllegalAccessError: superclass access check failed: class com.sun.glass.ui.monocle.MonoclePlatformFactory (in unnamed module @0x5e6319e7) cannot access class com.sun.glass.ui.PlatformFactory (in module javafx.graphics) because module javafx.graphics does not export com.sun.glass.ui to unnamed module @0x5e6319e7
 
Ja, man muss immer einen Fehler nach dem anderen raus machen ....

Dieser nächste Fehler:
module javafx.graphics does not export com.sun.glass.ui to unnamed module
kann z.B. mit einem Kommandozeilen-Parameter
--add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
eingestellt werden.
(Beim maven-compiler-plugin in configuration ein argLine Block einfügen. Und der bekommt diese Zeile. Bei mehreren Einträgen einfach in argLine mehrere Zeilen mit den ganzen Einträgen ...)
 
Wenn ich jetzt alles was noch kommen sollte beim maven-compiler-plugin als Argument eintrage, ist dass dann nicht auch beim goal compile ein Argument. Und ist das im Sinne des Erfinders, wenn ich das doch nur für die Tests brauche? Oder verstehe ich hier etwas grundlegendes nicht?
 
(Beim maven-compiler-plugin in configuration ein argLine Block einfügen.
Hab es aber gerade versucht, maven-compiler-plugin unterstützt kein argLine in configuration. Nur compilerArgs und compilerArguments.
Und folgendes verursacht einen fatal error.
XML:
<compilerArgs>
    <arg>--add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED</arg>
</compilerArgs>
 
Sorry, da habe ich beim schreiben nicht gut genug aufgepasst und daher versehentlich compiler plugin geschrieben.

Es ist ja kein Problem des compilers sondern der Test-Ausführung ==> Daher ist das surefire plugin das Plugin, welches konfiguriert werden muss und das kennt dieses argLine dann natürlich auch.


Edit:
Daher hattest Du das natürlich hier auch schon richtig erkannt:
Wenn ich jetzt alles was noch kommen sollte beim maven-compiler-plugin als Argument eintrage, ist dass dann nicht auch beim goal compile ein Argument. Und ist das im Sinne des Erfinders, wenn ich das doch nur für die Tests brauche? Oder verstehe ich hier etwas grundlegendes nicht?
Das mit dem argLine und so hatte ich richtig in Erinnerung, aber bezüglich compiler plugin habe ich natürlich Quatsch geschrieben ...
 
Sorry, da habe ich beim schreiben nicht gut genug aufgepasst und daher versehentlich compiler plugin geschrieben.
Kein Problem, damit ist dieser Punkt aber schonmal abgehakt. Surefire macht natürlich mehr Sinn, ich hatte das vorhin auch bereits ausprobiert, aber scheinbar durch die ganze Spielerei was anderes vergessen.
Jetzt habe ich es nochmal versuch und bin nun wieder an dem Punkt von Post 2 angekommen. Der annotationProcessorPaths wird scheinbar in testCompile nicht berücksichtigt, womit der Lombok builder nicht erstellt wird.
Code:
[ERROR] /F:/repos/sphw-jfx/src/main/java/de/sphw/commons/jfx/dialogs/Dialogs.java:[98,27] cannot find symbol
  symbol:   method builder()
  location: class de.sphw.commons.jfx.dialogs.AboutDialog
[INFO] 1 error

Hast Du vielleicht auch eine Lösung für die doppelte module-info.java im test Ordner. Ich bekomme hier Fehler in der IDE angezeigt und module-info.test funktioniert bei mir nicht.

Aber an dieser Stelle schonmal Danke für Deine bisherige Hilfe.
 
Hast Du vielleicht auch eine Lösung für die doppelte module-info.java im test Ordner
Ich hatte bisher in src/test/java keine module-info.java. Die hatte ich bisher in meinen Projekten nur in src/main/java.
Was für Probleme gibt es ohne diese module-info in test?

Und bezüglich Lombok: Ab Java 9 aufwärts musst Du das im compiler plugin (diesmal ist es wirklich das compiler plugin 🙂 ) konfigurieren. Fehlt das evtl?

Siehe dazu:
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</path>
</annotationProcessorPaths>
 
Ich hatte bisher in src/test/java keine module-info.java. Die hatte ich bisher in meinen Projekten nur in src/main/java.
Ich hatte das gestern in einem Beitrag gelesen, daher auch mal ausprobiert.
Was für Probleme gibt es ohne diese module-info in test?
Ohne die module-info.java im test Ordner hatte ich eben die Probleme vom 1. Post.
Ich habe zum testen mal opens de.sphw.commons.jfx.dialogs; in die module-info.java mit aufgenommen, aber das ist ein Rattenschwanz, danach geht es einfach weiter mit java modulen. Zumal ich das eigentlich auch nur für die Tests brauchen würde und das kommt mir nicht richtig vor.


Mit Deiner Hilfe habe ich jetzt aber verstanden wie ich die Fehlermeldungen behandeln muss. Jetzt habe ich die module-info.java im test Ordner wieder gelöscht und entsprechend alle Fehler nach einander behandelt und bin nun mit dieser argLine vorerst am Ziel angekommen.

XML:
<argLine>
    --add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
    --add-opens sphw.jfx/de.sphw.commons.jfx.dialogs=ALL-UNNAMED
    --add-opens javafx.graphics/com.sun.javafx.application=ALL-UNNAMED
</argLine>

Und bezüglich Lombok: Ab Java 9 aufwärts musst Du das im compiler plugin (diesmal ist es wirklich das compiler plugin 🙂 ) konfigurieren. Fehlt das evtl?
Ja, das habe ich drin. Als ich aber die module-info.java im test Ordner hatte, hat der compiler das bei testCompile scheinbar ignoriert. Aber da es ja jetzt auch ohne die module-info.java im test Ordner funktioniert, hat sich das ja erledigt. Das hat mich ohnehin wegen des Fehler in der IDE ziemlich gestört.

Danke nochmal für Deine Hilfe!
 

Neue Themen


Zurück
Oben