I have a huge project for which I am testing mutation testing with Pitest. The project is in an OSGi form and having all modules separated. I have this structure:
|-1.myProgramm-parent
|-pom.xml
|-2.myProgramm.module1
|-pom.xml
|-2.myProgramm.module1.Test
|-pom.xml
|-3.myProgramm.module2
|-pom.xml
|-3.myProgramm.module2.Test
|-pom.xml
... and so on.
Now I put into the pom.xml from my 1.myProgramm-parent all the Pitest configurations I need (taken from the official site of pitest.org). The targetClasses and targetTests are in the pom.xml of 2.myProgramm.module1.Test, which I need to use.
Pitest finds all 7 test classes to minion. And sends them. Then gathering for test description is also fine. Coverage generator Minion excited ok.
Then: created 0 mutation test units.
And a build failure is shown. No mutations found.
I tried already all the possible annotatons shown on pitest.org, like: targetClasses, targetTests and additionalClasspathElements.
How can I say that the testClasses are in this folder 2.myProgramm.module1.Test, where I am setting the targetClasses, targetTests in the pom.xml. BUT the normal javaClasses to be minioned are in this package: 2.myProgramm.module1
How I can tell, go out of your test-folder and get into the folder up?
I also gave the pure path to the folder with the normal javaClasses, but NO reaction.
Do you have an idea?
Ps. It is not my program. I didn't wrote it. I am just working on it, to test. I have already 11 other programs with Maven and Gradle. I get all to minion. But this is such a pain in the butt! ARG!
If you are working with multi-module projects, you will need to use the pitmp plugin (https://github.com/STAMP-project/pitmp-maven-plugin).
This is because PIT itself only mutates classes that are defined in the same module as the tests. In contrast, pitmp will execute the tests for all classes of the modules. More details are provided in the link above.
Related
This must be a very simple task for many of you. Let me explain the scenario.
I recently started practicing questions on HackerRank. But, I found the platform not so friendly for debugging. No online platform is or can be because of its own limitations. HackerRank provides question and stub code for many of the problems on its problem page.
For example, let us consider, https://www.hackerrank.com/challenges/java-datatypes/problem
But, because of it's debugging limitations I can't make the best use of portal. Hence, I wrote a PHP script to scrape all the content from the website and generated problem statements in HTML/PDF formats and solutions in java format.
Here's the GitHub project for the same.
https://github.com/saint1729/hr-idea-integration
The main intention of this activity is to have an integration of the website with an IDE like Intellij IDEA. This is now complete.
I created a gradle project with existing sources. But, the project contains many java files (almost 500+ files and each file has it's own main method). My intention is to solve one problem at a time and see if it compiles and submit it using a REST API provided by HackerRank.
But, when I am trying to Right Click and Click on Solution.main() for every file, it tries to compile all files in the project and because there are some compilation issues with the project, I am unable to test my code for the current file. This is not productive for me.
Please let me know if it's possible to compile and run a single file in IDEA (without compiling the whole project). If the idea of creating a gradle project for this activity is not necessary, can somebody recommend me another efficient solution?
NOTE: Every scraped java file contains it's own main method. I know that a project can contain only 1 main method. But, I don't know a coherent solution to solve my problem.
If you want to continue using gradle, you create a module per solution.
Let's suppose you have 3 solutions. canyouaccess, duplicateword and java1darray.
So your repository looks like this:
java
canyouaccess
src/main/java
package
Solution.java
duplicateword
src/main/java
package
Solution.java
java1darray
src/main/java
package
Solution.java
build.gradle
settings.gradle
Each module can have its own main. Inside a settings.gradle file the modules can be defined or disabled by commenting it out.
Your build.gradle looks like this:
...
subprojects { project ->
apply plugin: "java"
sourceCompatibility = 11
}
...
For the settings.gradle looks like this:
include 'java:canyouaccees'
include 'java:dublicateword'
include 'java:java1darray'
Each module can be build separately, you could even group modules by creating a sub module structure.
And each module can have it's own debug configuration, where the module and the main is selected. If your set them as shared, they are stored in xml format under .idea/runConfigurations. So your script can create them as well.
Each module needs it's own gradle.build file, where the main class is declared.
jar {
manifest {
attributes('Main-Class': 'your.main.class.goes.here')
}
}
Something like this should do.
I installed JUnit-Tools 1.1.0 in eclipse market. As per the documentation, they want the test-projects and the mock-projects to be created manually.
My class structure is like below :
I tried creating a test package like com.unifiedportal.core.unifiedportal.service.test and tried generating the test classes from the JUnit-Tools..
Got an warning like below :
Let me know how i should proceed with creating the test-project for this.
If you want to generate the tests under the same project you are in then remove Test-project-postfix in the junit tools preferences, otherwise let the postfix as it is and create a project (not a package) with the same name than your project plus that postfix.
Look an example of my config for generating the tests in the same project under src/test/java, because I don't want my tests to be in a separated project:
you can add the jars as maven or gradle dependencies.Change the test-source-folder-name to src/test/java and generate the test cases using the plugin.This will generate the test cases in your test folder
I am currently trying to introduce unit tests to a legacy project based on ant. The problem is that the project's structure is a little unconventional: Java files mixed up with xml files in the same directory, there are multiple java source directories, the Java files depend on import jars wich are not present in the same project ...
What is a clean way to introduce unit tests to a project with this structure:
--->project
----->folder1
----->folder2
-----file1.java
-----file2.xml
-----file3.prop
----->folder3
I'd probably do it like:
--->project
----->folder1
----->folder1-test
----->folder2
-----file1.java
-----file2.xml
-----file3.prop
----->folder2-test
-----file1Test.java
-----file2Test.xml
----->folder3
----->folder3-test
Or bite the bullet and refactor using maven conventions
folder1/src/main/java
folder1/src/main/resources
folder1/src/test/java
folder1/src/test/resources
etc...
I'm the author of one of the Maven plugins (not Apache/Codehaus, completely indie). Sometimes I get support requests or test cases where I'd really need to debug the execution of my plugin with an existing pom.xml. Basically the test cases I get are sample/test project (pom.xml with src/main/resoures, src/main/java and so on).
What I need is a way to:
Load an existing pom.xml.
Find a specific execution of my plugin there (usually it's the only one).
Get an instance of MyMojo - fully initialized/condigured, with all the components and parameters corectly injected.
Execute MyMojo.
What's important is that test projects are separate projects, I don't want to copy them into the Maven module of my plugin.
I'd like to be able to do this without remote debugging.
By debugging I mean to be able to set and halt on breakpoints (also conditional), step in/out/over on the source code.
Ideally I'd like to be able to executeMyMojoFrom(new File("pom.xml")) - for instance in a JUnit test or a main method of some class. (I can supply groupId, artifactId etc. All other definitions should just be loaded from that pom.xml.)
How can I achieve this?
What I've tried so far:
Debug As... on pom.xml in Eclipse - does not work well enough (source code not found, breakpoint don't work as its not a Java project context)
Maven Embedder/Invoker solutions - spawn things in separate processes via CLI. Forget breakpoints, no debugging.
Remote debugging with mvnDebug and then remote debugging from Eclipse as suggested by Pascal Thivent here. This is so far the best option. However, remote debugging means starting mvnDebug separately, and there's also not guarantee that the JARs I have in Eclipse are exactly the same that mvnDebug is using. So there's a certain distance here.
maven-plugin-testing-harness - I actually thought this this will do the task. But first I was jumping through hoops for a few hours just to make it start. All of the important dependencies are "provided" so I first had to figure out the right combination of versions of these artifacts. And then - only to discover that AbstractMojoTestCase only works within the plugin module you want to test. Probably I was mistaken when I thought that maven-plugin-testing-harness was a testing harness for Maven plugins. It seems that it's a testing harness for the plugin from that plugin's module. Which is not illogical but does not help my case. I'd like to test my plugin in other modules.
So right now I've got the best results with the remote debugging solution. But what I'm looking for is really something like maven-plugin-testing-harness but not hardwired to the plugin module. Does anyone happen to have a hint, if such a method exists somewhere in Maven artifacts?
To be even more specific, I'd like to write something like:
public void testSomething()
throws Exception
{
File pom = getTestFile( "pom.xml" );
assertNotNull( pom );
assertTrue( pom.exists() );
MyMojo myMojo = (MyMojo) lookupMojo( "myGroupId", "myArtifactid", ...,
"myGoal", pom );
assertNotNull( myMojo );
myMojo.execute();
...
}
Compare it to the MyMojoTest here - it's almost there. Should just not be hardwired into the mymojo Maven module (as it is in maven-plugin-testing-harness).
Update
Few answers to the questions in comments:
You mean you don't want such a test class, i.e MyMojoTest to reside inside the same project as the MyMojo, i.e your plugin project? Why is that?
Exactly. I want to debug the plugin execution in an existing Maven project, I don't want to move that project to my plugin project first to be able to run a test. I want to be able to test/debug an existing project. Ideally, I'd just need to add my-maven-plugin-testing dependency and subclass MyMojoTest in the project's src/test/jaca. This would be a good instrument to debug executions. Dragging the target project into my Mojo project ist just too much overhead - and mostly these aren't really the test cases I want to keep long-term. I hope, this answers, why.
Anyway, it's merely a convention to keep the project-to-test/pom.xml inside the src/test/resources of your plugin module, not a rule...
My problem is not the location of the pom.xml of the project-to-test, that is easily configurable. My difficulty is that maven-plugin-testing-harness is is somehow hardcoded to be in the Mojo's project. It uses the pom.xml of the Mojo, looks for other special files/descriptors in the containing project. So I somehow can't use it in a non-Mojo project, or can I? This is my question.
And I'm not sure why Debug as... didn't help you...
Not sure either, but (1) breakpoints did not work and (2) the source code was not "attached" for some reason.
If the Debug as didn't work for you as well as it should, you can try to use the mojo-executor with a bit of work.
https://github.com/TimMoore/mojo-executor
This is how you would execute the copy-dependencies goal of the Maven Dependency Plugin programmatically:
executeMojo(
plugin(
groupId("org.apache.maven.plugins"),
artifactId("maven-dependency-plugin"),
version("2.0")
),
goal("copy-dependencies"),
configuration(
element(name("outputDirectory"), "${project.build.directory}/foo")
),
executionEnvironment(
mavenProject,
mavenSession,
pluginManager
)
);
The project, session, and pluginManager variables should be injected via the normal Mojo injection. Yes, that means this should be executed from the context of another maven plugin. Now that I think about it, whether this would help you in any way is still a question because this still relies on injection of such components by the underlying plexus container.
My original idea was though to have you build a maven plugin that would invoke your jaxb2 plugin thru the mojo-executor like above, then serialize the mavenProject, mavenSession, pluginManager, i.e, all the plexus injected components and then use those objects to invoke your jaxb2 plugin in future from a standalone class without the plugin that you built.
I'm working on a large legacy project that I'm trying to componentize, starting with SonarQube. I'm configuring a multi-module project in sonar-project.properties. This works fine. However, I have an issue precisely identifying source folders.
Unfortunately, our modules aren't neatly separated in the file system. The project is separated into many Eclipse projects, and several Eclipse projects together form one module. I can, of course, enumerate all the projects, but this is very cumbersome as there are a lot of them. Here's a (simplified) version of our directory structure:
projects/
moduleAsubmodule1/
src/
com/mycompany/moduleA/submodule1/
moduleAsubmodule2/
src/
com/mycompany/moduleA/submodule2/
moduleBsubmodule1/
src/
com/mycompany/moduleB/submodule1/
moduleBsubmodule2/
src/
com/mycompany/moduleB/submodule2/
moduleBsubmodule3/
src/
com/mycompany/moduleB/submodule3/
Imagine many more modules and submodules, where the project name is concatenated, but the package names are nicely divided, making it much easier to differentiate on those.
moduleA.sonar.projectBaseDir=.
moduleA.sonar.sources=projects/**/src/com/mycompany/moduleA/**/*
moduleA.sonar.test=projects/**/*.test/src/com/mycompany/moduleA/**/*
According to the documentation, this should be possible for exclusions. However, I get the following error message:
16:10:44 ERROR: Unable to execute Sonar
16:10:44 ERROR: Caused by: The folder 'projects/**/src/com/mycompany/mymodule/**/*' does not exist for 'XXX:XXX:mymodule' (base directory = D:\XxxSonar\.)
So I guess globs don't work for sources? If that's indeed the case, what can I do?
We use SonarQube 4.1.2.
I had the same issue, but I solved it by doing like this:
sonar.sources=.
sonar.inclusions=projects/*/src/**/*
The inclusions/exclusions properties support wildcards. Same for your tests:
sonar.test.inclusions=projects/*/*.test/src/**/*
Wildcards are not allowed when specifying "sonar.sources". Instead, you should play with the properties that allow to narrow your source and test files. See the documentation page on how to include or exclude files to narrow the focus.