maven-plugin-development
maven-plugin-development copied to clipboard
Any recommendation for writing functional tests?
When writing a gradle-plugin, we can add some functional tests under src/functionalTest/java.
What is your recommendation for Maven Plugin? Everything seems quite old. Documentation: https://maven.apache.org/plugin-developers/plugin-testing.html
Did you try any of those method?
Hello @jmini,
you're right, testing Maven Mojo is not as clear cut as testing Gradle plugin is. There are several possible ways each with individual pros and cons. The page you references above already covers some of the options. There's also https://github.com/takari/takari-plugin-testing-project which help to set up tests.
At work we ended up building our own test harness. Our tests are implemented using Spock so we have a custom project builder fixture that uses Groovy's markup builder to generate a POM file and set up a maven project. Then we have a MavenRunner class that works much like GradleRunner from the Gradle test harness to start an in process maven build.
From our experience testing build logic in a more end to end kind of way makes the most sense since it's often the integration with the build tools or processing of files that's causing issues. So there is not much of a point for writing more unit test style tests. You might be able to leverage https://github.com/takari/takari-plugin-testing-project to achive something like that. But I didn't try it myself yet.
Writing a library that help with testing maven plugin that are build with this plugin is on my list of doing but I doubt I will have the time to work on that any time soon. I still have to finally publish the 0.3 release which is blocked because of an issue with the Gradle Plugin Plugin.
Let me know what you ended up doing for testin maven plugins.
I think I have something working.
I looked how the maven-plugin of the props2yaml project was using the takari-plugin-testing-project
So I created a task generateTakariTestResources to create some metadata files about the maven plugin under test. The takari testing logic is reading those metadata files.
Here my examples:
The implementation is really experimental:
- Usage of the
dependsOnis not recommended by Gradle experts. Especially to depend on tasks in other projects. - The method
addProject(..)to create theworkspacestate.propertiescontent- Not sure if the way to retrieve the GAV based on a project (found here) is correct. Maybe I should look into the publications.
- The location of the pom does not seems to be stable (in some projects it is
build/publications/mavenJava/pom-default.xml, in otherbuild/publications/maven/pom-default.xml) - The location of the jar for a given project is now really weak. I found that it is possible to do
jar.archiveFile.get().asFile.getAbsolutePath(), but I am not sure how to do it for the jar inside a given project.
- The point about not being able to access the
plugin.xmlduring tests is discussed in https://github.com/britter/maven-plugin-development/issues/76 - I am not sure about the items listed in the
workspacestate.properties. I am adding all the projects having a maven publication. I could also check the projects in theruntimeClasspathconfiguration and add only those.
Probably my task is not generic enough.
I appreciate any feedback I can get. I think I will start to use this approach in some of my projects.
Hey all,
just leaving this here as breadcrumb for future readers. The takari solution is pretty neat once one got it running as you can configure/setup your whole tests from code. On the other hand, many maven plugins are tested using the maven invoker plugin. If you find yourself in a position where you want to migrate your maven plugin's build to gradle, you may want to keep the invoker plugin tests. I was in the same situation and solved it using the maven-exec-plugin. It works like this:
- deploy the the plugin under test to a project-local m2 repository
- Have a template
pom.xmlwhich configures the invoker plugin. The pom contains some placeholders and uses maven'srevisionas version. This allows us to pass some parameters from the gradle build to the maven build, including the gradle project's version - Invoke a maven build using the maven-exec-plugin
With some fiddling I was also able to make it caching friendly. You can see it in action here (the directory is pretty self contained): restrict-imports-enforcer-rule