docs: Update testing guides for Vitest and Karma

This commit updates the testing documentation to reflect the introduction of Vitest as the default test runner, while ensuring Karma testing instructions are still available.

Key changes include:
- Adding a new guide for "Testing with Karma" (`guide/testing/karma.md`).
- Updating the "Code Coverage" guide (`guide/testing/code-coverage.md`) to use `angular.json` for coverage enforcement and referencing Vitest documentation.
- Modifying the "Testing Overview" guide (`guide/testing/overview.md`) to introduce Vitest as the default, update `ng test` output examples, and link to the new Karma guide.
- Updating navigation data to include the new Karma testing guide.
This commit is contained in:
Charles Lyding 2025-10-30 16:56:29 -04:00 committed by Andrew Kushnir
parent c91d8203a2
commit 2a2397acc4
6 changed files with 279 additions and 78 deletions

View file

@ -526,6 +526,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/testing/code-coverage',
contentPath: 'guide/testing/code-coverage',
},
{
label: 'Testing with Karma and Jasmine',
path: 'guide/testing/karma',
contentPath: 'guide/testing/karma',
},
{
label: 'Testing services',
path: 'guide/testing/services',

View file

@ -5,52 +5,59 @@ Code coverage reports show you any parts of your code base that might not be pro
To generate a coverage report run the following command in the root of your project.
<docs-code language="shell">
ng test --no-watch --code-coverage
</docs-code>
```shell
ng test --no-watch --coverage
```
When the tests are complete, the command creates a new `/coverage` directory in the project.
Open the `index.html` file to see a report with your source code and code coverage values.
If you want to create code-coverage reports every time you test, set the following option in the Angular CLI configuration file, `angular.json`:
<docs-code language="json">
"test": {
"options": {
"codeCoverage": true
```json
{
"projects": {
"your-project-name": {
"architect": {
"test": {
"options": {
"coverage": true
}
}
}
}
}
}
</docs-code>
```
## Code coverage enforcement
The code coverage percentages let you estimate how much of your code is tested.
If your team decides on a set minimum amount to be unit tested, enforce this minimum with the Angular CLI.
If your team decides on a set minimum amount to be unit tested, you can enforce this minimum directly in your Angular CLI configuration.
For example, suppose you want the code base to have a minimum of 80% code coverage.
To enable this, open the [Karma](https://karma-runner.github.io) test platform configuration file, `karma.conf.js`, and add the `check` property in the `coverageReporter:` key.
To enable this, open the `angular.json` file and add the `coverageThresholds` option to your test configuration:
<docs-code language="javascript">
coverageReporter: {
dir: require('path').join(__dirname, './coverage/<project-name>'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
],
check: {
global: {
statements: 80,
branches: 80,
functions: 80,
lines: 80
```json
{
"projects": {
"your-project-name": {
"architect": {
"test": {
"options": {
"coverage": true,
"coverageThresholds": {
"statements": 80,
"branches": 80,
"functions": 80,
"lines": 80
}
}
}
}
}
}
}
</docs-code>
```
HELPFUL: Read more about creating and fine tuning Karma configuration in the [testing guide](guide/testing#configuration).
The `check` property causes the tool to enforce a minimum of 80% code coverage when the unit tests are run in the project.
Read more on coverage configuration options in the [karma coverage documentation](https://github.com/karma-runner/karma-coverage/blob/master/docs/configuration.md).
Now, when you run `ng test`, the tool will throw an error if the coverage drops below 80%.

View file

@ -2,7 +2,9 @@
If your tests aren't working as you expect them to, you can inspect and debug them in the browser.
Debug specs in the browser in the same way that you debug an application.
NOTE: This guide describes debugging with the Karma test runner.
To debug an application with the Karma test runner:
1. Reveal the Karma browser window.
See [Set up testing](guide/testing#set-up-testing) if you need help with this step.

View file

@ -0,0 +1,182 @@
# Testing with Karma and Jasmine
While [Vitest](https://vitest.dev) is the default test runner for new Angular projects, [Karma](https://karma-runner.github.io) is still a supported and widely used test runner. This guide provides instructions for testing your Angular application using the Karma test runner with the [Jasmine](https://jasmine.github.io) testing framework.
## Setting Up Karma and Jasmine
You can set up Karma and Jasmine for a new project or add it to an existing one.
### For New Projects
To create a new project with Karma and Jasmine pre-configured, run the `ng new` command with the `--test-runner=karma` option:
```shell
ng new my-karma-app --test-runner=karma
```
### For Existing Projects
To add Karma and Jasmine to an existing project, follow these steps:
1. **Install the necessary packages:**
<docs-code-multifile>
<docs-code header="pnpm" language="shell">
pnpm add -D karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter jasmine-core @types/jasmine
</docs-code>
<docs-code header="npm" language="shell">
npm install --save-dev karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter jasmine-core @types/jasmine
</docs-code>
<docs-code header="yarn" language="shell">
yarn add --dev karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter jasmine-core @types/jasmine
</docs-code>
</docs-code-multifile>
2. **Configure the test runner in `angular.json`:**
In your `angular.json` file, find the `test` target and set the `runner` option to `karma`:
```json
{
// ...
"projects": {
"your-project-name": {
// ...
"architect": {
"test": {
"builder": "@angular/build:unit-test",
"options": {
"runner": "karma",
// ... other options
}
}
}
}
}
}
```
3. **Update `tsconfig.spec.json` for Jasmine types:**
To ensure TypeScript recognizes global testing functions like `describe` and `it`, add `"jasmine"` to the `types` array in your `tsconfig.spec.json`:
```json
{
// ...
"compilerOptions": {
// ...
"types": [
"jasmine"
]
},
// ...
}
```
## Running Tests
Once your project is configured, run the tests using the [`ng test`](cli/test) command:
```shell
ng test
```
The `ng test` command builds the application in _watch mode_ and launches the [Karma test runner](https://karma-runner.github.io).
The console output looks like below:
```shell
02 11 2022 09:08:28.605:INFO [karma-server]: Karma v6.4.1 server started at http://localhost:9876/
02 11 2022 09:08:28.607:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
02 11 2022 09:08:28.620:INFO [launcher]: Starting browser Chrome
02 11 2022 09:08:31.312:INFO [Chrome]: Connected on socket -LaEYvD2R7MdcS0-AAAB with id 31534482
Chrome: Executed 3 of 3 SUCCESS (0.193 secs / 0.172 secs)
TOTAL: 3 SUCCESS
```
The test output is displayed in the browser using [Karma Jasmine HTML Reporter](https://github.com/dfederm/karma-jasmine-html-reporter).
<img alt="Jasmine HTML Reporter in the browser" src="assets/images/guide/testing/initial-jasmine-html-reporter.png">
Click on a test row to re-run just that test or click on a description to re-run the tests in the selected test group ("test suite").
Meanwhile, the `ng test` command is watching for changes. To see this in action, make a small change to a source file and save. The tests run again, the browser refreshes, and the new test results appear.
## Configuration
The Angular CLI takes care of Jasmine and Karma configuration for you. It constructs the full configuration in memory, based on options specified in the `angular.json` file.
### Customizing Karma Configuration
If you want to customize Karma, you can create a `karma.conf.js` by running the following command:
```shell
ng generate config karma
```
HELPFUL: Read more about Karma configuration in the [Karma configuration guide](http://karma-runner.github.io/6.4/config/configuration-file.html).
### Setting the Test Runner in `angular.json`
To explicitly set Karma as the test runner for your project, locate the `test` target in your `angular.json` file and set the `runner` option to `karma`:
```json
{
// ...
"projects": {
"your-project-name": {
// ...
"architect": {
"test": {
"builder": "@angular/build:unit-test",
"options": {
"runner": "karma",
// ... other options
}
}
}
}
}
}
```
## Code coverage enforcement
To enforce a minimum code coverage level, you can use the `check` property in the `coverageReporter` section of your `karma.conf.js` file.
For example, to require a minimum of 80% coverage:
```javascript
coverageReporter: {
dir: require('path').join(__dirname, './coverage/<project-name>'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
],
check: {
global: {
statements: 80,
branches: 80,
functions: 80,
lines: 80
}
}
}
```
This will cause the test run to fail if the specified coverage thresholds are not met.
## Testing in continuous integration
To run your Karma tests in a CI environment, use the following command:
```shell
ng test --no-watch --no-progress --browsers=ChromeHeadless
```
NOTE: The `--no-watch` and `--no-progress` flags are crucial for Karma in CI environments to ensure tests run once and exit cleanly. The `--browsers=ChromeHeadless` flag is also essential for running tests in a browser environment without a graphical interface.

View file

@ -2,61 +2,58 @@
Testing your Angular application helps you check that your application is working as you expect.
NOTE: While Vitest is the default test runner, Karma is still fully supported. For information on testing with Karma, see the [Karma testing guide](guide/testing/karma).
## Set up testing
The Angular CLI downloads and installs everything you need to test an Angular application with [Jasmine testing framework](https://jasmine.github.io).
The Angular CLI downloads and installs everything you need to test an Angular application with the [Vitest testing framework](https://vitest.dev).
The project you create with the CLI is immediately ready to test.
Just run the [`ng test`](cli/test) CLI command:
<docs-code language="shell">
```shell
ng test
</docs-code>
```
The `ng test` command builds the application in _watch mode_,
and launches the [Karma test runner](https://karma-runner.github.io).
The `ng test` command builds the application in _watch mode_ and launches the [Vitest test runner](https://vitest.dev).
The console output looks like below:
<docs-code language="shell">
```shell
02 11 2022 09:08:28.605:INFO [karma-server]: Karma v6.4.1 server started at http://localhost:9876/
02 11 2022 09:08:28.607:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
02 11 2022 09:08:28.620:INFO [launcher]: Starting browser Chrome
02 11 2022 09:08:31.312:INFO [Chrome]: Connected on socket -LaEYvD2R7MdcS0-AAAB with id 31534482
Chrome: Executed 3 of 3 SUCCESS (0.193 secs / 0.172 secs)
TOTAL: 3 SUCCESS
✓ src/app/app.component.spec.ts (3)
✓ AppComponent should create the app
✓ AppComponent should have as title 'my-app'
✓ AppComponent should render title
Test Files 1 passed (1)
Tests 3 passed (3)
Start at 18:18:01
Duration 2.46s (transform 615ms, setup 2ms, collect 2.21s, tests 5ms)
</docs-code>
The last line of the log shows that Karma ran three tests that all passed.
The test output is displayed in the browser using [Karma Jasmine HTML Reporter](https://github.com/dfederm/karma-jasmine-html-reporter).
<img alt="Jasmine HTML Reporter in the browser" src="assets/images/guide/testing/initial-jasmine-html-reporter.png">
Click on a test row to re-run just that test or click on a description to re-run the tests in the selected test group \("test suite"\).
```
Meanwhile, the `ng test` command is watching for changes.
To see this in action, make a small change to `app.component.ts` and save.
The tests run again, the browser refreshes, and the new test results appear.
To see this in action, make a small change to `app.ts` and save.
The tests run again, and the new test results appear in the console.
## Configuration
The Angular CLI takes care of Jasmine and Karma configuration for you. It constructs the full configuration in memory, based on options specified in the `angular.json` file.
The Angular CLI takes care of the Vitest configuration for you. It constructs the full configuration in memory, based on options specified in the `angular.json` file.
If you want to customize Karma, you can create a `karma.conf.js` by running the following command:
If you want to customize Vitest, you can create a `vitest-base.config.ts` by running the following command:
<docs-code language="shell">
```shell
ng generate config karma
ng generate config vitest
</docs-code>
```
HELPFUL: Read more about Karma configuration in the [Karma configuration guide](http://karma-runner.github.io/6.4/config/configuration-file.html).
IMPORTANT: Using a custom `vitest-base.config.ts` provides powerful customization options. However, the Angular team does not provide support for the specific contents of this file or for any third-party plugins used within it.
HELPFUL: Read more about Vitest configuration in the [Vitest configuration guide](https://vitest.dev/config/).
### Other test frameworks
@ -65,12 +62,12 @@ Each library and runner has its own distinctive installation procedures, configu
### Test file name and location
Inside the `src/app` folder the Angular CLI generated a test file for the `AppComponent` named `app.component.spec.ts`.
Inside the `src/app` folder the Angular CLI generated a test file for the `App` component named `app.spec.ts`.
IMPORTANT: The test file extension **must be `.spec.ts`** so that tooling can identify it as a file with tests \(also known as a _spec_ file\).
IMPORTANT: The test file extension **must be `.spec.ts` or `.test.ts`** so that tooling can identify it as a file with tests \(also known as a _spec_ file\).
The `app.component.ts` and `app.component.spec.ts` files are siblings in the same folder.
The root file names \(`app.component`\) are the same for both files.
The `app.ts` and `app.spec.ts` files are siblings in the same folder.
The root file names \(`app`\) are the same for both files.
Adopt these two conventions in your own projects for _every kind_ of test file.
@ -103,11 +100,19 @@ One of the best ways to keep your project bug-free is through a test suite, but
Continuous integration \(CI\) servers let you set up your project repository so that your tests run on every commit and pull request.
To test your Angular CLI application in Continuous integration \(CI\) run the following command:
To test your Angular application in a continuous integration (CI) server, you can typically run the standard test command:
<docs-code language="shell">
ng test --no-watch --no-progress --browsers=ChromeHeadless
</docs-code>
```shell
ng test
```
Most CI servers set a `CI=true` environment variable, which `ng test` detects. This automatically runs your tests in the appropriate non-interactive, single-run mode.
If your CI server does not set this variable, or if you need to force single-run mode manually, you can use the `--no-watch` and `--no-progress` flags:
```shell
ng test --no-watch --no-progress
```
## More information on testing

View file

@ -57,20 +57,20 @@ Call `TestBed` methods _within_ a `beforeEach()` to ensure a fresh start before
Here are the most important static methods, in order of likely utility.
| Methods | Details |
| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `configureTestingModule` | The testing shims \(`karma-test-shim`, `browser-test-shim`\) establish the [initial test environment](guide/testing) and a default testing module. The default testing module is configured with basic declaratives and some Angular service substitutes that every tester needs. <br /> Call `configureTestingModule` to refine the testing module configuration for a particular set of tests by adding and removing imports, declarations \(of components, directives, and pipes\), and providers. |
| `compileComponents` | Compile the testing module asynchronously after you've finished configuring it. You **must** call this method if _any_ of the testing module components have a `templateUrl` or `styleUrls` because fetching component template and style files is necessarily asynchronous. See [compileComponents](guide/testing/components-scenarios#calling-compilecomponents). <br /> After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec. |
| `createComponent<T>` | Create an instance of a component of type `T` based on the current `TestBed` configuration. After calling `createComponent`, the `TestBed` configuration is frozen for the duration of the current spec. |
| `overrideModule` | Replace metadata for the given `NgModule`. Recall that modules can import other modules. The `overrideModule` method can reach deeply into the current testing module to modify one of these inner modules. |
| `overrideComponent` | Replace metadata for the given component class, which could be nested deeply within an inner module. |
| `overrideDirective` | Replace metadata for the given directive class, which could be nested deeply within an inner module. |
| `overridePipe` | Replace metadata for the given pipe class, which could be nested deeply within an inner module. |
| Methods | Details |
| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `configureTestingModule` | The testing shims establish the [initial test environment](guide/testing) and a default testing module. The default testing module is configured with basic declaratives and some Angular service substitutes that every tester needs. <br /> Call `configureTestingModule` to refine the testing module configuration for a particular set of tests by adding and removing imports, declarations \(of components, directives, and pipes\), and providers. |
| `compileComponents` | Compile the testing module asynchronously after you've finished configuring it. You **must** call this method if _any_ of the testing module components have a `templateUrl` or `styleUrls` because fetching component template and style files is necessarily asynchronous. See [compileComponents](guide/testing/components-scenarios#calling-compilecomponents). <br /> After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec. |
| `createComponent<T>` | Create an instance of a component of type `T` based on the current `TestBed` configuration. After calling `createComponent`, the `TestBed` configuration is frozen for the duration of the current spec. |
| `overrideModule` | Replace metadata for the given `NgModule`. Recall that modules can import other modules. The `overrideModule` method can reach deeply into the current testing module to modify one of these inner modules. |
| `overrideComponent` | Replace metadata for the given component class, which could be nested deeply within an inner module. |
| `overrideDirective` | Replace metadata for the given directive class, which could be nested deeply within an inner module. |
| `overridePipe` | Replace metadata for the given pipe class, which could be nested deeply within an inner module. |
|
`inject` | Retrieve a service from the current `TestBed` injector. The `inject` function is often adequate for this purpose. But `inject` throws an error if it can't provide the service. <br /> What if the service is optional? <br /> The `TestBed.inject()` method takes an optional second parameter, the object to return if Angular can't find the provider \(`null` in this example\): <docs-code header="app/demo/demo.testbed.spec.ts" path="adev/src/content/examples/testing/src/app/demo/demo.testbed.spec.ts" visibleRegion="testbed-get-w-null"/> After calling `TestBed.inject`, the `TestBed` configuration is frozen for the duration of the current spec. |
|
`initTestEnvironment` | Initialize the testing environment for the entire test run. <br /> The testing shims \(`karma-test-shim`, `browser-test-shim`\) call it for you so there is rarely a reason for you to call it yourself. <br /> Call this method _exactly once_. To change this default in the middle of a test run, call `resetTestEnvironment` first. <br /> Specify the Angular compiler factory, a `PlatformRef`, and a default Angular testing module. Alternatives for non-browser platforms are available in the general form `@angular/platform-<platform_name>/testing/<platform_name>`. |
`initTestEnvironment` | Initialize the testing environment for the entire test run. <br /> The testing shims call it for you so there is rarely a reason for you to call it yourself. <br /> Call this method _exactly once_. To change this default in the middle of a test run, call `resetTestEnvironment` first. <br /> Specify the Angular compiler factory, a `PlatformRef`, and a default Angular testing module. Alternatives for non-browser platforms are available in the general form `@angular/platform-<platform_name>/testing/<platform_name>`. |
| `resetTestEnvironment` | Reset the initial test environment, including the default testing module. |
A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods.