How do SonarCloud properties work in relation to each other?

Hello all,

I’m new to SonarCloud and just wanted a little further clarification on how the properties listed in the sonar-project.properties file works. In particular, how does sonar.tests work in relation to sonar.test.inclusions. We came across an issue with the coverage that we fixed but we’re not 100% sure why that fixed it.

Here is an example. We have the following directory structure:

src/[feature]/components
src/[feature]/utils
src/[feature]/test
src/[feature]/index.ts

When we included the following properties into our sonar-project.properties, the code coverage was not working correctly:

sonar.sources=src
sonar.tests=test,src/**/test
sonar.test.inclusions=test,src/**/test

To fix the issue we used the following:

sonar.sources=src
sonar.tests=test,src
sonar.test.inclusions=test,src/**/test

Not exactly sure why that fixed our issue, and not sure if both lines are needed. Would love some help understanding why.

Thank you!
Cherly

Another side observation, we noticed that the UI (General Settings > Analysis Scope) did not reflect what was set in the properties file. We ended up clearing everything in the UI and just used the property file.

Hello @cyeung,

Welcome to the SonarSource community :wave:, I hope you’ll enjoy it.
The relationship between sonar.tests and sonar.test.inclusions is the following:

  • sonar.test define the list of top level directories where the Scanner will search recursively for tests files
  • Within the directories defined by sonar.tests, sonar.test.inclusion will define the subset of files that will be considered as tests

Your problem is that, in the first case, you used glob patterns to define the test directories as src/**/test. The test value is also considered, but will match no files since all the test files are under the toplevel src directory not under a top level test directory
See https://sonarcloud.io/documentation/analysis/analysis-parameters/ on how you can specify sonar.tests

When no tests files are found, all files are considered as sources, and as such are counted for the coverage, and therefore your coverage is negatively affected (because test files obviously have 0% coverage).

So for you the right way to configure you scan is:

# Define same root directory for main sources and tests
sonar.sources=src
sonar.tests=src
# Only take into account files in a test directory for test files
sonar.test.inclusions=src/**/test/**/*
# Exclude files in a test directory from the main source files
sonar.exclusions=src/**/test/**/*

It’s a good practice to make sure that all files selected as main sources and all files selected as tests files represent 2 disjoint file sets. That’s why I added the sonar.exclusions property.
I am even surprised that your 2nd configuration did work. It was almost correct except that you did not exclude the test files from the sources, and I would have expected this to break the analysis.

Hope this clarifies.

Olivier

Hello @cyeung,

You may also want to have a look here: at Narrowing the Focus in the docs, for more details.

Thank you @OlivierK for the awesome explanation. :clap:
This helps clarify what we were seeing.