2015-01-23 1 views
11

Ich frage mich, ob jemand hat grunzen Karma, um nur eine Spezifikation, die auf der Uhr geändert wird laufen zu lassen. Das ist meine Konfiguration unten. Das Problem ist, dass die Zeile grunt.config ('karma.unit.options.files', Dateipfad); scheint nichts zu tun, da alle Spezifikationen immer noch laufen, aber foo wird ausgegeben, bevor das karma: unit: run gefeuert wird.Getting grunt Karma, um eine Einheit Test

Gibt es jemanden da draußen, der die Ausführung einer Spezifikation im Terminal bei Dateiänderung erreicht hat? Wir haben Tausende von Tests, so dass es langsam wird.

Danke, Alex

+0

Related Karma Ausgabe: https://github.com/karma-runner/karma/issues/1507 # issuecomment-320383049 – Stefan

+0

Verwandte Frage mit einer Lösung für Gulp: https://stackoverflow.com/questions/26552729/karma-run-single-test/45350941#45350941 – Stefan

Antwort

7

Ich habe das zur Arbeit gebracht. Im Grunde verwenden Sie Watch mit einem Event-Handler, um die Karma-Konfiguration bei jeder Dateiänderung dynamisch zu ändern. Hier ist der Ablauf:

Meine Grunt-Konfiguration hat zwei Karma-Aufgaben: "Alle" und "Eins". "all" läuft alle von ihnen, und "one" nur eine einzige Datei, die es nicht vorher weiß.

grunt.initConfig({ 
    // ... 
    karma: { 
    all: { 
     configFile: 'karma.conf.js', 
     browsers: ['PhantomJS'], 
     singleRun: true, 
     options: { 
     files: [ 
      'bower_components/jquery/dist/jquery.js', // dependencies 
      'src/js/**/*.js', // js source files 
      'src/js/**/*.spec.js' // unit test files 
     ] 
     } 
    }, 
    one: { 
     configFile: 'karma.conf.js', 
     browsers: ['PhantomJS'], 
     singleRun: true, 
     files: [ 
     {src: 'bower_components/jquery/dist/jquery.js'}, // dependencies 
     {src: ['src/js/**/*.js','!src/js/**/*.spec.js']} // source files 
     // (exclude the unit test files) 
     // watchEventListener will add the unit test file to run 
     ] 
    } 
    }, 
    // ... 
}); 

Und dann später in meiner Gruntfile, ich füge einen Listener für Watch Events. Dieser Listener aktualisiert die Aufgabe karma: one und fügt die Komponententestdatei hinzu. Wir behalten eine Kopie des Originaldatei-Arrays bei, andernfalls würden unsere Additionen beibehalten und während der Lebensdauer der Überwachungsaufgabe akkumuliert.

// when a unit test changes, execute only it 
var original_karmaOne_files = grunt.config.get('karma.one.files'); // keep the original files array 
grunt.event.on('watch', function watchEventListener(action, filepath, target){ 

    // this handler handles ALL watch changes. Try to filter out ones from other watch tasks 
    if (target == 'js_spec') handleJSHintSpec(); 

    // --------------------- 
    function handleJSHintSpec() { 
    if (action == 'deleted') return; // we don't need to run any tests when a file is deleted 
    // this will probably fail if a watch task is triggered with multiple files at once 
    // dynamically change the config 
    grunt.config.set('karma.one.files', [].concat(original_karmaOne_files, [{src: filepath}])); 
    } 
}); 

Und hier ist Aufgabe Uhr meines gruntfile:

watch: { 
    // ... 
    // when js spec files change, 
    // lint them 
    // run unit tests 
    js_spec: { 
    options: { 
     interrupt: true 
    }, 
    files: 'src/js/**/*.spec.js', 
    tasks: ['jshint:js_spec', 'karma:one'] 
    }, 
    // ... 
} 

Meine karma.conf.js Datei ist ziemlich Standard, aber seine Dateien Array ist leer. Eigentlich habe ich es auskommentiert, also ist die Eigenschaft nicht definiert.

// list of files/patterns to load in the browser 
//files: [], // specified in the gruntfile 
+2

Auch ich fand, dass die Dateien-Array muss Objekte mit einer 'src' Eigenschaft enthalten - nein t einfache Dateipfadzeichenfolgen, andernfalls fehlgeschlagen. –

+0

Außerdem muss bei jedem Beobachtungsziel die Option 'spawn' auf 'false' gesetzt sein, andernfalls hat' grunt.config.set() 'keine Wirkung. –

+1

Vielen Dank für diesen tollen Startpunkt und die Kommentare. Trotzdem hat es einige Zeit gedauert, bis es funktionierte. Ich habe meine resultierende Gruntfile.js als Antwort unten hinzugefügt. – Stefan

2

TL; DR: Benutze Karma: Einheit überall statt Karma: Einheit: run und benutze grunt.event.on ('watch', function() {}); Bearbeiten Sie die Karma-Konfiguration so, dass nur die Testdateien enthalten sind, die Sie ausführen möchten.

Ich habe das funktioniert, aber es könnte nicht sein, was Sie wollen. Ich starte den Server jedes Mal neu, wenn ich eine Datei speichere. Weitere Erklärung ist unten. Hier sind einige der config:

watch: { 
     tests: { 
      files: 'tests/**/*.js', 
      tasks: ['karma:unit'] 
     }, 
     tsChanged: { 
      files: config.tsFiles, 
      tasks: [ 
       'ts', 
       'karma:unit' 
      ] 
     } 
    } 

    grunt.event.on('watch', function(action, filepath){ 
     grunt.config(['karma', 'unit', 'files'], [{ 
      src: [ 
       path/to/your/source/files, 
       path/to/your/test/file, 
      ] 
     }]); 
    }); 

Es scheint mir, dass Karma alle der App-Dateien lädt und den Testdateien in den Browser, wenn es den Server startet. In Ihrem Fall wäre das, wenn Sie "grunt karma: unit: start watch" in die Befehlszeile eingeben. Also habe ich "grunt watch" benutzt und einfach ein "karma: unit" hinzugefügt. Dann fing ich das Speicherereignis ab und aktualisierte die Karma-Konfiguration, bevor es den Server startete.

Hoffe, das hilft.

1

eine Kombination aus yargs und einig Laufzeit-Magie, ich dies tun:

var argv = require('yargs') 
    .default('t', '*.js') 
    .alias('t', 'tests') 
    .describe('t', 'A file or file pattern of the test files to run, relative to the test/unit dir') 
    .help('?') 
    .alias('?', 'help') 
    .argv; 

var filesToLoad = ['src/**/*.js', 'test/unit/helpers/*.js']; 
filesToLoad.push(path.join('test/unit/**', argv.t)); 

gulp.task('tdd', function (done) { 
    karma.start({ 
     configFile: __dirname + '/../../karma.conf.js', 
     jspm: { 
      loadFiles: filesToLoad, 
     } 
    }, function(e) { 
     done(); 
    }); 
}); 

, die ein Testdatei/Pfadmuster als Argument zu schlucken und Lasten, die alle in dem Vorzug die Dateien.

0

Basierend auf der Antwort von Matthias und den Kommentaren meiner Grunddatei.js ist:

module.exports = function (grunt) { 

    grunt.initConfig({ 
     pkg: grunt.file.readJSON('package.json'), 
     karma: { 
      all: { 
       configFile: 'karma.conf.js',    
       background: true, 
       files: [ 
        { src: './Leen.Managementsystem/bower_components/jquery/dist/jquery.js' }, 
        { src: './Leen.Managementsystem/bower_components/globalize/lib/globalize.js' }, 
        { src: './Leen.Managementsystem/bower_components/**/*.js', included: false }, 
        { src: './Leen.Managementsystem.Tests/App/test/mockFactory.js', included: false }, 
        { src: './Leen.Managementsystem/App/**/*.js', included: false }, 
        { src: './Leen.Managementsystem.Tests/App/test/*.js', included: false }, 
        { src: './Leen.Managementsystem.Tests/App/**/*.spec.js', included: false }, 
        { src: './Leen.Managementsystem.Tests/App/test-main.js' } 
       ] 
      }, 
      one: { 
       configFile: 'karma.conf.js',    
       files: [ 
        { src: './Leen.Managementsystem/bower_components/jquery/dist/jquery.js' }, 
        { src: './Leen.Managementsystem/bower_components/globalize/lib/globalize.js' }, 
        { src: './Leen.Managementsystem/bower_components/**/*.js', included: false }, 
        { src: './Leen.Managementsystem.Tests/App/test/mockFactory.js', included: false }, 
        { src: './Leen.Managementsystem/App/**/*.js', included: false }, 
        { src: './Leen.Managementsystem.Tests/App/test/*.js', included: false },   
        // (do not inlcude the *.spec.js files here! The watch event listener will add the single spec file to run) 
        { src: './Leen.Managementsystem.Tests/App/test-main.js' } 
       ] 
      } 
     }, 
     watch: {   
      spec_js: { 
       options: { 
        interrupt: true, 
        spawn: false 
       }, 
       files: 'Leen.Managementsystem.Tests/App/**/*.spec.js', 
       tasks: ['karma:one:start']    
      } 
     } 
    }); 

    var originalKarmaOneFiles = grunt.config.get('karma.one.files'); // keep the original files array 

    grunt.event.on('watch', function watchEventListener(action, filepath, target) { 

     if (target === 'spec_js') { 
      handleChangedSpecFile(); 
     } 

     function handleChangedSpecFile() { 
      if (action === 'deleted') { 
       return; 
      }   

      var testFilePath = "./" + filepath.replace(/\\/g, "/"); 

      grunt.log.writeln(['Running single karma test for: ' + testFilePath]); 
      var updatedFiles = originalKarmaOneFiles.concat([{ src: testFilePath, included: false }]); 

      grunt.config.set('karma.one.files', updatedFiles); 
     } 
    }); 


    grunt.loadNpmTasks('grunt-karma'); 
    grunt.loadNpmTasks('grunt-contrib-watch'); 

    grunt.registerTask('default', ['karma:all','watch']); 

}; 

karma.conf.js:

module.exports = function(config) { 
    config.set({ 

     // base path, that will be used to resolve files and exclude 
     basePath: '', //the solution root path, e.g. D:\Energienetzwerke\trunk 


     // frameworks to use 
     frameworks: ['jasmine', 'requirejs'], 

     // list of files/patterns to load in the 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: './Leen.Managementsystem.Tests/App/**/*.spec.js', included: false}, 
     './Leen.Managementsystem.Tests/App/test-main.js' 
     ], 


     // list of files to exclude 
     exclude: [ 
     './Leen.Managementsystem/App/main.js' 
     ], 


     // test results reporter to use 
     // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 
     reporters: ['progress', 'coverage', 'notify', 'htmlDetailed', 'xml'], 



     coverageReporter: { 
     dir: './Leen.Managementsystem.Tests/testCoverage', 
     reporters: [ 
      { type: 'html',subdir: 'html'}, 
      { type: 'cobertura',subdir: 'xml', file: 'coverage.xml' }, 
      { type: 'lcov', subdir: 'lcov' }, 
      { type: 'text-summary' } 
      ] 
     }, 


     notifyReporter: { 
     reportEachFailure: true, // Default: false, Will notify on every failed spec 
     reportSuccess: false // Default: true, Will notify when a suite was successful 
     }, 

     htmlDetailed: { 
     autoReload: true, 
     dir: './Leen.Managementsystem.Tests/testResults' 

     }, 
    preprocessors: { 
     // source files, that you wanna generate coverage for 
     // do not include tests or libraries 
     // (these files will be instrumented by Istanbul) 
     './Leen.Managementsystem/App/**/*.js': ['coverage'] 
    }, 


    // web server port 
    port: 9876, 


    // enable/disable colors in the output (reporters and logs) 
    colors: true, 


    // level of logging 
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 
    logLevel: config.LOG_INFO, 


    // enable/disable watching file and executing tests whenever any file changes 
    autoWatch: false, //watching is done by Gruntfile.js to only execute changed tests 
    usePolling: true, 

    // Start these browsers, currently available: 
    // - Chrome 
    // - ChromeCanary 
    // - Firefox 
    // - Opera 
    // - Safari (only Mac) 
    // - PhantomJS 
    // - IE (only Windows) 
    browsers: ['Chrome_With_Saved_DevTools_Settings'], 

    customLaunchers: { 
     Chrome_With_Saved_DevTools_Settings: { 
      base: 'Chrome', 
      chromeDataDir: './.chrome'    
     } 
    }, 


    // If browser does not capture in given timeout [ms], kill it 
    captureTimeout: 60000, 


    // Continuous Integration mode 
    // if true, it capture browsers, run tests and exit 
    singleRun: true 
    }); 
}; 

package.json:

{ 
    "name": "solution", 
    "version": "1.0.0", 
    "description": "contains packages that are needed for running karma", 
    "main": "./Leen.Managementsystem.Tests/App/test-main.js", 
    "dependencies": { 
    "grunt": "1.0.1", 
    "grunt-cli": "1.2.0", 
    "grunt-contrib-watch": "1.0.0", 
    "grunt-karma": "2.0.0", 
    "jasmine-core": "2.6.4", 
    "karma": "1.7.0", 
    "karma-chrome-launcher": "2.2.0", 
    "karma-cli": "1.0.1", 
    "karma-coverage": "1.1.1", 
    "karma-firefox-launcher": "1.0.1", 
    "karma-html-detailed-reporter": "1.1.20", 
    "karma-ie-launcher": "1.0.0", 
    "karma-jasmine": "1.1.0", 
    "karma-notify-reporter": "1.0.1", 
    "karma-phantomjs-launcher": "1.0.4", 
    "karma-requirejs": "1.1.0", 
    "karma-xml-reporter": "0.1.4", 
    "requirejs": "2.3.4" 
    }, 
    "devDependencies": {}, 
    "scripts": { 
    "test": "karma run" 
    }, 
    "author": "LEEN", 
    "license": "private" 
}