I have implemented a Maven plugin which is used to create test database (with random name) before Maven test phase, and drops that database when the test phase is completed.
The plugin need to be executed two times, before test phase (when is used to create database) and after test phase (when is used to drop that test database).
Which Maven lifecycle phase will be always executed after test phase, whether test phase is successfully executed or not?
There are no particular phase in the Maven lifecycle that corresponds to pre- and post-test. This is because unit tests are not supposed to require an external environment. It sounds like what you want to do are not unit tests but integration tests instead, because they require an environment to be set up.
From the docs:
test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
integration-test - process and deploy the package if necessary into an environment where integration tests can be run
And there is a pre-integration-test, integration-test and post-integration-test that are used to setup, run and destroy the test environment.
pre-integration-test: perform actions required before integration tests are executed. This may involve things such as setting up the required environment.
integration-test: process and deploy the package if necessary into an environment where integration tests can be run.
post-integration-test: perform actions required after integration tests have been executed. This may including cleaning up the environment.
As such, it would be easier and a lot cleaner to do this in integration-test phase using the maven-failsafe-plugin.
Now, if you really want to run that as unit tests, I would not write the creation / deletion of the database as a Maven plugin. It would be a lot better to let your application create the test database when it is configured in a test environment. (For example, if you're using Spring, it has a lot of facilities for that.)
And, if you really want to run that as unit tests in the test phase, and using your plugin, you will have to skip the default execution of the maven-surefire-plugin and then define an execution of your Maven plugin creating the database, a new execution of the maven-surefire-plugin and an execution of your Maven plugin dropping the database, bound to the test phase.
This works because Maven invokes the plugins in the order as they are defined in the POM when they're bound to the same phase.
A configuration would look like:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId><!-- group id of your plugin --></groupId>
<artifactId><!-- artifact id of your plugin --></artifactId>
<version><!-- version --></version>
<executions>
<execution>
<id>create-db</id>
<phase>test</phase>
<goals>
<goal><!-- your goal --></goal>
</goals>
<!-- add configuration -->
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId><!-- group id of your plugin --></groupId>
<artifactId><!-- artifact id of your plugin --></artifactId>
<version><!-- version --></version>
<executions>
<execution>
<id>drop-db</id>
<phase>test</phase>
<goals>
<goal><!-- your goal --></goal>
</goals>
<!-- add configuration -->
</execution>
</executions>
</plugin>
Related
I try to make parallel execution using JUnit5 + Maven Surefire Plugin. For that I made some settings:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<properties>
<configurationParameters>
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
</configurationParameters>
</properties>
</configuration>
</plugin>
</plugins>
And it works correctly for test methods that marked annotation #Test.
But I also have tests that marked annotation #ParameterizedTest and I expect that they should run in parallel using different values from the source. But it doesn't work as I expect - it runs in one thread.
Is there possible to fix that or it is a feature in JUnit 5.
Use #Execution(ExecutionMode.CONCURRENT) tag along with #ParameterizedTest to run the scripts in parallel for the each set of data.
I've a pretty standard Java-Maven build with some plain JUnit tests and some for Arquillian. JaCoCo is hooked via Maven like this:
<properties>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
</properties>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${argLine}</argLine>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.4</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Running Sonar now seems to work, however the code coverage is all wrong. I'm not sure if these are separate issues or if there is one problem with the configuration producing all of them, so I'll just list them:
test suites are not run at all (meaning JUnit tests with #RunWith(AllTests.class))
Arquillian tests (with #RunWith(Arquillian.class)) are run, but the code coverage is wrong, i.e. entities have a code coverage of 0%
an entire module is not tested and I'm not sure why (all but one of the tests has #RunWith(Parameterized.class), but this annotation works in another module)
(After Qword's suggestion I tried it without the reportPath. However the reports in target/sites/jacoco/ are still missing the coverage.)
I'm wondering if the problem is with the JUnit runners or maybe because some of these tests are in another module than the classes they test (Arquillian / integration tests especially). On the other hand, some of the JUnit runners seem to work as well. Maybe it's a third component that breaks the build.
I tried arquillian-extension-jacoco as well, this plug-in doesn't seem to work at all (tests won't even start).
Is the problem with the JUnit runners? With the integration tests? How do I fix this?
You don't actually need to specify sonar.jacoco.reportPath. First of all, it's been deprecated in favor of sonar.jacoco.reportPaths. Second, if you specify the latter property, all reports will be created in a single binary file, but this is not default Jacoco behaviour (and SonarQube deprecated that as well).
I would suggest, as a first step, to
Entirely remove properties sonar.jacoco.reportPath and sonar.jacoco.reportPaths
Remove the configuration node from Jacoco plugin definition
Now, you'll won't find anymore the jacoco.exec file but instead for every module you'll find a new directory target/sites/jacoco in which there will be reports in CSV, XLM, and HTML. This is the standard Jacoco behaviour in v0.8.4.
I'm not entirely sure this will fix all your problems, but at least
I'm quite sure SonarQube will be able to correctly pick up the reports and show the coverage
You'll be able to analyse coverage with a simple mvn clean install on your local machine without having to go to SonarQube every time
When I run a mvn -Pprod package, gulp runs tests.
But it fails during the tests. I don't know how solve this for now.
So I would like to disable those tests.
How can I do that?
Thank you.
In pom.xml, remove the following from the prod profile's build tag:
<execution>
<id>gulp test</id>
<goals>
<goal>gulp</goal>
</goals>
<phase>test</phase>
<configuration>
<arguments>test --no-notification</arguments>
</configuration>
</execution>
It's at line 750 in JHipster 3.3.0's pom.xml.
A much better solution would be to figure out why those tests are failing and fix them - their purpose is to help you find problems and they are failing for a reason.
In newer JHipster version 5.7.2, to disable web tests (jest), you need to remove the following on pom.xml:
<execution>
<id>webpack build test</id>
<goals>
<goal>npm</goal>
</goals>
<phase>test</phase>
<configuration>
<arguments>run webpack:test</arguments>
<npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
</configuration>
</execution>
Can you try with mvn -Pprod package -DskipTests. -DskipTests should skip test during the build and package
maven-surefire-plugin enables running JUnit tests in parallel[1] - is there way to run JUnit-Tests in Eclipse in parallel, too?
[1] e.g.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<parallel>methods</parallel>
</configuration>
</plugin>
"Running tests in parallel" https://maven.apache.org/plugins/maven-surefire-plugin/examples/junit.html
You can use tempus-fugit to run tests in parallel in Eclipse. This should work.
I try to use JAXB2 maven plugin to generate java code from a bunch of .xsd files. If I try to generate from all xsds in a single execution I'll get org.xml.sax.SAXParseException: 'root' is already defined. I cannot modify the xsd files so I need to generate each independently. I found the following pom configuration to achieve that:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>jaxb-Execution1</id>
<phase>generate-sources</phase>
<goals><goal>xjc</goal></goals>
<configuration>
<schemaDirectory>${jaxbSchemaDirectory}</schemaDirectory>
<outputDirectory>${jaxbGenerateDirectory}</outputDirectory>
<staleFile>${jaxbGenerateDirectory}/.staleFlagExecution1</staleFile>
<bindingDirectory>${jaxbSchemaDirectory}</bindingDirectory>
<bindingFiles>bindings1.xml</bindingFiles>
<schemaFiles>schema1.xsd</schemaFiles>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>jaxb-Execution2</id>
<phase>generate-sources</phase>
<goals><goal>xjc</goal></goals>
<configuration>
<schemaDirectory>${jaxbSchemaDirectory}</schemaDirectory>
<outputDirectory>${jaxbGenerateDirectory}</outputDirectory>
<staleFile>${jaxbGenerateDirectory}/.staleFlagExecution2</staleFile>
<bindingDirectory>${jaxbSchemaDirectory}</bindingDirectory>
<bindingFiles>bindings2.xml</bindingFiles>
<schemaFiles>schema2.xsd</schemaFiles>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
</executions>
But this is not working. The problem is that configurations are not read from inside of the execution block. Why is that? I am using maven 2.2.1.
I had the same issue when I tried to run the plugin using:
mvn jaxb2:xjc
A workaround for me was using:
mvn generate-sources