V8 Coverage showing unexpected results
- Langage dominant
- TypeScript
- Étoiles
- 27k
- Forks
- 11.8k
- Merge moyen
- 14 h 23 min
- PR mergées (30 j)
- 162
Description
### Which @angular/* package(s) are the source of the bug?
Don't known / other
### Is this a regression?
No
### Description
I'm in the process of migrating from jasmine/karma with istanbul coverage to vitest with v8 coverage. I'm currently migrating around 2500 unit tests. With Istanbul I had over 95% coverage across statements, branches, functions and lines. With vitest I'm seeing lower coverage, mainly on the branches with 90%.
I've noticed that even empty classes (template only) show 90% branch coverage (9/10).
A minimal reproduction:
* Create a new Angular 21 application: `ng new ng21`
* Install v8 coverage `npm i --save-dev @vitest/coverage-v8`
* Remove the protected title variable from app.ts `-- protected readonly title = signal('ng21');`
* Remove the `should render title` test from app.spec.ts
* Run `ng test --coverage`
This is the coverage I see:
Similar from my project:
with the spec file as:
```
import { TestBed } from '@angular/core/testing';
import { HeaderComponent } from './header.component';
import { HeaderComponent as ClsHeaderComponent, TenantDropdownComponent } from '@cls/ui-util';
import { MockComponent } from '@cls/ui-util/testing';
import { SearchComponent } from '../../schedule/components/search/search.component';
describe('HeaderComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HeaderComponent],
providers: []
})
.overrideComponent(HeaderComponent, {
remove: { imports: [SearchComponent, ClsHeaderComponent, TenantDropdownComponent] },
add: {
imports: [
MockComponent({ selector: 'app-search' }) as any,
MockComponent({ selector: 'cls-header' }) as any,
MockComponent({ selector: 'cls-tenant-dropdown' }) as any
]
}
})
.compileComponents();
});
function setup() {
const fixture = TestBed.createComponent(HeaderComponent);
return {
fixture,
app: fixture.componentInstance,
compiled: fixture.debugElement.nativeElement
};
}
it('should create the app', () => {
const { app } = setup();
expect(app).toBeTruthy();
});
});
```
angular.json
```
"test": {
"builder": "@angular/build:unit-test",
"options": {
"browsers": ["chromium"],
"buildTarget": "admin-ui:build",
"headless": true,
"tsConfig": "./tsconfig.spec.json",
"runnerConfig": "./vitest.config.ts",
"coverage": true,
"coverageInclude": ["src/app/**/*.ts"],
"coverageExclude": ["index.ts", "main.ts", "polyfills.ts", "**/*.routes.ts", "**/*.model.ts", "**/*.interface.ts"],
"coverageReporters": ["text", "html", "lcov"],
"coverageThresholds": {
"statements": 90,
"branches": 90,
"functions": 90,
"lines": 90
}
}
}
```
vitest.config.ts
```
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['src/test-setup.ts'],
restoreMocks: true,
coverage: {
provider: 'v8'
},
browser: {
screenshotFailures: false
}
}
});
```
Have I misconfigured something? Do I have an incorrect assumption of v8 coverage or is there an issue here?
### Please provide a link to a minimal reproduction of the bug
_No response_
### Please provide the exception or error you saw
```true
```
### Please provide the environment you discovered this bug in (run `ng version`)
```true
Angular CLI : 21.2.3
Angular : 21.2.5
Node.js : 22.13.1
Package Manager : npm 10.9.2
Operating System : darwin arm64
┌───────────────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────────────┼───────────────────┼───────────────────┤
│ @angular/animations │ 21.2.5 │ ~21.2.0 │
│ @angular/build │ 21.2.3 │ ^21.2.0 │
│ @angular/cdk │ 21.2.3 │ ~21.2.0 │
│ @angular/cli │ 21.2.3 │ ~21.2.0 │
│ @angular/common │ 21.2.5 │ ~21.2.0 │
│ @angular/compiler │ 21.2.5 │ ~21.2.0 │
│ @angular/compiler-cli │ 21.2.5 │ ~21.2.0 │
│ @angular/core │ 21.2.5 │ ~21.2.0 │
│ @angular/forms │ 21.2.5 │ ~21.2.0 │
│ @angular/language-service │ 21.2.5 │ ~21.2.0 │
│ @angular/platform-browser │ 21.2.5 │ ~21.2.0 │
│ @angular/platform-browser-dynamic │ 21.2.5 │ ~21.2.0 │
│ @angular/router │ 21.2.5 │ ~21.2.0 │
│ rxjs │ 7.8.2 │ ~7.8.2 │
│ typescript │ 5.9.3 │ ~5.9.3 │
│ vitest │ 4.1.0 │ ^4.0.18 │
│ zone.js │ 0.15.1 │ ~0.15.0 │
└───────────────────────────────────┴───────────────────┴──────────────────
```
### Anything else?
_No response_
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par reproduire le problème avec Angular 21 en utilisant `ng test --coverage`, puis examinez `angular.json` et `vitest.config.ts` ainsi que les modifications apportées à `app.ts` et `app.spec.ts`. Comparez le rapport de branche V8 du composant vide avec les inclusions et exclusions de coverage configurées. Le travail est terminé lorsqu’il est établi si le résultat correspond au comportement attendu de V8 ou à un défaut du builder de tests unitaires d’Angular CLI, avec un cas reproductible et le comportement attendu de la coverage documenté.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- angular, typescript
- Domaine
- build-system, testing-qa
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100