React Typescript tests not being detected

SonarQube 9.7.0.61563
Sonar dotnet scanner: latest

I am using the dotnet scanner to scan a solution containing lots of projects. One of those projects (WebsiteHost.csproj) contains both C# code and also a react javascript application (in Typescript) in a subfolder called ClientApp/src.

When scanned, only the Typescript code files are detected (eg. /builds/rocket/Boost/WebsiteHost/ClientApp/src/components/Alert.tsx), but the Typescript test file is not detected (eg. /builds/rocket/Boost/WebsiteHost/ClientApp/src/components/Alert.spec.tsx). I can see this in the scanned code folder in SonarQube.

The scanner shows me this output for this project:

INFO: Indexing files of module 'WebsiteHost'
INFO:   Base dir: /builds/rocket/boost/src/WebsiteHost
INFO:   Source paths: Configure.AppHost.cs, Controllers/ErrorController.cs, Control...
INFO:   Excluded sources: **/src/*UnitTests/**/*, **/src/*IntegrationTests/**/*, **/src/*UITests/**/*, **/src/TestResults/**/*, **/src/WebsiteHost/wwwroot/**/*, **/src/WebsiteHost/ClientApp/public/mockServiceWorker.js, **/src/WebsiteHost/ClientApp/src/**/*.spec.ts*, **/src/WebsiteHost/ClientApp/node_modules/**/*, **/src/*UnitTests/**/*, **/src/*IntegrationTests/**/*, **/src/*UITests/**/*, **/src/WebsiteHost/ClientApp/src/**/*.spec.ts*, **/src/WebsiteHost.UITests/**/*.cy.ts*
INFO:   Included tests: **/src/*UnitTests/**/*, **/src/*IntegrationTests/**/*, **/src/*UITests/**/*, **/src/WebsiteHost/ClientApp/src/**/*.spec.ts*, **/src/WebsiteHost.UITests/**/*.cy.ts*
INFO:   Excluded sources for coverage: **/src/*UnitTests/**/*, **/src/*IntegrationTests/**/*, **/src/*UITests/**/*, **/src/External.StubServices/**/*, **/src/*Testing.Common/**/*, **/src/**/Configure.AppHost.cs, **/src/**/Program.cs, **/src/Common/Annotations.cs, **/src/Common/Null*.cs, **/src/Common/*Exception.cs, **/src/Application.Interfaces/Resources/*.cs, **/src/Infrastructure.Api.Interfaces/ServiceOperations/**/*.cs, **/src/Infrastructure.Common/Recording/*.cs, **/src/Infrastructure.Storage*/*sitory.cs, **/src/WebsiteHost/ClientApp/src/**/*.spec.ts*, **/src/WebsiteHost/ClientApp/src/**/*.stories.ts*, **/src/WebsiteHost/ClientApp/coverage/**/*, **/src/WebsiteHost/ClientApp/public/**/*, **/src/WebsiteHost/ClientApp/tools/**/*, **/src/WebsiteHost/ClientApp/**/*.config.js

This seems to be be missing the output for Test paths property, even though, as you can see, we have included this path (**/src/WebsiteHost/ClientApp/src/**/*.spec.ts*) in the sonar.test.inclusions variable, and excluded it for the sonar.exclusions code property.

Then later in the scanner, when I try to upload the test execution report, that references these *.spec.tsx files, I see this error:

INFO: Sensor Generic Test Executions Report
INFO: Parsing /builds/rocket/boost/src/TestResults/react/sonar-generic.xml
INFO: Imported test execution data for 0 files
INFO: Test execution data ignored for 50 unknown files, including:
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/users/LoginPage.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/cars/new/components/CarForm/CarForm.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/users/RegisterPage.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/users/ResetPasswordPage.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/validators/password-strength.spec.ts

I am not certain this is the evidence I need to narrow the problem down, but the result is that my TypeScript tests are not being reported in the “Unit test” metric.

What do I have to do to fix this?

Hi,

Your actual analysis command and/or properties would be helpful here. With that, I could verify whether or not you’ve specified sonar.tests. (I suspect you haven’t.) You’ll need to define your tests location with sonar.tests before you can include/exclude anything from it.

 
Ann

Hey @ganncamp
Happy New Year, and thanks for looking at this for me.

Yes, here is my full command. Have redacted some of the paths for brevity, and removed variables for Code Coverage - as I understand that it has no impact on it):

SONAR_CODE_EXCLUSIONS: "\
      **/src/*UnitTests/**/*,\
      **/src/*IntegrationTests/**/*,\
      **/src/*UITests/**/*,\
      **/src/TestResults/**/*,\
      **/src/WebsiteHost/ClientApp/src/**/*.spec.ts*"
SONAR_TEST_INCLUSIONS: "\
      **/src/*UnitTests/**/*,\
      **/src/*IntegrationTests/**/*,\
      **/src/*UITests/**/*,\
      **/src/WebsiteHost/ClientApp/src/**/*.spec.ts*,\
      **/src/WebsiteHost.UITests/**/*.cy.ts*"
script:
    - apt-get install --yes openjdk-11-jre
    - dotnet tool install --global dotnet-sonarscanner
    - dotnet sonarscanner begin /k:"$SONAR_PROJECT" /d:sonar.login="$SONAR_TOKEN" /d:sonar.host.url="$SONAR_HOST_URL"
      /d:sonar.sources="src"
      /d:sonar.exclusions="$SONAR_CODE_EXCLUSIONS"
      /d:sonar.tests="src"
      /d:sonar.test.inclusions="$SONAR_TEST_INCLUSIONS"
      /d:sonar.cs.vstest.reportsPaths="${CI_PROJECT_DIR}/src/TestResults/csharp/*.trx"
      /d:sonar.testExecutionReportPaths="${CI_PROJECT_DIR}/src/TestResults/react/sonar-generic.xml,${CI_PROJECT_DIR}/src/TestResults/cypress/sonar-generic.xml"
      /d:sonar.verbose=false
    - dotnet build --configuration:$BUILD_CONFIGURATION src/$SOLUTIONNAME
    # No need to run tests here, just include the test and coverage reports created from all previous jobs
    - dotnet sonarscanner end /d:sonar.login="$SONAR_TOKEN"

Note: on my linux build server the full path to the code is /builds/rocket/boost/src, and this scanner command is run from the /builds/rocket/boost directory.

Hi,

Thanks for the detail. I’m not sure if this is about the use of the .NET scanner or if it’s on the TypeScript side, so I’ve flagged this for more expert attention.

 
Ann

Hello @jezzsantos,

it looks like you are including and excluding the same files at the same time. Can you try to run the analysis again with **/src/WebsiteHost/ClientApp/src/**/*.spec.ts* removed from SONAR_CODE_EXCLUSIONS?

If this doesn’t work, please send us the verbose logs for the begin step and the end step:

Share the Scanner for .NET verbose logs

  • Add /d:"sonar.verbose=true" to the…
    • SonarScanner.MSBuild.exe or dotnet sonarscanner begin command to get more detailed logs
      • For example: SonarScanner.MSBuild.exe begin /k:"MyProject" /d:"sonar.verbose=true"
    • “SonarQubePrepare” or “SonarCloudPrepare” task’s extraProperties argument if you are using Azure DevOps
      • For example:
        - task: SonarCloudPrepare@1
            inputs:
              SonarCloud: 'sonarcloud'
              organization: 'foo'
              scannerMode: 'MSBuild'
              projectKey: 'foo_sonar-scanning-someconsoleapp'
              projectName: 'sonar-scanning-someconsoleapp'
              extraProperties: |
                sonar.verbose=true
        
  • The important logs are in the END step (i.e. SonarQubeAnalyze / SonarCloudAnalyze / “Run Code Analysis”)

Share the msbuild detailed logs

MsBuild.exe /t:Rebuild /v:d

or

dotnet build -v:d

Thanks @Martin_Strecker,

Unfortunately, I can’t get all the verbose details you might need. Our GitLab runner reaches a maximum for logs, and then stops logging, so I don’t see the details you want to see:

Job's log exceeded limit of 4194304 bytes.
Job execution will continue but no more output will be collected.

Instead, I added: /d:sonar.log.level=DEBUG as that gives more details.

I removed ALL test code references from the SONAR_CODE_EXCLUSIONS as requested (including all C# test projects, my Cypress test project, and the React project). Those paths still exist in the SONAR_TEST_INCLUSIONS of course.

But still, I see this in the logs:

23:57:09.052 INFO: Sensor Generic Test Executions Report
23:57:09.052 INFO: Parsing /builds/rocket/boost/src/TestResults/react/sonar-generic.xml
23:57:09.106 INFO: Imported test execution data for 0 files
23:57:09.107 INFO: Test execution data ignored for 50 unknown files, including:
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/users/LoginPage.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/cars/new/components/CarForm/CarForm.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/users/RegisterPage.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/pages/users/ResetPasswordPage.spec.tsx
/builds/rocket/boost/src/WebsiteHost/ClientApp/src/validators/password-strength.spec.ts

I’m not able to get the fine detail you want. What should I be looking for next?

BTW: I copied my inclusions/exclusions approach as per your documentation.
If that approach is not recommended, I think that should be updated your docs.

Hey there @Martin_Strecker,

Sorry to bother, but is there something more we can do?
I need to resolve this issue.