Jenkins Maven: How to create independent jobs with single POM file - java

I have configured my Jenkins/Maven project, it reads my TestNG test from POM file configuration where is test.xml file with instructions which tests to run.
If I will add more tests to XML file (for example Test1 and Test2), they will be dependent on the same POM file, and when I create a job in Jenkins, both tests will run in one Jenkins job.
My question is:
How to configure Maven or Jenkins to be able to create two separate Jobs in Jenkins (Job Test1 and Job Test2) but using the single POM file?

My suggestion would be - create different Maven's profiles and execute it for specific Jenkin's job.
For example, you have 2 different test classes, you can create a specific profile for each at pom file:
<profiles>
<profile>
<id>test1</id>
<properties>
<suite.pattern>**/TestOne.java</suite.pattern>
</properties>
</profile>
<profile>
<id>test2</id>
<properties>
<suite.pattern>**/TestTwo.java</suite.pattern>
</properties>
</profile>
now you can run them separately:
mvn clean test -P test1
or
mvn clean test -P test2
Thus, you can configure two Jenkins jobs.

I have found another solution.
In Jenkins Project configuration need to write the command like this:
-Dtest=FirefoxTest2.java clean test
Do not need to add any additional information about java classes in POM file.

Related

Spring Boot Profile-specific Properties build using Maven Configuration

How to build the environment specific war file for a spring boot application using maven.I have created 3 profile configuration files placed in src/main/resource/ folder.
application.prod.properties
application.dev.properties
application.test.properties
I am able to run application by specifying required profile type in the VM argument tab with the value "-Dspring.profiles.active=dev" while executing the project as spring boot application.
Here while running as spring boot application i am able to the specify the required profile. In the same way when I need to use for MAVEN install with different profile. Is it there any way to specify profile as part of VM argument list in Run Configuration for Maven Install goal.
I have limitation as not to touch the existing java code.
I am using STS IDE, Spring boot 1.5.2.RELEASE version, Java 1.8 and oracle db.
In the same way also help me in how to configure profiles in Jenkins.
My profile configuration has two requirements.
Run the application in STS IDE as spring boot app with the VM args.
Used the below VM ARGS
-Dspring.profiles.active=dev
Blockquote
(Here I am getting below exception while starting SpringBootApp locally in Dev Environment).
APPLICATION FAILED TO START
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (the profiles "dev" are currently active).
Blockquote
How to do the same thing using maven install by specifying profiles dynamically to generate war file.I am unable to find the solution.
In your main application.properties file, set spring.profiles.active to #myActiveProfile# (or any name you wish)
spring.profiles.active=#myActiveProfile#
Add your application.properties file as a filtered resource so that the placeholder myActiveProfile is replaced during build phase.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
…
</build>
Add a profiles section to your pom.xml
<profiles>
<profile>
<id>dev</id>
<properties>
<myActiveProfile>dev</myActiveProfile>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<myActiveProfile>prod</myActiveProfile>
</properties>
</profile>
</profiles>
Basically, you are able to specify maven profiles when executing a particular goal. E.g mvn install -P profileName. Within a profile, you can create a property which can be passed from the command line when running a goal like mvn install -DmyActiveProfile=foo
Hope this helps.
Helpful Links
How to set spring active profiles with maven profiles
https://maven.apache.org/guides/introduction/introduction-to-profiles.html
Here, first of all I would suggest to rename your properties files to application-prod.properties, application-dev.properties and application-test.properties.
Second, maven install goal is to compile and build your project.
If you also want to run your application, when you do install I suggest to use spring-boot-maven-plugin.
And you can use a maven command something like below
mvn clean install spring-boot:run
Some links below for you information
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-running-your-application.html
https://docs.spring.io/spring-boot/docs/current/maven-plugin/run-mojo.html

How to run Junit test with a specific Category defined in a POM.xml using IntelliJ

I would like to know if using IntelliJ, is possible to run all test in the visual environment choosing a specific Junit category.
At the moment if you execute:
mvn clean test
you execute Fast Tests, but how to use IntelliJ to choose Slow or Fast?
Fragment of pom.xml
<profiles>
<profile>
<id>SlowTest</id>
<properties>
<testcase.groups>YOUR.PROJECT.test.categories.Slow</testcase.groups>
</properties>
</profile>
<profile>
<id>FastTest</id>
<properties>
<testcase.groups>YOUR.PROJECT.test.categories.Fast</testcase.groups>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
Many thanks in Advance
Juan Antonio
Your profiles are focusing the test run on specific categories. The JUnit Run/Debug configuration in IntelliJ also allows you to focus a JUnit run on a specific category.
You can access this configuration window from Run > Edit Configurations
Here's a screenshot showing a saved confoguiraiton named SlowTests which runs all tests having the category: com.stackoverflow.surefire.SlowTests:
You can save any such configuration by clicking on the file icon in the top left hand corner of this window and then that configuration will be available in the Run menu and you can even associate a keyboard short cut with it.
More information in the docs.
If you created your project using the pom.xml, in the "Maven Projects"-View you can activate the profiles you want to be active. There (Lifecycle) you can start the goal you want to be executed for each module as well.
How to get this: View->Tool Windows->Maven Projects

Shorter way for debugging Maven builds with eclipse

I have a Maven project in eclipse, which I run with a Run configuration. That configuration does compile and exec:exec with a script (called runner) defined in my pom.xml dependent on the OS (.bat in Windows, .sh in Linux). The runners do OS-dependent stuff and then start Java with my application. Which runner to use is specified with profiles like the following:
<profile>
<id>WINused</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<runnerForLaunch>${basedir}/src/runners/windowsRunner.bat</runnerToUse>
</properties>
</profile>
So, when I want to run it, I use Alt+Shift+X, M and select the Maven config. Later, I just use Ctrl+F11.
When I have to debug it, I have to do the following:
Edit the pom.xml to use another runner script that adds -agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=y to the Java call.
Launch the run configuration.
Launch a debug configuration that connects to the debugger.
My question is, can I somehow shorten that process? I regularly forget to undo my changes to pom.xml and use the runner I currently do not need.
Can't Maven somehow detect if I run it with Run as or Debug as and adjust variables depending on that?
If the runner config in your POM supports command line arguments:
Create another profile containing:
<profile>
<id>debug</id>
<properties>
<debugArgument>-agentlib: ...</debugArgument>
</properties>
</profile>
Use the new property in:
<runnerForLaunch>${basedir}/src/runners/windowsRunner.bat ${debugArgument}</runnerToUse>
Add debug to Profiles: in your debug configuration.
Use %1 or $1 at the Java call in your scripts.
Or:
Declare and supply a property value of <debugArgument>debug</debugArgument>.
Evaluate %1 or $1 in your scripts and call Java with different arguments accordingly.
Or:
Add a property debugArgument with 1) debug or 2) -agentlib: ... to Parameter Name / Value in your debug configuration.
Use the property in:
<runnerForLaunch>${basedir}/src/runners/windowsRunner.bat ${debugArgument}</runnerToUse>
1) Evaluate %1 or $1 for debug and call Java with different arguments accordingly or 2) use them at the Java call in your scripts.
Usually, you don't need to add debug options because eclipse simply adds them by calling "mvnDebug" instead of "mvn" when debugging a maven project. I suggest you simply run the shell script before you run your Java app, and start the Java app using exec:java in order to have it run inside the maven process that is attached to the eclipse debugger.

Pass Spring profile in maven build

I am running the spring boot app by passing the spring active profile like below:
spring-boot:run -Dspring.profiles.active=dev
But how do I pass the spring.profiles.active when creating the package using maven. Following is the maven command:
mvn clean install
In case someone have the same situation, you can achieve this with 2 steps with spring boot and maven:
First in spring properties or yaml file, add the spring.profiles.active with it's value as placeholder:
spring.profiles.active=#active.profile#
Second, pass the value with maven:
mvn clean install -Dactive.profile=dev
When the jar/war packaged, the value will be set to dev.
you can also leverage the use of maven profiles:
<profiles>
<profile>
<id>dev</id>
<properties>
<active.profile>dev</active.profile>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<active.profile>test</active.profile>
</properties>
</profile>
</profiles>
Then run:
mvn clean install -Pdev
Maven is a build-time tool, the only way to make it modify the eventual runtime behaviour of the built artifact is to use its (build-time) profiles. This must not be confused with Spring's runtime profiles which are parameters instructing the Spring container to bootstrap application in a specific way.
In other words, the spring.profiles.active parameter doesn't get "baked into" the war file by maven, you'll still need to pass it when starting the application up, be it via command-line parameters or configuration file or whatever mechanism your servlet container offers.
For package, you may replace install with package
mvn clean install -P dev
You can use environment variables.
export SPRING_PROFILES_ACTIVE=some,test,profiles
mvn spring-boot:run

Skip a *test* with cobertura plugin

We're in the middle of developing a big project, with many interacting modules and teams working on said modules. we have implemented CI with jenkins, which does periodic and on-commit builds that run junit tests, fitnesse tests, and cobertura coverage.
Since we're interacting with so many components, for some specific projects we have implemented integration tests, which bring up a Spring context, and run many test cases that simulate significant pieces of the application flow. These are implemented as Junit for simplicity/convenience, are placed in the src/test folders, but are not unit tests.
Our problem is that some component builds are taking very long to run, and one of the identified issues is that the long running integration tests are running twice, once in the test phase and once in the cobertura phase (as cobertura instruments the classes and then runs the tests again). Which leads to the question: is it possible to exclude a test from the cobertura execution?
Using exclude or ignore in the pom cobertura config only works for src/java classes, not the test classes. I couldn't find anything in the cobertura plugin documentation. I'm trying to find a way to do this via configuration. The only other way I think it could be accomplished is to move these tests to another maven module that does not have the cobertura plugin enabled, and have that module be the home of the integration tests. That way the build of the parent pom would trigger the integration tests, but it would not fall under the scope of cobertura. But if it could be done by configuration, it would be so much easier :)
Thanks in advance,
JG
==== UPDATE AND RESOLUTION ====
After building a little on kkamilpl's answer (thanks again!) I was able to include and exclude the needed tests without changing anything in the directory structure. With just java style expressions, once you realize that overrides in the surefire plugin setup, you can manage to run "all but a package"/"only that given package" like this:
<profiles>
<profile>
<id>unit-tests</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<testcase.include>**/*.class</testcase.include>
<testcase.exclude>**/integration/*.class</testcase.exclude>
</properties>
</profile>
<profile>
<id>integration-tests</id>
<properties>
<testcase.include>**/integration/*.class</testcase.include>
<testcase.exclude>**/dummyStringThatWontMatch/*.class</testcase.exclude>
</properties>
</profile>
</profiles>
I was able to run all unit tests (that is, everything but the contents of the integration test folder) with test target and default profile, and then invoke target test with the integration-tests profile to just run the integration test. Then it's a matter of adding the call to the new profile in jenkins as a new top level target call (it targets a parent pom) so that the jenkins build will run the integration tests, but only once, instead of having them re-run by cobertura when it uses the test target.
You can always use maven profiles: http://maven.apache.org/guides/introduction/introduction-to-profiles.html
Separate tests to different directories e.g:
testsType1
SomeTest1.java
SomeTest2.java
testsType2
OtherTest1.java
OtherTest2.java
Next in pom define proper profile for each test type e.g:
<profile>
<id>testsType1</id>
<properties>
<testcase.include>%regex[.*/testsType1/.*[.]class]</testcase.include>
<testcase.exclude>%regex[.*/testsType2/.*[.]class]</testcase.exclude>
</properties>
</profile>
To define the default profile:
<activation>
<activeByDefault>true</activeByDefault>
</activation>
And finally define surefire plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>>
<configuration>
<includes>
<include>${testcase.include}</include>
</includes>
<excludes>
<exclude>${testcase.exclude}</exclude>
</excludes>
</configuration>
</plugin>
To use it call
mvn test #to use default profile
mvn test -P profileName #to use defined profileName

Categories

Resources