Angular7项目Jenkins自动执行单元测试配置故障排查求助
Hey there, let's get to the bottom of this Jenkins test failure. The error you're seeing boils down to PhantomJS 2.1.1 lacking support for modern JavaScript features—specifically Array.prototype.fill(), an ES6 method your app or its dependencies are using. PhantomJS is built on an outdated WebKit engine, so it can't keep up with the ES6+ features Angular 7 and modern libraries rely on.
Here are two solid solutions to resolve this:
1. Switch to Headless Chrome (Recommended)
Headless Chrome is a far better fit for CI environments like Jenkins. It supports all modern JS features Angular needs and is actively maintained. Here's how to set it up:
- First, remove the outdated PhantomJS launcher:
npm uninstall karma-phantomjs-launcher --save-dev - Update your
karma.conf.jsto use ChromeHeadless instead. Replace your browsers and singleRun settings with this:module.exports = function (config) { config.set({ // Keep all your existing config except these sections browsers: ['ChromeHeadless'], customLaunchers: { ChromeHeadless: { base: 'Chrome', flags: [ '--headless', '--disable-gpu', '--no-sandbox', // Critical for Linux/Jenkins to avoid permission issues '--remote-debugging-port=9222' ] } }, singleRun: true // Ensures tests run once and exit, perfect for CI pipelines }); }; - Adjust your Jenkins command to install dependencies first, then run tests (note the corrected structure):
npm install && ng test --watch=false --code-coverage
2. Add a Polyfill for Array.prototype.fill() (If You Must Keep PhantomJS)
If you need to stick with PhantomJS for some reason, you can add a polyfill to add support for the missing method:
- Open your
src/polyfills.tsfile and add this standard polyfill (from MDN):// Polyfill for Array.prototype.fill() to support PhantomJS if (!Array.prototype.fill) { Array.prototype.fill = function(value) { if (this == null) { throw new TypeError('this is null or not defined'); } const O = Object(this); const len = O.length >>> 0; const start = arguments[1]; const relativeStart = start >> 0; let k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len); const end = arguments[2]; const relativeEnd = end === undefined ? len : end >> 0; const final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len); while (k < final) { O[k] = value; k++; } return O; }; } - Keep in mind this only fixes the
fill()issue—you might run into other ES6 feature gaps later, which is why Headless Chrome is the better long-term fix.
One quick note: Your current karma.conf.js has singleRun: false, which is great for local development (auto-re-runs tests on changes). For Jenkins, setting this to true (or letting the --watch=false flag override it) ensures the test process exits after running, which is exactly what you want in a CI pipeline.
内容的提问来源于stack exchange,提问作者Joost Kaal

