Replace Karma with Vitest - #57
Open
hupponen wants to merge 4 commits into
Open
Conversation
Vitest runs the tests in Node without a browser, so they can run in containers and CI where Karma's Chrome is not available. Run them with npm run test:unit. Delete the eight component specs that only checked that the component can be created. They were generated by the Angular CLI and never given the services the components inject, so TestBed.createComponent() would have thrown. Angular's TestBed support comes with the Angular 20 unit-test builder, which also uses Vitest. Also delete a disabled test that expected getItemsByIndexes() to throw for a non-array input. It asserted a return value instead, and lodash map() returns an empty array for undefined, so the test could never pass.
Karma hasn't been usable for a long time: karma.conf.js requires karma-coverage-istanbul-reporter, which isn't installed, and src/test.ts imports zone.js/dist paths that no longer exist. Tests run with Vitest now, so remove the config, the entry point, the Angular test target and the Karma and Jasmine dependencies. test/unit-tests.html was an even older SystemJS and Jasmine runner, with test/liteserver-test-config.json only pointing at it. Removing Karma also removed lodash from node_modules, which revealed that session.resource.ts and datasetmodal.service.ts imported 'lodash' even though only 'lodash-es' is declared as a dependency. They resolved to the copy that Karma happened to bring in. Import chunk() and cloneDeep() from lodash-es like the rest of the code does.
The e2e target pointed to e2e/protractor.conf.js, but that directory doesn't exist and protractor isn't a dependency, so 'ng e2e' could not run. Angular CLI dropped Protractor support years ago.
Vitest only transpiles, it doesn't check types, so 'tsc -p tsconfig.json --noEmit' is what type checks the specs. The root tsconfig has no include, so it already covers them. Vitest ships .d.ts files that reference exports-map subpaths, which the 'node' module resolution cannot follow. Use 'bundler' resolution instead, which resolves them and is the default of new Angular projects. That keeps the type checking of dependencies on, unlike skipLibCheck. tsconfig.spec.json is not needed for this and nothing read it anymore: the Angular test target that used it is gone and Vitest doesn't read it.
hupponen
force-pushed
the
replace-karma-with-vitest
branch
from
August 28, 2026 21:11
9724c62 to
f2c932f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Karma hasn't been usable for a long time, so the unit tests haven't been run either. Two independent reasons:
karma.conf.jsrequireskarma-coverage-istanbul-reporter, which isn't installed, andsrc/test.tsimportszone.js/dist/...paths that no longer exist in current zone.js.Vitest runs the tests in Node without a browser, so they also work in containers and in CI, where Karma's Chrome isn't available. The whole suite takes about a second.
Changes
Add Vitest for unit tests (
2ac8e348)vitest.config.mts, andsrc/test-setup.tswhich imports@angular/compilerso the JIT compiler is available as a fallback for the partially compiled declarations in the published Angular packagesdescribe/it/expectfromvitestexplicitly instead of relying on globals, which keeps them type-checked without any tsconfig changesexpect(component).toBeTruthy(). They were generated by the Angular CLI and were never given the services the components inject, soTestBed.createComponent()would have thrown. TestBed support comes with the Angular 20 unit-test builder, which also uses VitestgetItemsByIndexes()to throw for a non-array input: it asserted a return value instead, and lodashmap()returns an empty array forundefined, so it could never passRemove unused Karma test setup (
48e25747)karma.conf.js,src/test.ts, the Angular test target and the Karma and Jasmine dependencies.npm testnow runs Vitesttest/unit-tests.htmlwas an even older SystemJS and Jasmine runner, withtest/liteserver-test-config.jsononly pointing at itlodashfromnode_modules, which revealed thatsession.resource.tsanddatasetmodal.service.tsimportedlodasheven though onlylodash-esis declared as a dependency. They had been resolving to the copy Karma happened to bring in, so the production build broke as soon as Karma was gone. They now importchunk()andcloneDeep()fromlodash-eslike the rest of the codeRemove unused Protractor e2e setup (
e58991aa)e2etarget pointed toe2e/protractor.conf.js, but that directory doesn't exist and protractor isn't a dependency. Angular CLI dropped Protractor support years agoType check the specs with the root tsconfig (
f2c932fc)tsc -p tsconfig.json --noEmitis what type checks the specs. The root tsconfig has noinclude, so it already covers them.d.tsfiles that reference exports-map subpaths, whichmoduleResolution: "node"cannot follow. Use"bundler"instead, which resolves them and is the default of new Angular projects. UnlikeskipLibCheck, that keeps the type checking of dependencies ontsconfig.spec.json: the Angular test target that used it is gone and Vitest doesn't read itTesting
npm test: 16 tests pass, no skipped tests, ~1.1 snpx tsc -p tsconfig.json --noEmit: no errors, this is what type checks the specsnpx tsc -p tsconfig.app.json --noEmit: no errorsnpm run build: production bundle buildsReviewers need
npm ciafter checkout, because the lockfile changed.Only unit tests are in scope here. Testing user flows, e.g. that dialogs close when navigating, needs a real browser and is left for a Playwright setup.