GitHub Actions运行Angular Karma测试读取innerText失败本地通过
问题根因
报错本质是GitHub Actions跑Karma测试时用的无头浏览器默认视口尺寸太小,达不到Angular CDK里Breakpoints.Web的最小宽度要求(这个断点默认要求宽度≥1024px,而CI环境无头浏览器默认视口一般是800x600甚至更小)。
这时候模板里*ngIf="(isWeb | async)?.matches"的判断条件不成立,<mat-label>元素根本不会渲染到DOM里,querySelector('mat-label')直接返回null,读innerText自然抛空引用错误。
本地测试能过是因为本地开浏览器跑测试时,默认窗口大小刚好够Web断点阈值;其他querySelector用例不报错,是因为那些查询的元素没有加断点渲染控制,不管窗口多大都存在。
修复方案
- 方案1(最推荐,单元测试标准写法):测试环境Mock BreakpointObserver,强制返回Web匹配状态
这种写法完全不依赖浏览器视口尺寸,测试结果稳定,不会因为环境变化出问题。修改TestBed的provider配置,替换掉真实的BreakpointObserver实现:// 记得在文件顶部导入of操作符 import { of } from 'rxjs'; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [AdminComponent], imports: [RacsAdminModule, BrowserAnimationsModule], providers: [ { provide: BreakpointObserver, useValue: { observe: () => of({ matches: true, breakpoints: { [Breakpoints.Web]: true } }) } } ] }) .compileComponents(); fixture = TestBed.createComponent(AdminComponent); compiled = fixture.nativeElement; component = fixture.componentInstance; fixture.detectChanges(); // 等异步管道执行完、条件元素渲染完成再跑断言 await fixture.whenStable(); fixture.detectChanges(); }); - 方案2:修改Karma配置,给CI环境的无头浏览器固定大视口
如果不想Mock断点逻辑,想测真实的断点匹配行为,就改karma.conf.js里的自定义启动器配置,强制指定无头浏览器启动时的窗口尺寸:
之后在GitHub Actions的测试脚本里指定用这个启动器跑测试就行:customLaunchers: { ChromeHeadlessCI: { base: 'ChromeHeadless', flags: [ '--no-sandbox', '--disable-gpu', '--window-size=1920,1080' // 宽度设为1920,完全满足Web断点要求 ] } }ng test --browsers=ChromeHeadlessCI --watch=false
额外优化建议
原测试代码直接拿querySelector的返回值读属性,没有提前判断元素是否存在,出问题的时候报错信息很模糊。可以加一层前置断言,元素不存在时直接给出明确的报错:
tabs.forEach((tab: any) => { const labelEl = tab.querySelector('mat-label'); const iconEl = tab.querySelector('mat-icon'); expect(labelEl).withContext('tab标签文本元素未渲染').toBeTruthy(); expect(iconEl).withContext('tab图标元素未渲染').toBeTruthy(); const label: string = labelEl.innerText.trim(); const icon: string = iconEl.innerText.trim(); expect(label in tabLabelIconPairs).toBeTruthy(); expect(tabLabelIconPairs[label]).toBe(icon) });
内容的提问来源于stack exchange,提问作者Jason Michael Smit
相关产品推荐
相关产品推荐

