Search code examples
angularjestjssonarqubenomachine-nx

Nx, Angular, Jest and Sonar


I'm looking for a recipe to use with an Nx (13.4.1) Angular (13.1) Workspace using Jest to run unit tests. I want to generate and publish unit test run results and coverage reports to SonarQube server individually for each library.


Solution

  • Create Nx Angular Workspace with Multiple Angular Libraries https://nx.dev/angular

    (for this recipe, library folder structure must be of the form ./libs/my-scope/my-library)

    (Optional) Create Local SonarQube Server via Docker

    docker run -d --name sonarqube -p 9000:9000 sonarqube:latest
    

    (change credentials from admin / admin to something else) https://www.sonarqube.org/features/deployment/

    Setup SonarQube Scanner

    Quick Start Article - Setup SonarQube for Angular https://codeburst.io/setup-sonarqube-for-angular-application-locally-in-three-easy-steps-8f31e339ac19

    npm install -g sonar-scanner
    

    Modify jest.config.js in each library

    module.exports = {
      displayName: 'my-scope-my-library',
      preset: '../../../jest.preset.js',
      setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
      globals: {
        'ts-jest': {
          tsconfig: '<rootDir>/tsconfig.spec.json',
          stringifyContentPathRegex: '\\.(html|svg)$',
        },
      },
      coverageReporters: ["clover", "json", "lcov", "text", "text-summary"],
      collectCoverage: true,
      testResultsProcessor: "jest-sonar-reporter",
      coverageDirectory: '../../../coverage/libs/my-scope/my-library',
      transform: {
        '^.+.(ts|mjs|js|html)$': 'jest-preset-angular',
      },
      transformIgnorePatterns: ['node_modules/(?!.*.mjs$)'],
      transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
      snapshotSerializers: [
        'jest-preset-angular/build/serializers/no-ng-attributes',
        'jest-preset-angular/build/serializers/ng-snapshot',
        'jest-preset-angular/build/serializers/html-comment',
      ],
    };
    

    (these three lines were added)

      coverageReporters: ["clover", "json", "lcov", "text", "text-summary"],
      collectCoverage: true,
      testResultsProcessor: "jest-sonar-reporter",
    

    Install jest-sonar-reporter npm package

    npm install --save-dev jest-sonar-scanner
    

    Create sonar-project.properties in workspace root

    sonar.projectBaseDir=.
    sonar.sourceEncoding=UTF-8
    sonar.exclusions=
    sonar.inclusions=**/*.ts, **/*.scss, **/*.html
    sonar.test.inclusions=**/*.spec.ts
    

    Create bash script to loop through the scopes and libraries

    scopes=$(ls libs)
    for scope in $(echo $scopes); do
      libs=$(ls libs/$scope)
      for lib in $(echo $libs); do
        echo "$scope -- $lib"
        nx test "$scope-$lib" --code-coverage || true
        mv test-report.xml coverage/libs/$scope/$lib
    
        # run sonar scanner to anaylize and publish results
        sonar-scanner \
          -Dsonar.login=$SONAR_LOGIN \
          -Dsonar.host.url=$SONAR_HOST_URL \
          -Dsonar.projectKey="optional-prefix-$scope-$lib" \
          -Dsonar.sources=libs/$scope/$lib/src \
          -Dsonar.tests=libs/$scope/$lib/src \
          -Dsonar.javascript.lcov.reportPaths=coverage/libs/$scope/$lib/lcov.info \
          -Dsonar.testExecutionReportPaths=coverage/libs/$scope/$lib/test-report.xml
    
      done
    done