How do SonarCloud properties work in relation to each other?

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