如何使用 karma 在我的 Aurelia 应用程序中获得代码覆盖率结果?
How can I get code coverage results in my Aurelia app using karma?
我使用 Aurelia CLI (au new
) 创建了一个 Aurelia 应用程序并想设置代码覆盖率(最好使用 karma-coverage,但是如果那不可能我会使用任何东西)。
我先npm install karma-coverage --save-dev
然后将test.js
任务复制到cover.js
(这样我就可以运行au cover
)。
cover.js
import {Server as Karma} from 'karma';
import {CLIOptions} from 'aurelia-cli';
// import project from "../aurelia.json";
export function cover(done) {
new Karma({
// This is the same as what's in karma.conf.js after running
// Except I added the 'src\**\*.js' part
files: [
'scripts\vendor-bundle.js',
{pattern: 'test\unit\**\*.js', included: false},
'test/aurelia-karma.js',
'scripts\app-bundle.js',
'scripts\materialize-bundle.js',
{pattern: 'src\**\*.js', included: false}
],
configFile: __dirname + '/../../karma.conf.js',
singleRun: !CLIOptions.hasFlag('watch'),
reporters: ['progress', 'coverage'],
//logLevel: 'debug',
preprocessors: {
// [project.unitTestRunner.source]: [project.transpiler.id], // Is this actually needed? Nothing changes if I add or remove this...
'src/**/*.js': ['babel', 'coverage']
},
coverageReporter: {
includeAllSources: true,
reporters: [
{type: 'html', dir: 'coverage'},
{type: 'text'}
]
}
}, done).start();
}
export default cover;
这...让我到达某个地方?
但我不认为测试链接到单个 src 文件(它们链接到 app-bundle.js
)。
有没有办法在 Aurelia 应用程序的 src 文件级别(即非捆绑包级别)获得代码覆盖率?
其他感兴趣的文件
app.js
export class App {
constructor() {
this.message = 'Hello World!';
}
}
karma.conf.js
"use strict";
const path = require('path');
const project = require('./aurelia_project/aurelia.json');
let testSrc = [
{ pattern: project.unitTestRunner.source, included: false },
'test/aurelia-karma.js'
];
let output = project.platform.output;
let appSrc = project.build.bundles.map(x => path.join(output, x.name));
let entryIndex = appSrc.indexOf(path.join(output, project.build.loader.configTarget));
let entryBundle = appSrc.splice(entryIndex, 1)[0];
let files = [entryBundle].concat(testSrc).concat(appSrc); console.log(files);
module.exports = function(config) {
config.set({
basePath: '',
frameworks: [project.testFramework.id],
files: files,
exclude: [],
preprocessors: {
[project.unitTestRunner.source]: [project.transpiler.id]
},
'babelPreprocessor': { options: project.transpiler.options },
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
// client.args must be a array of string.
// Leave 'aurelia-root', project.paths.root in this order so we can find
// the root of the aurelia project.
client: {
args: ['aurelia-root', project.paths.root]
}
});
};
从您的终端屏幕截图来看,您似乎覆盖了个人文件 src/app.js
(12.5%)、src/environment.js
(0%) 和 src/main.js
(12.5%) ) 除了捆绑文件。它与您添加的额外行有关,包括 src/
.
中的文件
我怀疑如果您转到覆盖目录并在浏览器中查看它,您会看到更详细的结果。
我不确定具体的 Aurelia 应用程序,但要获得单个文件覆盖率,您希望针对原始文件而不是捆绑版本进行测试 运行,并且您希望使用相同的路径您的原始文件也将在预处理器中。
files: [
...
'src/**/*.js',
'path/to/tests/*.spec.js'
...
],
preprocessors: {
'src/**/*.js': ['coverage']
}
此模式(您已完成)告诉 Karma 加载单个文件,并将它们包含在覆盖范围内。在这一点上,我不会费心加载捆绑的应用程序代码,因为您已经加载了所有原始内容。
另外请务必按照它们可能捆绑的顺序加载它们,这样您就可以确定 Karma 可以首先初始化应用程序。
files: [
'src/app.js',
'src/environment.js',
'src/main.js'
]
如果您将名为 myTest.spec.js
的规范放在他们测试的文件旁边,您可以使用 src/!(*.spec).js
来确保您包含未经测试的应用程序代码。
我终于让它工作了,但是它需要大量的底层修改=\
首先我必须安装以下软件包
npm install karma-coverage --save-dev
npm install karma-requirejs --save-dev
npm install babel-plugin-istanbul --save-dev
aurelia_project/tasks/cover.js
这是基于test.js
。
- 将
requirejs
添加到 frameworks
的列表中(来自 karma-requirejs 包)
- 添加单独的 src/test 文件(带有
included: false
)以及 test/aurelia-karma-cover.js
,后者执行实际的 require
测试文件。
- 将
aurelia-karma.js
修改为 aurelia-karma-cover.js
以不包含 /test/unit/setup.js
(这给我带来了 aurelia-browser-pal 依赖项的麻烦)
- 从 src 文件预处理中删除
"coverage"
(babel-plugin-istanbul 现在将处理代码检测 - 详情请参阅末尾的声明)。
import {Server as Karma} from 'karma';
import {CLIOptions} from 'aurelia-cli';
import project from "../aurelia.json";
export function cover(done) {
new Karma({
configFile: __dirname + '/../../karma.conf.js',
frameworks: [project.testFramework.id, 'requirejs'],
files: [
{pattern: 'src\**\*.js', included: false},
{pattern: 'test\unit\**\*.js', included: false},
// This file actually loads the spec files via require - it's based on aurelia-karma.js
// but removes setup.js and its dependencies
'test/aurelia-karma-cover.js'
],
exclude: [
'src/environment.js',
'src/main.js',
'src/resources/index.js'
],
preprocessors: {
'src/**/*.js': ['babel'],
},
reporters: ['progress', 'coverage'],
singleRun: !CLIOptions.hasFlag('watch'),
coverageReporter: {
includeAllSources: true,
reporters: [
{type: 'html', dir: 'coverage'},
{type: 'text'}
]
}
}, done).start();
}
export default cover;
test/unit/aurelia-karma-cover.js
只需将 var allTestFiles = ['/base/test/unit/setup.js'];
更改为 var allTestFiles = [];
即可避免 aurelia-pal-browser 依赖错误。
aurelia_project/aurelia.json
如果使用 babel-plugin-istanbul.
,请将 "istanbul"
添加到 transpiler.options.plugins
列表
* 如果没有 babel-plugin-istanbul
,代码覆盖率适用于 post-transpiled 代码,它添加了无法真正测试的样板。这使您可以达到 100% 的代码覆盖率 ;)
@lebolo 这些是我必须做出的调整才能让这里的东西正常工作:
aurelia_project/tasks/cover.js
在封面函数的开头包含一个供应商路径常量:
const VENDORS_PATH = __dirname + '/../../node_modules/';
使用 VENDORS_PATH 在文件中包含我依赖的库:
files: [
{pattern: VENDORS_PATH + 'moment/min/moment.min.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'test/unit/**/*.js', included: false},
'test/aurelia-karma-cover.js'
]
预处理器中包含的测试文件:
preprocessors: {
'src/**/*.js': ['babel'],
'test/unit/**/*.js': ['babel']
}
test/unit/aurelia-karma-cover.js
更改 url 在 requirejs.load
函数中的内置方式:
url = '/base/' + url;
=> url = ['/base', root, url].join('/');
添加了一项功能来配置 requirejs 路径并在 patchRequireJS()
调用后调用它:
function configRequire() {
var VENDORS_PATH = '../node_modules/';
requirejs.config({
paths: {
'moment': VENDORS_PATH + 'moment/min/moment.min'
}
});
}
我使用 Aurelia CLI (au new
) 创建了一个 Aurelia 应用程序并想设置代码覆盖率(最好使用 karma-coverage,但是如果那不可能我会使用任何东西)。
我先npm install karma-coverage --save-dev
然后将test.js
任务复制到cover.js
(这样我就可以运行au cover
)。
cover.js
import {Server as Karma} from 'karma';
import {CLIOptions} from 'aurelia-cli';
// import project from "../aurelia.json";
export function cover(done) {
new Karma({
// This is the same as what's in karma.conf.js after running
// Except I added the 'src\**\*.js' part
files: [
'scripts\vendor-bundle.js',
{pattern: 'test\unit\**\*.js', included: false},
'test/aurelia-karma.js',
'scripts\app-bundle.js',
'scripts\materialize-bundle.js',
{pattern: 'src\**\*.js', included: false}
],
configFile: __dirname + '/../../karma.conf.js',
singleRun: !CLIOptions.hasFlag('watch'),
reporters: ['progress', 'coverage'],
//logLevel: 'debug',
preprocessors: {
// [project.unitTestRunner.source]: [project.transpiler.id], // Is this actually needed? Nothing changes if I add or remove this...
'src/**/*.js': ['babel', 'coverage']
},
coverageReporter: {
includeAllSources: true,
reporters: [
{type: 'html', dir: 'coverage'},
{type: 'text'}
]
}
}, done).start();
}
export default cover;
这...让我到达某个地方?
但我不认为测试链接到单个 src 文件(它们链接到 app-bundle.js
)。
有没有办法在 Aurelia 应用程序的 src 文件级别(即非捆绑包级别)获得代码覆盖率?
其他感兴趣的文件
app.js
export class App {
constructor() {
this.message = 'Hello World!';
}
}
karma.conf.js
"use strict";
const path = require('path');
const project = require('./aurelia_project/aurelia.json');
let testSrc = [
{ pattern: project.unitTestRunner.source, included: false },
'test/aurelia-karma.js'
];
let output = project.platform.output;
let appSrc = project.build.bundles.map(x => path.join(output, x.name));
let entryIndex = appSrc.indexOf(path.join(output, project.build.loader.configTarget));
let entryBundle = appSrc.splice(entryIndex, 1)[0];
let files = [entryBundle].concat(testSrc).concat(appSrc); console.log(files);
module.exports = function(config) {
config.set({
basePath: '',
frameworks: [project.testFramework.id],
files: files,
exclude: [],
preprocessors: {
[project.unitTestRunner.source]: [project.transpiler.id]
},
'babelPreprocessor': { options: project.transpiler.options },
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
// client.args must be a array of string.
// Leave 'aurelia-root', project.paths.root in this order so we can find
// the root of the aurelia project.
client: {
args: ['aurelia-root', project.paths.root]
}
});
};
从您的终端屏幕截图来看,您似乎覆盖了个人文件 src/app.js
(12.5%)、src/environment.js
(0%) 和 src/main.js
(12.5%) ) 除了捆绑文件。它与您添加的额外行有关,包括 src/
.
我怀疑如果您转到覆盖目录并在浏览器中查看它,您会看到更详细的结果。
我不确定具体的 Aurelia 应用程序,但要获得单个文件覆盖率,您希望针对原始文件而不是捆绑版本进行测试 运行,并且您希望使用相同的路径您的原始文件也将在预处理器中。
files: [
...
'src/**/*.js',
'path/to/tests/*.spec.js'
...
],
preprocessors: {
'src/**/*.js': ['coverage']
}
此模式(您已完成)告诉 Karma 加载单个文件,并将它们包含在覆盖范围内。在这一点上,我不会费心加载捆绑的应用程序代码,因为您已经加载了所有原始内容。
另外请务必按照它们可能捆绑的顺序加载它们,这样您就可以确定 Karma 可以首先初始化应用程序。
files: [
'src/app.js',
'src/environment.js',
'src/main.js'
]
如果您将名为 myTest.spec.js
的规范放在他们测试的文件旁边,您可以使用 src/!(*.spec).js
来确保您包含未经测试的应用程序代码。
我终于让它工作了,但是它需要大量的底层修改=\
首先我必须安装以下软件包
npm install karma-coverage --save-dev
npm install karma-requirejs --save-dev
npm install babel-plugin-istanbul --save-dev
aurelia_project/tasks/cover.js
这是基于test.js
。
- 将
requirejs
添加到frameworks
的列表中(来自 karma-requirejs 包) - 添加单独的 src/test 文件(带有
included: false
)以及test/aurelia-karma-cover.js
,后者执行实际的require
测试文件。 - 将
aurelia-karma.js
修改为aurelia-karma-cover.js
以不包含/test/unit/setup.js
(这给我带来了 aurelia-browser-pal 依赖项的麻烦) - 从 src 文件预处理中删除
"coverage"
(babel-plugin-istanbul 现在将处理代码检测 - 详情请参阅末尾的声明)。
import {Server as Karma} from 'karma';
import {CLIOptions} from 'aurelia-cli';
import project from "../aurelia.json";
export function cover(done) {
new Karma({
configFile: __dirname + '/../../karma.conf.js',
frameworks: [project.testFramework.id, 'requirejs'],
files: [
{pattern: 'src\**\*.js', included: false},
{pattern: 'test\unit\**\*.js', included: false},
// This file actually loads the spec files via require - it's based on aurelia-karma.js
// but removes setup.js and its dependencies
'test/aurelia-karma-cover.js'
],
exclude: [
'src/environment.js',
'src/main.js',
'src/resources/index.js'
],
preprocessors: {
'src/**/*.js': ['babel'],
},
reporters: ['progress', 'coverage'],
singleRun: !CLIOptions.hasFlag('watch'),
coverageReporter: {
includeAllSources: true,
reporters: [
{type: 'html', dir: 'coverage'},
{type: 'text'}
]
}
}, done).start();
}
export default cover;
test/unit/aurelia-karma-cover.js
只需将 var allTestFiles = ['/base/test/unit/setup.js'];
更改为 var allTestFiles = [];
即可避免 aurelia-pal-browser 依赖错误。
aurelia_project/aurelia.json
如果使用 babel-plugin-istanbul.
,请将"istanbul"
添加到 transpiler.options.plugins
列表
* 如果没有 babel-plugin-istanbul
,代码覆盖率适用于 post-transpiled 代码,它添加了无法真正测试的样板。这使您可以达到 100% 的代码覆盖率 ;)
@lebolo 这些是我必须做出的调整才能让这里的东西正常工作:
aurelia_project/tasks/cover.js
在封面函数的开头包含一个供应商路径常量:
const VENDORS_PATH = __dirname + '/../../node_modules/';
使用 VENDORS_PATH 在文件中包含我依赖的库:
files: [
{pattern: VENDORS_PATH + 'moment/min/moment.min.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'test/unit/**/*.js', included: false},
'test/aurelia-karma-cover.js'
]
预处理器中包含的测试文件:
preprocessors: {
'src/**/*.js': ['babel'],
'test/unit/**/*.js': ['babel']
}
test/unit/aurelia-karma-cover.js
更改 url 在 requirejs.load
函数中的内置方式:
url = '/base/' + url;
=> url = ['/base', root, url].join('/');
添加了一项功能来配置 requirejs 路径并在 patchRequireJS()
调用后调用它:
function configRequire() {
var VENDORS_PATH = '../node_modules/';
requirejs.config({
paths: {
'moment': VENDORS_PATH + 'moment/min/moment.min'
}
});
}