Given a typical Angular CLI generated project, I'd like to run tests without the CLI (because big-business). I'd like to initiate karma using the Karma CLI. I am using Angular 16.
With my setup, I'm currently getting Incomplete: No specs found
Here's what I did:
- Generated a new Angular CLI project using
ng new - Created my own
karma-sans-ng.conf.jsthat does not include the Angular plugins, since they cannot be used outside the CLI. Most of it was copied from the karma config file generated using the CLI, but I had to make some tweaks, which I've annotated below. - Created my own
src/test.ts(since Angular no longer uses this :( ) - Modified
tsconfig.spec.jsonto includesrc/test.tsso I can initialize the test utils when running Karma - Compile with
tsc --project .\tsconfig.spec.json - Start Karma with
karma start .\karma-sans-ng.conf.js- no specs are found
karma-sans-ng.conf.js
const webpack = require('webpack');
module.exports = function (config) {
config.set({
basePath: '',
files: [
//include the test initialization and the actual tests
{
pattern: 'out-tsc/spec/test.js',
type: 'module'
},
{
pattern: 'out-tsc/**/*.spec.js',
type: 'module'
}
],
frameworks: ['jasmine'],
plugins: [
require('karma-webpack'), //needed to bundle everything for the browser
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
],
preprocessors: {
//more webpack stuff needed to bundle everything for the browser
'out-tsc/spec/test.js': [ 'webpack' ],
'out-tsc/**/*.spec.js': [ 'webpack' ]
},
webpack: {
plugins: [
//needed, or Karma gets errors about "process not defined"
new webpack.ProvidePlugin({
process: 'process/browser',
}),
]
},
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/testing-without-cli'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
browsers: ['Chrome'],
restartOnFileChange: true
});
};
test.ts
import 'zone.js';
import 'zone.js/testing';
import { TestBed, getTestBed } from "@angular/core/testing";
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing";
declare const __karma__:any;
declare const require: any;
__karma__.loaded = function(){};
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
const context = require.context('./', true, /\.spec\.ts$/);
//const context = require.context('./', true, /out-tsc\\spec\\.*.spec.js$/); //this doesn't work either
context.keys().map(context);
__karma__.start();
tsconfig.spec.ts
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]
},
"files": [
"src/test.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
In older versions of Angular, the test.ts file would be generated by the CLI, but this kind of stuff appears to now be managed in angular.json. Is my problem that the line that identifies the files is looking in the wrong place?