【问题标题】:Karma run single testKarma 运行单次测试
【发布时间】:2014-12-20 13:48:46
【问题描述】:

我使用 karma 来运行测试。我有很多测试,运行所有测试是一个非常缓慢的过程。我只想运行一个测试以减少时间,因为所有测试都运行大约 10 分钟。

有可能吗?

【问题讨论】:

标签: karma-runner


【解决方案1】:

将您的 karma conf 更改为仅包含您要运行的测试而不是完整目录。

文件内部:[...]

如果您需要/想要在 chrome 中调试测试以避免 js 被缩小,您可能需要评论预处理器。

【讨论】:

    【解决方案2】:

    将 it() 更改为 iit() 应该可以运行单个测试。 同样,对于 describe() 块,我们可以使用 ddescribe()

    【讨论】:

    • 根据您的业力版本,您可能需要使用 fdescribe()fit(),正如 brendan 指出的那样
    【解决方案3】:

    更新:业力已经改变。

    现在使用fit()fdescribe()

    f 代表专注!

    【讨论】:

    • ahhh f 代表 focused...有点愚蠢,但我会接受的,哈哈
    【解决方案4】:

    如果您使用的是 Karma/Jasmine 堆栈,请使用:

    fdescribe("when ...", function () { // to [f]ocus on a single group of tests
      fit("should ...", function () {...}); // to [f]ocus on a single test case
    });
    

    ...和:

    xdescribe("when ...", function () { // to e[x]clude a group of tests
      xit("should ...", function () {...}); // to e[x]clude a test case
    });
    

    当您使用 Karma/Mocha 时:

    describe.only("when ...", function () { // to run [only] this group of tests
      it.only("should ...", function () {...}); // to run [only] this test case
    });
    

    ...和:

    describe.skip("when ...", function () { // to [skip] running this group of tests
      it.skip("should ...", function () {...}); // to [skip] running this test case
    });
    

    【讨论】:

    • 但是如果一个贡献者已经调试了一些东西并重命名了一些测试来缩小问题的范围,忘记这样做并提交了怎么办?我发现来回编辑测试以集中和分散它是愚蠢的。有没有办法使用 CLI 就像“运行这个测试,并且只运行这个测试”?
    • 通常在一个文件中有多个测试用例和组,例如,有时您只需要运行其中一个。 “焦点”功能是任何单元测试库中的“必备”功能。此外,您可以添加“git-hook”来检查 .onlyfit 代码外观并在找到时拒绝提交。
    • 我明白了——好点子!但是我无法将 git-hook 签入 VCS,可以吗?
    • 好问题,但似乎超出了这个问题。
    【解决方案5】:

    a) 您可以将描述单个文件的模式作为命令行参数传递给 karma start 命令:

    # build and run all tests
    $ karma start
    
    # build and run only those tests that are in this dir
    $ karma start --grep app/modules/sidebar/tests
    
    # build and run only this test file
    $ karma start --grep app/modules/sidebar/tests/animation_test.js
    

    来源:https://gist.github.com/KidkArolis/fd5c0da60a5b748d54b2

    b) 您可以使用 Gulp(或 Grunt 等)任务为您启动 Karma。这使您在如何执行 Karma 方面具有更大的灵活性。例如,您可以将自定义命令行参数传递给这些任务。如果您想实现只执行更改的测试的监视模式,此策略也很有用。 (Karma 监视模式将执行所有测试。)另一个用例是在提交之前仅对具有本地更改的文件执行测试。 另请参阅下面的 Gulp 示例。

    c) 如果您使用 VisualStudio,您可能希望将外部工具命令添加到解决方案资源管理器的上下文菜单中。这样,您可以从该上下文菜单开始测试,而不是使用控制台。另见

    How to execute custom file specific command / task in Visual Studio?

    示例 Gulp 文件

    //This gulp file is used to execute the Karma test runner
    //Several tasks are available, providing different work flows
    //for using Karma. 
    
    var gulp = require('gulp');
    var karma = require('karma');
    var KarmaServerConstructor = karma.Server;
    var karmaStopper = karma.stopper;
    var watch = require('gulp-watch');
    var commandLineArguments = require('yargs').argv;
    var svn = require('gulp-svn');
    var exec = require('child_process').exec;
    var fs = require('fs');
    
    //Executes all tests, based on the specifications in karma.conf.js
    //Example usage: gulp all
    gulp.task('all', function (done) {
        var karmaOptions = { configFile: __dirname + '/karma.conf.js' };
        var karmaServer = new KarmaServerConstructor(karmaOptions, done);
        karmaServer.on('browsers_change', stopServerIfAllBrowsersAreClosed); //for a full list of events see http://karma-runner.github.io/1.0/dev/public-api.html
        karmaServer.start();   
    });
    
    //Executes only one test which has to be passed as command line argument --filePath
    //The option --browser also has to be passed as command line argument.
    //Example usage:  gulp single --browser="Chrome_With_Saved_DevTools_Settings" --filePath="C:\myTest.spec.js"
    gulp.task('single', function (done) {     
    
        var filePath = commandLineArguments.filePath.replace(/\\/g, "/");
    
        var karmaOptions = {
            configFile: __dirname + '/karma.conf.js',
            action: 'start',        
            browsers: [commandLineArguments.browser],       
            files: [
                './Leen.Managementsystem/bower_components/jquery/dist/jquery.js',
                './Leen.Managementsystem/bower_components/globalize/lib/globalize.js',
                { pattern: './Leen.Managementsystem/bower_components/**/*.js', included: false },
                { pattern: './Leen.Managementsystem.Tests/App/test/mockFactory.js', included: false },
                { pattern: './Leen.Managementsystem/App/**/*.js', included: false },
                { pattern: './Leen.Managementsystem.Tests/App/test/*.js', included: false },
                { pattern: filePath, included: false },
                './Leen.Managementsystem.Tests/App/test-main.js',
                './switchKarmaToDebugTab.js' //also see https://stackoverflow.com/questions/33023535/open-karma-debug-html-page-on-startup
            ]
        };
    
        var karmaServer = new KarmaServerConstructor(karmaOptions, done);   
        karmaServer.on('browsers_change', stopServerIfAllBrowsersAreClosed);
        karmaServer.start();     
    });
    
    //Starts a watch mode for all *.spec.js files. Executes a test whenever it is saved with changes. 
    //The original Karma watch mode would execute all tests. This watch mode only executes the changed test.
    //Example usage:  gulp watch 
    gulp.task('watch', function () {
    
        return gulp //
            .watch('Leen.Managementsystem.Tests/App/**/*.spec.js', handleFileChanged)
            .on('error', handleGulpError);
    
        function handleFileChange(vinyl) {
    
            var pathForChangedFile = "./" + vinyl.replace(/\\/g, "/");
    
            var karmaOptions = {
                configFile: __dirname + '/karma.conf.js',
                action: 'start',
                browsers: ['PhantomJS'],
                singleRun: true,
                files: [
                        './Leen.Managementsystem/bower_components/jquery/dist/jquery.js',
                        './Leen.Managementsystem/bower_components/globalize/lib/globalize.js',
                        { pattern: './Leen.Managementsystem/bower_components/**/*.js', included: false },
                        { pattern: './Leen.Managementsystem.Tests/App/test/mockFactory.js', included: false },
                        { pattern: './Leen.Managementsystem/App/**/*.js', included: false },
                        { pattern: './Leen.Managementsystem.Tests/App/test/*.js', included: false },
                        { pattern: pathForChangedFile, included: false },
                        './Leen.Managementsystem.Tests/App/test-main.js'
                ]
            };
    
            var karmaServer = new KarmaServerConstructor(karmaOptions);
            karmaServer.start();
    
        }
    
    });
    
    //Executes only tests for files that have local changes
    //The option --browser has to be passed as command line arguments.
    //Example usage:  gulp localChanges --browser="Chrome_With_Saved_DevTools_Settings"
    gulp.task('localChanges', function (done) {   
    
        exec('svn status -u --quiet --xml', handleSvnStatusOutput);
    
        function handleSvnStatusOutput(error, stdout, stderr) {
    
            if (error) {
                throw error;
            }
    
            var changedJsFiles = getJavaScriptFiles(stdout);   
            var specFiles = getSpecFiles(changedJsFiles);
    
    
            if(specFiles.length>0){
                console.log('--- Following tests need to be executed for changed files: ---');
                specFiles.forEach(function (file) {
                    console.log(file);
                });
                console.log('--------------------------------------------------------------');
            } else{
                console.log('Finsihed: No modified files need to be tested.');
                return;
            }
    
            var files = [
                    './Leen.Managementsystem/bower_components/jquery/dist/jquery.js',
                    './Leen.Managementsystem/bower_components/globalize/lib/globalize.js',
                    { pattern: './Leen.Managementsystem/bower_components/**/*.js', included: false },
                    { pattern: './Leen.Managementsystem.Tests/App/test/mockFactory.js', included: false },
                    { pattern: './Leen.Managementsystem/App/**/*.js', included: false },
                    { pattern: './Leen.Managementsystem.Tests/App/test/*.js', included: false }];
    
            specFiles.forEach(function (file) {
                var pathForChangedFile = "./" + file.replace(/\\/g, "/");
                files = files.concat([{ pattern: pathForChangedFile, included: false }]);
            });
    
            files = files.concat([ //
                './Leen.Managementsystem.Tests/App/test-main.js', //
                './switchKarmaToDebugTab.js'
            ]);
    
            var karmaOptions = {
                configFile: __dirname + '/karma.conf.js',
                action: 'start',
                singleRun: false,
                browsers: [commandLineArguments.browser],
                files: files              
            };
    
            var karmaServer = new KarmaServerConstructor(karmaOptions, done);
            karmaServer.on('browsers_change', stopServerIfAllBrowsersAreClosed);
            karmaServer.start();
        }  
    
    
    });
    
    function getJavaScriptFiles(stdout) {
        var jsFiles = [];
    
        var lines = stdout.toString().split('\n');
        lines.forEach(function (line) {
            if (line.includes('js">')) {
                var filePath = line.substring(9, line.length - 3);
                jsFiles.push(filePath);
            }
        });
        return jsFiles;
    }
    
    function getSpecFiles(jsFiles) {
    
        var specFiles = [];
        jsFiles.forEach(function (file) {
    
            if (file.endsWith('.spec.js')) {
                specFiles.push(file);
            } else {
                if (file.startsWith('Leen\.Managementsystem')) {
                    var specFile = file.replace('Leen\.Managementsystem\\', 'Leen.Managementsystem.Tests\\').replace('\.js', '.spec.js');
                    if (fs.existsSync(specFile)) {
                        specFiles.push(specFile);
                    } else {
                        console.error('Missing test: ' + specFile);
                    }
                }
            }
        });
        return specFiles;
    }
    
    function stopServerIfAllBrowsersAreClosed(browsers) {
        if (browsers.length === 0) {
            karmaStopper.stop();
        }
    }
    
    function handleGulpError(error) {
    
    
      throw error;
    }
    

    VisualStudio 中 ExternalToolCommand 的示例设置:

    标题:使用 Chrome 运行 Karma

    命令:cmd.exe

    参数:/c gulp single --browser="Chrome_With_Saved_DevTools_Settings" --filePath=$(ItemPath)

    初始目录:$(SolutionDir)

    使用输出窗口:true

    【讨论】:

      【解决方案6】:

      如果你想用 Angular 运行 karma 测试,你只需要修改你的 test.ts 文件。

      寻线const context = require.context('./', true, /\.spec\.ts$/);

      如果要运行your.component.spec.ts,请将行修改为:const context = require.context('./', true, /your\.component\.spec\.ts$/);

      【讨论】:

      • 这是第一个 Angular 答案!
      【解决方案7】:

      对于 Angular 用户!

      我知道两种方法:

      1. Visual Studio 代码扩展:

      最简单的方法是使用vscode-test-explorer 扩展及其子angular-karma-test-explorerjasmine-test-adapter,如果需要,您将获得当前测试的列表以逐个运行:

      1. 直接修改test.ts

      对我来说,我无法使用扩展方式因为this bug,所以我最终修改了test.ts文件(如hereShashi所述),只是为了在此处巩固答案,默认情况下上下文如下所示:

      const context = require.context('./', true, /\.spec\.ts$/);
      

      您应该修改它的 RegExp 以匹配您愿意测试的文件,例如,如果您想测试名为“my.single.file.custom.name.spec.ts”的单个文件,它会看起来这样:

      const context = require.context('./', true, /my\.single\.file\.custom\.name\.spec\.ts$/);
      

      有关require参数的更多详细信息,您可以找到here at their wiki

      1. Karma 跑步者改进

      目前有一个未解决的问题可以改善他们当前的行为,您可以在他们的 github 页面 (https://github.com/karma-runner/karma/issues/1507) 上关注他们的进度。

      【讨论】:

        【解决方案8】:

        是的,这是一个旧线程。

        在过去的几年里,我已经发生了 2-3 次以下情况。更何况当我没有做太多的单元测试并回到它时。

        我启动了我的 Karma,发现测试在初始启动后应该在 1 秒内完成,现在需要 20 秒。此外,尝试在 Chrome 中调试单元测试变得非常缓慢。网络选项卡显示所有文件,每个文件需要 2 - 3 秒。

        解决方案:我没有意识到 Fiddler 已打开。关闭它并重新开始测试。

        【讨论】:

          【解决方案9】:

          回答特殊 Angular/IE 案例的建议:到目前为止,我使用“karma-ie-launcher”来运行 IE 作为浏览器的唯一工作是修改 tsconfig 的“include”属性。 spec.json 使用通用限定路径而不是 glob 显式引用目标测试文件,例如“C:\filepath\my-test.spec.ts”,用于编译目的。 “此外”应适当修改 test.ts 文件,以针对测试文件限制目的的所述文件。请注意,此方案需要在 IE 中初始删除缓存才能生效。

          (对于 Angular/Chrome 案例,单独修改 test.ts 就足够了。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-08-26
            • 2013-08-24
            • 1970-01-01
            • 2015-05-22
            • 2019-06-17
            • 2017-01-13
            • 1970-01-01
            相关资源
            最近更新 更多