angular / angular/angular-cli

V8 Coverage showing unexpected results

Đang mở
#32,836 11 bình luận 7 reaction 0 người được giao Xem trên GitHub
angular/build:unit-test area: @angular/build gemini-triaged
Ngôn ngữ chính
TypeScript
Star
27k
Fork
11.8k
Merge trung bình
14 giờ 23 phút
Pull request đã merge (30 ngày)
162

Mô tả

### 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:
Image

Similar from my project:
Image

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_

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu bằng cách tái hiện trên Angular 21 bằng `ng test --coverage`, sau đó kiểm tra `angular.json` và `vitest.config.ts` cùng với các thay đổi trong `app.ts` và `app.spec.ts`. So sánh báo cáo branch của V8 cho component rỗng với các include và exclude coverage đã cấu hình. Được coi là hoàn tất khi xác định được kết quả là hành vi V8 như mong đợi hay là lỗi trong unit-test builder của Angular CLI, kèm theo một trường hợp có thể tái hiện và tài liệu mô tả hành vi coverage mong đợi.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
angular, typescript
Lĩnh vực
build-system, testing-qa
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.