Commit 9b60febb authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

docs: clarify unit test and coverage reports configuration

parent 3802fefc
Loading
Loading
Loading
Loading
+72 −107
Original line number Diff line number Diff line
@@ -102,7 +102,24 @@ The next chapters presents some requirements related to your unit tests (using K
To be able to launch unit tests with Angular CLI, the Angular template requires a headless browser within the Docker
image `NG_CLI_IMAGE` (it is the case with the default image, [docker-ng-cli-karma](https://github.com/trion-development/docker-ng-cli-karma)).

#### 1. Using Karma
The following chapters detail the required configuration (depending on the unit testing framework you're using) in
order to integrate your [unit tests reports](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) and [code coverage reports](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) to GitLab.

Additionally, if also using SonarQube, you'll have to enable some extra reporters.

#### Unit testing with Karma

:information_source: At least up to Angular 16, Karma was the default unit testing framework.

Here is the required configuration if you're using [Karma](https://karma-runner.github.io/) as unit testing framework.

| Reporter                                                                                                                              | Needs `npm install` | Expected report file                | Usage                                                                                                                                                                  |
| ------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [karma-junit-reporter](https://github.com/karma-runner/karma-junit-reporter)                                                          | Yes                 | `reports/ng-test.xunit.xml`         | [GitLab unit tests integration](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) _(JUnit format)_                                                         |
| [karma-coverage text-summary reporter](https://github.com/karma-runner/karma-coverage?tab=readme-ov-file#advanced-multiple-reporters) | No                  | N/A _(stdout)_                      | [GitLab MR test coverage results](https://docs.gitlab.com/ee/ci/testing/code_coverage.html#view-code-coverage-results-in-the-mr) _(GitLab grabs coverage from stdout)_ |
| [karma-coverage cobertura reporter](https://github.com/karma-runner/karma-coverage?tab=readme-ov-file#advanced-multiple-reporters)    | No                  | `reports/ng-coverage.cobertura.xml` | [GitLab code coverage integration](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) _(Cobertura format)_                                        |
| [karma-sonarqube-execution-reporter](https://github.com/lisrec/karma-sonarqube-execution-reporter)                                    | Yes                 | `reports/ng-test.sonar.xml`         | [SonarQube unit tests integration](https://docs.sonarqube.org/latest/analysis/generic-test/) _(generic SonarQube format)_                                              |
| [karma-coverage lcovonly reporter](https://github.com/karma-runner/karma-coverage?tab=readme-ov-file#advanced-multiple-reporters)     | No                  | `reports/ng-coverage.lcov.info`     | [SonarQube code coverage integration](https://docs.sonarqube.org/latest/analysis/test-coverage/javascript-typescript-test-coverage/) _(JS/TS LCOV format)_             |

##### Code Coverage reports

@@ -131,6 +148,7 @@ the Angular template expects the following in your `karma.conf.js`:
   ```

   :warning: in case of multiple angular projects in the workspace, each project shall produce its coverage report in `reports/ng-coverage-<projectName>.cobertura.xml` (it can be in sub-folders but must follow the file name pattern).

3. Additionally, if using SonarQube, you may also want to generate [LCOV report](https://docs.sonarqube.org/latest/analysis/test-coverage/javascript-typescript-test-coverage/):

   ```js
@@ -150,7 +168,7 @@ the Angular template expects the following in your `karma.conf.js`:

##### Unit Tests reports

In order to be able to [integrate your test reports to GitLab](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportsjunit):
In order to be able to [integrate your test reports to GitLab](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html):

1. Add the [karma-junit-reporter](https://github.com/karma-runner/karma-junit-reporter) package as dev dependency:

@@ -211,25 +229,36 @@ Additionally, if using **SonarQube**, you may also want to generate [SonarQube g
   NG_TEST_ARGS: test --reporters junit,sonarqubeUnit`
   ```

#### 2. Using Jest
#### Unit testing with Jest

##### Unit Tests reports
:warning: be aware that Jest is not the default unit testing framework with Angular (up to Angular 16, Karma is the default unit testing framework).
The rest of the documentation assumes you've properly uninstalled Karma, and replaced it with Jest. Please refer to the appropriate documentation.

Here is the required configuration if you're using [Jest](https://jestjs.io/) as unit testing framework.

To be able to use Jest instead Karma, you first have to install some jest packages.
Then you have to create a dedicated jest config file, and to modify your angular.json and tsconfig.spec.json files to set Jest as test builder.
| Reporter                                                                                     | Needs `npm install` | Expected report file                | Usage                                                                                                                                                                  |
| -------------------------------------------------------------------------------------------- | ------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [jest-junit](https://github.com/jest-community/jest-junit)                                   | Yes                 | `reports/ng-test.xunit.xml`         | [GitLab unit tests integration](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) _(JUnit format)_                                                         |
| istanbul [text](https://istanbul.js.org/docs/advanced/alternative-reporters/#text)           | No                  | N/A _(stdout)_                      | [GitLab MR test coverage results](https://docs.gitlab.com/ee/ci/testing/code_coverage.html#view-code-coverage-results-in-the-mr) _(GitLab grabs coverage from stdout)_ |
| istanbul [cobertura](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) | No                  | `reports/ng-coverage.cobertura.xml` | [GitLab code coverage integration](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) _(Cobertura format)_                                        |
| [jest-sonar](https://github.com/sh33dafi/jest-sonar)                                         | Yes                 | `reports/ng-test.sonar.xml`         | [SonarQube unit tests integration](https://docs.sonarqube.org/latest/analysis/generic-test/) _(generic SonarQube format)_                                              |
| istanbul [lcovonly](https://istanbul.js.org/docs/advanced/alternative-reporters/#lcovonly)   | No                  | `reports/ng-coverage.lcov.info`     | [SonarQube code coverage integration](https://docs.sonarqube.org/latest/analysis/test-coverage/javascript-typescript-test-coverage/) _(JS/TS LCOV format)_             |

1. Add [jest](https://www.npmjs.com/package/jest), [jest-junit](https://github.com/jest-community/jest-junit#readme), [jest-preset-angular](https://www.npmjs.com/package/jest-preset-angular), [@types/jest](https://www.npmjs.com/package/@types/jest) and [@angular-builders/jest](https://www.npmjs.com/package/@angular-builders/jest) to your project as a dev dependency:
The following packages will have to be installed to your project as a dev dependencies: [jest](https://www.npmjs.com/package/jest), [jest-junit](https://github.com/jest-community/jest-junit#readme), [jest-preset-angular](https://www.npmjs.com/package/jest-preset-angular), [@types/jest](https://www.npmjs.com/package/@types/jest) and [@angular-builders/jest](https://www.npmjs.com/package/@angular-builders/jest)

```shell
npm install jest jest-preset-angular jest-junit @types/jest @angular-builders/jest --save-dev
```

2. Create the file `jest.config.js`, and add the following lines:
Then edit your `jest.config.js` configuration file with all the above reporters configured as expected:

```js
module.exports = {
  preset: "jest-preset-angular",
  globalSetup: "jest-preset-angular/global-setup",
  reporters: [
    "default",
    // 'jest-junit' to enable GitLab unit test report integration
    [
      "jest-junit",
      {
@@ -237,89 +266,27 @@ Then you have to create a dedicated jest config file, and to modify your angular
        outputName: "ng-test.xunit.xml",
      },
    ],
    // [OPTIONAL] only if using SonarQube
    // 'jest-sonar' to enable SonarQube unit test report integration
    [
      "jest-sonar",
      {
        outputDirectory: "reports",
        outputName: "ng-test.sonar.xml",
      },
    ],
  ],
     preset: "jest-preset-angular",
     globalSetup: "jest-preset-angular/global-setup",
   };
   ```

3. Open the `angular.json` file. Replace the test builder with jest, and convert "inlineStyleLanguage" option to array instead string:

   ```js
   "test": {
   // REPLACE: "builder": "@angular-devkit/build-angular:karma",
   // With:
     "builder": "@angular-builders/jest:run",
   ...
   // REPLACE: "inlineStyleLanguage": "scss",
   // With:
     "inlineStyleLanguage": ["scss"],
   ```

4. Open the `tsconfig.spec.json`file and replace the following line:

   ```js
   "types": [
     // REPLACE: "jasmine"
     // With:
     "jest"
   ]
   ```

##### Code Coverage reports

1. Modify the file `jest.config.js`, and add the following lines into the module.exports:

   ```js
  coverageDirectory: "reports",
  coverageReporters: [
    // 'text' to let GitLab grab coverage from stdout
    "text",
    // 'cobertura' to enable GitLab test coverage visualization
     ["cobertura",{file: 'ng-coverage.cobertura.xml'}],
    ["cobertura", { file: "ng-coverage.cobertura.xml" }],
    // [OPTIONAL] only if using SonarQube
    // 'lcovonly' to enable SonarQube test coverage reporting
     "lcovonly",
    ["lcovonly", { file: "ng-coverage.lcov.info" }],
  ],
   ```

2. Open the `angular.json` file and add the following line to the test options:

   ```js
   "ci": true,
   "coverage": true,
   ```

3. Finally, override the NG_TEST_ARGS from your `gitlab-ci.yml` variables:

   ```yaml
   NG_TEST_ARGS: test --coverage
   ```

Additionally, if using **SonarQube**, you may also want to generate [SonarQube generic test report](https://docs.sonarqube.org/latest/analysis/generic-test/):

1. Add [jest-sonar-reporter](https://www.npmjs.com/package/jest-sonar-reporter) to your project as a dev dependency:

   ```shell
   npm install --save-dev jest-sonar-reporter
   ```

2. In your `jest.config.js`, add this config line to the exports:

   ```js
   testResultsProcessor: "jest-sonar-reporter",
   ```

3. In your `jest.config.js`, add a jestSonar section to configure the name of the jest report.

   ```js
   "devDependencies": {
     ...
   },
   "jestSonar": {
     "reportPath": "reports",
     "reportFile": "ng-test.sonar.xml"
   }
};
```

### `ng-e2e` job
@@ -461,12 +428,10 @@ sonar.tests=app
sonar.test.inclusions=**/*.spec.ts

# tests report: generic format
# set the path configured with karma-sonarqube-execution-reporter
sonar.testExecutionReportPaths=reports/ng-test.sonar.xml
# lint report: TSLint JSON
sonar.typescript.tslint.reportPaths=reports/ng-lint.tslint.json
# coverage report: LCOV format
# set the path configured with karma-coverage-istanbul-reporter
sonar.typescript.lcov.reportPaths=reports/ng-coverage.lcov.info
```