Maven: BDD build and copy "plug-in" artifact to program folder, then run program for tests?

StackOverflow https://stackoverflow.com/questions/21141509

  •  28-09-2022
  •  | 
  •  

Question

I'm building a plug-in for a Java program (let's call it JavaProg). The program has a mechanism in which its behavior can be extended by loading JAR files at runtime that are placed in the programs installation folder: /plugins.

I want to use Maven for building the plug-in, and I want to use BDD with Cucumber (with FEST maybe) for driving its Swing GUI. Basically the plug-in will add new menus and buttons to JavaProg when loaded, and I want to test those through JavaProgs GUI - of course this requires the plug-in to be loaded and this is the central problem.

When developing the plug-in I don't have access to any source files of JavaProg. The only thing I have is a JAR file with some classes I must extend to allow the plug-in to be loaded into JavaProg. However, this poses a question: how do I setup Maven to handle this?

Basically I want something like this:

JavaProg-plugin (project)

  • Contains source for the plugin
  • Contains unit tests for the plugin (which doesn't depend on JavaProg)
  • Can be built as a JAR file (maven package)

AcceptanceTests (project)

  • Contains the Cucumber tests
  • When asked to do "test" Maven will:
    • Check that JavaProg is installed on the local system, if it's not then it cannot test and will abort
    • Build the JavaProg-plugin project as a JAR and copy it to /plugins
    • Launch JavaProg with Java. It's main class is located in /javaprog.jar
    • Run the Cucumber tests which will find the newly launched JavaProg window, click its buttons, check the responses and so on
    • Cleanup: delete the plug-in from /plugins

Is this a crazy idea or is it possible? I want to do automated BDD tests through the GUI and I thought this would be the best way. I just have no idea if Maven is fit for the task or how to start.

Was it helpful?

Solution

Answer One: Check if the app is running from your tests. This can be done from java.

Create a java function that:

  1. checks if the app is installed and running. If you like this step could also install the program and run it.
  2. Remove any old version of the plugin, if its there
  3. If the plugin is not installed go trough the plugin installation procedures.
  4. Checks that the installation went ok.

Just call this function from all your tests.

Though this approach is doable I think it might become a mess after a while since JavaProg might build up unknown state. It is generaly a good idea to structure your test environments in a way that lest you test from a deterministic startingpoint. This makes it a lot easier to reason about the results.

The two next answers are suggestions on how to achieve this.


Answer two: Run JavaProg from inside maven instead of reusing an installed app.
I belive it is mutch better to run the JavaProg from maven and test against it from inside maven. This way you will have a clean running install of JavaProg and your tests are much more likely to be determenistic. I dont know if this is possible, but its seems like you are the author of javaprog and this might be a good solution.

Usually for these kinds of setups I tend to do this in an external project, not part of the JavaProg plugin project. It is of course easy to join them in the plugin, but its tidier to keep them seperate.

Assembling the app
Lets create a new project named JavaProgPluginTest. JavaProgPluginTest needs a dependency to JavaProg. You can use the maven-dependency-plugin to copy the plugin into ./plugins forlder. This would have to be done in a phase before the test phase. Pherhaps the compile phase.
I am assuming here that your tests can be compiled without any dependencies to the plugin. If you need this things get a bit trickier.

Running the tests
Since I am not a Cucumber expert I wil explain how I would do it in JUnit instead.
I would find a way to bring the app as a static dependency inside my tests. Create a static function that initiates the app if it is not running and waits until it is finished initiating. call this from inside the test before the tests are run.
Then you can safely run your tests.


Answer tree: Use other tools to create a complete deterministic machine running JavaProg. Then run against it.
At work we have created a setup where we can order new virtual machines via a rest call to a webservice. This has allowed us to create a setup where we create a complete virtual test environment from scratch before running our tests. It also has the added benefit that when a test fails we have a running virtual environment that demonstrates the failure. This makes it a lot easier to figure out what went wrong.

The solution we are using is based on pearl and bash script and is controlled by jenkins. Testresults are reported back to jenkins using the TAP protocol.

Using this approach we are able to test the installation process and lots of runtime stuff. Cleanup is easy since we just have to delete the wm when it is no longer usefull.

OTHER TIPS

Here is an example of using maven-dependency-plugin to add dependency jars at various stages during the build:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.6</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>com.github.jsimone</groupId>
                                <artifactId>webapp-runner</artifactId>
                                <version>${webapp.runner.version}</version>
                                <destFileName>webapp-runner.jar</destFileName>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
                <execution>
                    <id>copy-new-relic</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <includeGroupIds>com.newrelic.agent.java</includeGroupIds>
                        <includeArtifactIds>newrelic-agent</includeArtifactIds>
                        <stripVersion>true</stripVersion>
                    </configuration>
                </execution>
            </executions>
        </plugin>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top