业力覆盖率报告显示代码已覆盖(显然未覆盖)

Posted

技术标签:

【中文标题】业力覆盖率报告显示代码已覆盖(显然未覆盖)【英文标题】:Karma-Coverage Report Shows Code As Covered (which is obviously not covered) 【发布时间】:2016-03-21 09:12:22 【问题描述】:

我试图生成 html 覆盖率报告,但它不包含我期望的输出。也许我在这里错了,但它应该只显示那些从规范文件中调用的行和方法,对吧?

不知何故没有。

更新:

我创建了一个存储库来提供一个工作示例,概述问题:

https://github.com/gearsdigital/stunning-octo-train

这是我的(测试)项目设置。如果需要,我可以将其推送到 GitHub 存储库,因为我不知道如何设置 JSFiddle 来运行此代码。

TL;DR

有一个生成 HTML 覆盖率报告的过程。此报告显示已覆盖的代码,由于没有可用的测试,显然未覆盖。

karma.conf.js:

var webpack = require('webpack');
var path = require('path');

// Reference webpack.config.js, don't repeat it!
var webpackConfig = require('./webpack.config.js');

// The entry point from the referenced Webpack configuration has to be
// removed or tests will fail in weird and inscrutable ways.
// Easy enough, just define an empty entry object (null won't work).
webpackConfig.entry = ;
webpackConfig.module = 
    preLoaders: [
        
            test: /\.js$/,
            // files within these directories should be excluded
            // for babel processing
            exclude: /(node_modules)/,
            loaders: ['babel?cacheDirectory']
        ,
        
            test: /\.js$/,
            include: /(src\/js)/,
            exclude: /(vendor)/,
            loaders: ['isparta']
        
    ]
;

/**
 * Karma configuration
 * @param config
 */
module.exports = function (config) 
    config.set(
        browsers: ['PhantomJS'],
        coverageReporter: 
            dir: 'test-results',
            reporters: [
                type: 'text-summary',
                type: 'html', subdir: 'coverage'
            ]
        ,
        files: [
            'webpack.test.config.js'
        ],
        frameworks: [
            'jasmine'
        ],
        preprocessors: 
            'webpack.test.config.js': ['webpack']
        ,
        reporters: ['spec', 'coverage'],
        webpack: webpackConfig
    );
;

webpack.config.js:

var webpack = require('webpack');
var path = require('path');

module.exports = 
    plugins: [
        new webpack.ProvidePlugin(
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery"
        )
    ]
;

webpack.test.config.js:

// make sure the file name regexp matches your test files.
var testsContext = require.context('./tests', true, /\.spec\.js$/);
testsContext.keys().forEach(testsContext);

// make sure the file name regexp matches your test files.
var srcContext = require.context('./src/js', true, /\.js$/);
srcContext.keys().forEach(srcContext);

bootstrap.js:

import Calculator from './modules/Calculator';
let c = new Calculator();
c.add(1,2); // 3

Calculator.js:

export class Calculator 
    add(op1, op2) 
        return op1 + op2;
    

    sub(op1, op2) 
        if (typeof op1 !== 'number') 
            return false;
        
        return op1 - op2;
    

    mul(op1, op2) 
        return op1 * op2;
    

    div(op1, op2) 
        return op1 / op2;
    

bootstrap.spec.js:

import Calculator from '../src/js/modules/Calculator';

describe('Calculator', function () 

    it('should return 10', function () 
        expect(true).toBe(false);
    );

);

生成的报告:

我希望add() 被发现,因为它没有在任何测试中调用,而是在bootstrap.js 中调用。

项目结构:

【问题讨论】:

我不明白为什么更多的报道是不好的:) 更多的覆盖率还不错:) 尽管没有为这段代码编写测试,但代码被覆盖是很糟糕的。 【参考方案1】:

好的,所以我不熟悉 Webpack 或 Babel,但我强烈怀疑,由于您将所有文件都包含在 Karma 配置中,因此无论测试中的内容是什么,代码都会被执行。我已经查看了您的 GitHub 示例(顺便说一句,这样做更容易调试),如果我注释掉 cart.js 的第 3 行和第 4 行,则覆盖率报告不会将 utilities.js 显示为“运行” .

长话短说:显然,未封装到函数中的代码通过在 Karma 中包含文件来运行。另外,在根本没有测试时不要相信 Karma(例如,字面意思是 0 it),在这种特定情况下它是不可靠的。

【讨论】:

感谢您的回答!你对如何处理这个问题有什么建议吗?我认为使用 ES2015 模块进行一些封装。 嗯,是的,你只是不应该调用 JS 文件顶部的函数。因为实际上,当被包含时,文件cart.js 会调用方法objectLength()。 Karma “看到”测试期间调用的代码,因此将其标记为已覆盖。【参考方案2】:

src/js/bootstrap.js 被加载;这意味着这些行将被执行。

import Calculator from './modules/Calculator';
let c = new Calculator();
c.add(1,2); // 3

我猜这个块是罪魁祸首:

    
        test: /\.js$/,
        include: /(src\/js)/,
        exclude: /(vendor)/,
        loaders: ['isparta']
    

我的代码不应该只在测试期间执行吗?

简短的回答是否定的。

当你导入模块时,任何不在闭包/函数/方法中的东西都可能被覆盖。

// this will get coverage; because it is top-level code outside a function block
var dummy = null;

export class Calculator 
    add(op1, op2) 
        // this will get coverage only if you call explicitly the function.
        return op1 + op2;
    


// this will get coverage.
var c = new Calculator();
// and now, Calculator.add will get coverage.
c.add(1,2); // 3

【讨论】:

好吧,也许我走错了路!谢谢你的回答。

以上是关于业力覆盖率报告显示代码已覆盖(显然未覆盖)的主要内容,如果未能解决你的问题,请参考以下文章

如何从业力代码覆盖率报告中排除文件?

Angular 单元测试中业力代码覆盖率报告中的 1x 3x 等是啥意思?

Karma 代码覆盖率未在 Sonarqube 中显示

有没有办法从业力覆盖文本报告器结果中排除所有 100% 或阈值的文件?

找不到业力覆盖

为啥 Karma Coverage 实际显示“未涵盖的声明”?