I need to analyse code via Sonar using Gradle and I have some strange problem which I cannot handle. I have the following project structure
-java
|-src
|-main
|-test
|-integration-test
And Sonar analyse only test directory by default and integration-test directory if I change sonar.test property to /src/integration-test, but I want to analyze this two directories together and I actually dont know how to do it. Below we have my sonarqube task properties from gradle.build file.
sonarqube {
properties {
property "sonar.projectName", "projectName"
property "sonar.projectKey", "org.sonarqube:projectName"
property "sonar.host.url", "http://sonar.doesntmetter"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.junit.reportsPath", "build/test-results/test"
property "sonar.jacoco.reportPath", "build/jacoco/test.exec"
property "sonar.jacoco.itReportPath", "build/jacoco/integrationTest.exec"
property "sonar.login", "admin"
property "sonar.password", "admin"
}
}
What I noticed is that when I run gradle build there would be integrationTest.exec and test.exec in /build/jacoco/ directory, but in case I run gradle sonarqube with default sonar.test property there would be only test.exec, and from other hand when I run gradle sonarqube with sonar.test=/src/integration-test there would be both test.exec and integrationTest.exec.
Dont you know how to analyze unit and integration test in one run?
I think you can add this to your Gradle:
sonarqube {
properties {
properties["sonar.sources"] += sourceSets.custom.allSource.srcDirs
properties["sonar.tests"] += sourceSets.integTest.allSource.srcDirs
}
}
Just use += to add more tests/sources.
More information and examples are here.
EDIT:
Add report paths too! Properties are named:
sonar.surefire.reportsPath - test.testResultsDir (if the directory exists)
sonar.junit.reportsPath - test.testResultsDir (if the directory exists)
EDIT:
I rewrite your code and set sources for testing in one line, check it with your structure
sonarqube {
properties {
property "sonar.projectName", "projectName"
property "sonar.projectKey", "projectKey"
property "sonar.host.url", "http://itsprettyprivate"
property "sonar.java.coveragePlugin", "jacoco"
// Or add it via += to properties, it is up to you ;)
property "sonar.sources", "src/java,src/test,src/integration-test"
//Tells SonarQube where the unit tests execution reports are
property "sonar.junit.reportsPath", "build/test-results/test"
//Tells SonarQube where the unit tests code coverage report is
property "sonar.jacoco.reportPath", "build/jacoco/test.exec"
//Tells SonarQube where the integration tests code coverage report is
property "sonar.jacoco.itReportPath", "build/jacoco/integrationTest.exec"
property "sonar.login", "admin"
property "sonar.password", "password"
}
}
Related
I am using Jacoco v0.8.4 and Sonarcube v2.7.1.
I am using the following configuration for SonarCube.
property "sonar.sources", "src/main/java"
property "sonar.binaries","build/intermediates/javac,app/build/tmp/kotlin-classes"
property "sonar.java.binaries", "build/intermediates/javac,app/build/tmp/kotlin-classes"
property "sonar.tests", "src/test/java" // where the tests are located
property "sonar.java.test.binaries", "build/intermediates/javac,app/build/tmp/kotlin-classes"
property "sonar.jacoco.reportPath", "build/jacoco/testDevDebugUnitTest.exec"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.android.lint.report", "build/reports/lint results.xml"
The SonarCube analysis failed with reason as Invalid value for sonar.java.binaries
> No files nor directories matching 'app/build/tmp/kotlin-classes'
But 'app/build/tmp/kotlin-classes' exist in my project folder.
But, If I remove kotlin things from the property then it provides the coverage for Java files successfully.
Am I doing anything wrong for Kotlin coverage?
you also need to add you build variant folder in pathlike below
property "sonar.java.test.binaries", "build/intermediates/classes/test/, app/build/tmp/kotlin-classes/<BuildVariant>UnitTest"
property "sonar.java.binaries", "build/intermediates/classes/<BuildVariant>/, app/build/tmp/kotlin-classes/<BuildVariant>/"
property "sonar.binaries", "build/intermediates/classes/<BuildVariant>/, app/build/tmp/kotlin-classes/<BuildVariant>/"
and one more thing try to avoid using file name with whitespace like lint results.xml
I have a selenium script which I want to run from Jenkins. I have a properties file called app.properties. This file consists properties such as:
browser=chrome
I configured my project as parameterized so when I run my build, it asks for browser parameter. I want to select this parameter(for example firefox), so that it will change browser property in app.properties and will run the automation in Firefox.
Normally, when I change the browser property in app.properties in Intellij, my program runs with that browser. So there is nothing wrong with my program in that sense.
Is there a way to change app.properties with respect to my Jenkins build parameter and run the program with that configuration?
EDIT: I found the following solution:
Install surefire plugin.
Add a browser parameter.
In your property managing class, take browser parameter as
System.getProperty("browser");
From jenkins, configure a browser parameter
Invoke maven command: mvn test "-Dbrowser=${BROWSER}"
You can pass system properties to change configuration.
First you should configure your project to read both system properties and configuration file, where system properties will have higher priority. I'd recommend Apache Commons Composite Configuration. It can look like this:
CompositeConfiguration configuration = new CompositeConfiguration();
try {
configuration.addConfiguration(new SystemConfiguration());
configuration.addConfiguration(new PropertiesConfiguration("app.properties"));
} catch (ConfigurationException e) {
e.printStackTrace();
}
//Read your configuration values here
This way when you provide system property -Dbrowser=chrome it will override value from configuration file.
Secondly, you'll need to configure Jenkins job. Since you're passing a parameter you can use it in your build step definition:
mvn clean test -Dbroswer=${browser-param}
“The way parameters take effect is also different depending on the parameter type you choose ... String parameters are exposed as environment variables of the same name.”
https://wiki.jenkins.io/plugins/servlet/mobile?contentId=34930782#content/view/34930782
I'm trying to run a test suite that includes all of my unit tests across all of the (sub)modules of my project. In eclipse, this was done by simply running the xml test suite from the root of the project. If I try this in IDEA, I get a bunch of different errors depending on how I set up my Run Configuration.
Running my Suite as "In whole project", I get:
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'jdv.config.name' in string value "${jdv.config.name}"
Otherwise, TestNG's main class simply can't be found.
This persists even when I provide the project's application.properties file (where the aforementioned property is stored) in the Properties file field under the Parameters tab.
I have mutli-module Gradle application and I would to add properties which I've defined in gradle.properties to be available in application.properties of all my subprojects in /src/main/resources folder.
What I've alread tried is adding processResources plugin to subprojects section.
subprojects {
processResources {
expand(project.properties)
}
// ...
As an example, I've defined the following property in gradle.properties file:
appVersion='0.0.1-SNAPSHOT'
Now, I want it to be present in application.properties, so I've added a placeholder as stated here. So, my application.properties looks the following way:
app.version=${appVersion}
Later on, I would like to use it using Spring, e.g.:
#Value("${app.version}")
However, after the project is built, properties are not replaced, so I have no version value in application.properties and still ${appVersion} placeholder. Any suggestions how to do that?
I feel strongly that you should have separate folders for separate purposes. Therefore I suggest moving application.properties to src/main/filteredResources. Then:
import org.apache.tools.ant.filters.ReplaceTokens
processResources {
with copySpec {
from 'src/main/filteredResources'
filter(ReplaceTokens, tokens: project.properties)
}
}
The problem was not in the Gradle configuration, but how my Spring Boot application started. I was running main() method directly from Intellij IDEA, which didn't work for me well, probably some of the tasks were not executed properly.
So, the solution is to run ./gradlew bootRun command. This way properties are getting correctly replaced.
I have two properties files in src/main/resources application-dev.properties and application-prod.properties.
When I run my application with java -jar -Dspring.profiles.active=dev it picks the correct properties file and my application is running.
However when I use gradle -Dspring.profiles.active=dev test, the properties are not set from the specified profile.
I also created an application.properties file containing spring.profiles.active=dev.
When I compile and run with java -jar test.jar it works as expected but when I use gradle test the properties are ignored.
There are two JVMs involved, one running Gradle and one running your test. When you run gradle -Dspring.profiles.active=dev test you are setting a property on the JVM running Gradle, not the JVM running your test. Gradle doesn't automatically copy system properties from its JVM to the JVM it spawns. This topic at the Gradle forums explains how to set properties on the JVM running your test, but in short you'll need something like this in your build.gradle:
tasks.withType(Test) {
systemProperty 'spring.profiles.active', 'dev test'
}
If you've set the active profile as a system property you can use this:
tasks.withType(Test) {
systemProperty 'spring.profiles.active', System.getProperty('spring.profiles.active')
}
To copy all system properties:
tasks.withType(Test) {
systemProperties = System.getProperties()
}