Angular 15升级后,如何运行项目外部的单元测试?
Angular 15 共享代码测试用例运行方案
问题场景
项目结构:
- projects/app1
- projects/app2
- projects/app3
- shared(跨应用共享代码,未在angular.json中注册为独立项目)
升级到Angular 15后,原test.ts中用来加载外部测试用例的require.context被移除,之前靠这个函数让Karma识别shared文件夹下的.spec.ts文件,现在失效;尝试用符号链接也没解决问题。需要实现:将shared的测试用例挂到现有项目中运行,或单独运行,但不想为shared创建独立的Angular项目配置。
解决方法
方法1:将共享测试纳入现有项目的测试任务
直接修改目标项目(比如app1)的angular.json,在测试配置的文件列表中添加shared的路径:
找到projects.app1.architect.test.options.files节点,新增一行:
"../../shared/**/*.spec.ts"
修改完成后,运行ng test app1时,会自动包含shared目录下所有测试用例,无需修改test.ts。
方法2:单独运行共享测试用例
如果需要单独执行shared的测试,可以自定义Karma配置文件,比如创建karma.shared.conf.js,核心配置如下:
module.exports = function(config) { config.set({ basePath: '', frameworks: ['jasmine', '@angular-devkit/build-angular'], plugins: [ require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), require('@angular-devkit/build-angular/plugins/karma') ], files: [ // 复用现有项目的test.ts作为测试入口(保证Angular测试环境初始化) 'projects/app1/src/test.ts', // 指定共享代码的测试文件路径 '../../shared/**/*.spec.ts' ], preprocessors: { 'projects/app1/src/test.ts': ['@angular-devkit/build-angular'], '../../shared/**/*.spec.ts': ['@angular-devkit/build-angular'] }, // 其余配置可参考现有项目的karma.conf.js browsers: ['Chrome'], reporters: ['progress', 'kjhtml'], coverageReporter: { dir: require('path').join(__dirname, './coverage/shared'), subdir: '.', reporters: [ { type: 'html' }, { type: 'text-summary' } ] } }); };
执行命令启动测试:
ng test --karma-config=karma.shared.conf.js
这样就能独立运行shared的测试用例,无需为其创建Angular项目配置。
方法3:在test.ts中用动态导入替代require.context
如果不想修改angular.json,可以借助glob模块实现文件遍历和动态导入:
- 安装依赖:
npm install glob --save-dev
- 修改现有项目的test.ts:
import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; import * as glob from 'glob'; // 初始化Angular测试环境 getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting(), ); // 加载当前项目的测试用例 const context = require.context('./', true, /\.spec\.ts$/); context.keys().map(context); // 加载shared目录下的所有测试用例 const sharedSpecPaths = glob.sync('../../shared/**/*.spec.ts', { cwd: __dirname }); Promise.all(sharedSpecPaths.map(path => import(`../../${path}`)));
注意:这种方式需要确保Karma环境支持Node模块导入,若出现兼容性问题,优先选择方法1或2。
内容的提问来源于stack exchange,提问作者Andrei Fara
相关产品推荐
相关产品推荐

