简体   繁体   中英

Java + Maven - executable jar from test class

I've got a multi-module Selenium project that's using the Page Factory and running tests through Suites by calling mvn clean verify...

I've created a JavaFX app that loads all the Suites and lets the user select a test, which is then run by the above-mentioned command.

The problem I'm facing now is that, in order to load all the test classes (I'm using test-jar in module dependencies so that my test class in the app module can see the tests in the other modules), I need to have the main method in a test class, and not in a main class. Obviously, that doesn't work since the test classes are not included in the jar.

I'm looking for a solution, either on having that main method in a test class, or for src/main to see into src/test.

One of the recommendations people have been giving is to have a separate module for the tests. This is not an option for me though as I don't have the rights to move the tests classes around or change the project structure that much.

Here's the plugin I'm using:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <mainClass>com.package.myapp.Main</mainClass>
        </manifest>
      </archive>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <appendAssemblyId>false</appendAssemblyId>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

For loading the suites, I use ClassLoader loader = Thread.currentThread().getContextClassLoader() which gets an ImmutableSet<ClassPath.ClassInfo> from ClassPath.from(loader).getTopLevelClasses()

This is a standard problem about decoupling modules: You have two modules: Dependent Module and Independent Module. You need the Independent to be invoked from the Dependent one, but without including the Independent in the Dependent's compilation.

So, you have several options to chose:

  1. When the API and protocol of Independent modules is known at compile-time. In this case, you should design an interface to model each Independent API. Publish these interfaces into a separated library, and retro-extend the Independent library to these interfaces. Provide also a factory which returns objects of these interfaces, by dynamic instantiation of a set of classes names (received at run time).

In the Dependent module, you just have to invoke the factory to obtain each interface implementation and use it.

  1. When the API and protocol of independent modules is not known at compile-time.

Uh, uh...! I hope sincerely this is not your case, because it does not fit in the good practices of standard design. Anyway, in Java you can always invoke any method in any object through the use of reflection . Though I won't advise it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM