Karma führt einen Einzeltest durch

77

Ich benutze Karma für Lauftests. Ich habe viele Tests und alle Tests sind sehr langsam. Ich möchte nur einen einzigen Test ausführen, um weniger Zeit zu verbringen, da alle Tests etwa 10 Minuten dauern.

Ist es möglich ?

Vielen Dank.


quelle
Verwandte Karma-Problem: github.com/karma-runner/karma/issues/…
Stefan
Sie können describenach fdescribeund itnach ändernfit
Ernesto Alfonso

Antworten:

98

Wenn Sie den Karma / Jasmin- Stapel verwenden, verwenden Sie:

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

... und:

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

Wenn Sie auf Karma / Mokka sind :

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

... und:

describe.skip("when ...", function () { // to [skip] running this group of tests
  it.skip("should ...", function () {...}); // to [skip] running this test case
});
Dan KK
quelle
16
Aber was ist, wenn ein Mitwirkender, der etwas debuggt und einige Tests umbenannt hat, um das Problem einzugrenzen, dies vergisst und dies festschreibt? Ich finde es dumm, den Test hin und her zu bearbeiten, um ihn zu fokussieren und zu fokussieren. Gibt es keine Möglichkeit, die CLI so zu verwenden, dass sie nur "diesen Test und nur diesen Test ausführen" lautet?
Ingwie Phoenix
1
Normalerweise befinden sich mehrere Testfälle und Gruppen in einer Datei, und manchmal müssen Sie beispielsweise nur einen davon ausführen. Die "Fokus" -Funktion ist "Muss" in jeder Unit-Test-Bibliothek. Sie können auch "git-hook" hinzufügen, der das Auftreten von Code überprüft .onlyoder fitcodiert und das Commit ablehnt, wenn es gefunden wird.
Dan KK
Ich verstehe - guter Punkt! Aber ich kann keinen Git-Hook in VCS einchecken, oder?
Ingwie Phoenix
Gute Frage, aber es scheint, dass es über dieses Problem hinausgeht.
Dan KK
38

Update: Karma hat sich geändert.

Verwenden Sie jetzt fit()undfdescribe()

f steht für fokussiert!

brendan
quelle
ahhh fsteht für focused... irgendwie dumm, aber ich werde es nehmen lol
Alexander Mills
14

Für Angular Benutzer!

Ich kenne zwei Möglichkeiten:

  1. Visual Studio-Codeerweiterung:

Am einfachsten ist es, die Erweiterung vscode-test-explorer zusammen mit dem untergeordneten Winkel-Karma-Test-Explorer und dem Jasmin-Test-Adapter zu verwenden . Sie erhalten eine Liste der aktuellen Tests, die Sie einzeln ausführen können, wenn Sie möchten:

Geben Sie hier die Bildbeschreibung ein

  1. Ändern Sie test.ts direkt

Für mich war ich aufgrund dieses Fehlers nicht in der Lage, die Erweiterungsmethode zu verwenden , und so habe ich die test.tsDatei geändert (wie hier von Shashi angegeben ), nur um diese Antwort hier zu konsolidieren. Der Standardkontext sieht folgendermaßen aus:

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

Sie sollten RegExp so ändern, dass es mit den Dateien übereinstimmt, die Sie testen möchten. Wenn Sie beispielsweise eine einzelne Datei mit dem Namen "my.single.file.custom.name.spec.ts" testen möchten, sieht dies folgendermaßen aus:

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

Weitere Details zu requireParametern finden Sie hier im Wiki .

  1. Verbesserung des Karma-Läufers

Derzeit gibt es ein offenes Problem zur Verbesserung des aktuellen Verhaltens. Sie können den Fortschritt auf der Github-Seite ( https://github.com/karma-runner/karma/issues/1507 ) verfolgen .

Luis Limas
quelle
6

a) Sie können dem Karma-Startbefehl ein Muster übergeben, das Ihre einzelne Datei als Befehlszeilenargument beschreibt:

# 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

Quelle: https://gist.github.com/KidkArolis/fd5c0da60a5b748d54b2

b) Sie können eine Gulp- (oder Grunz-) Aufgabe verwenden, die Karma für Sie startet. Dies gibt Ihnen mehr Flexibilität bei der Ausführung von Karma. Sie können beispielsweise benutzerdefinierte Befehlszeilenargumente an diese Aufgaben übergeben. Diese Strategie ist auch nützlich, wenn Sie einen Überwachungsmodus implementieren möchten, der nur die geänderten Tests ausführt. (Der Karma-Überwachungsmodus führt alle Tests aus.) Ein weiterer Anwendungsfall besteht darin, nur Tests für Dateien mit lokalen Änderungen auszuführen, bevor Sie ein Commit durchführen. Siehe auch Gulp-Beispiele unten.

c) Wenn Sie VisualStudio verwenden, möchten Sie möglicherweise einen externen Tool-Befehl zum Kontextmenü des Solution Explorers hinzufügen. Auf diese Weise können Sie den Test über dieses Kontextmenü starten, anstatt die Konsole zu verwenden. Siehe auch

Wie führe ich benutzerdefinierte dateispezifische Befehle / Aufgaben in Visual Studio aus?

Beispiel Gulp-Datei

//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 /programming/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;
}

Beispieleinstellungen für ExternalToolCommand in VisualStudio:

Titel: Führen Sie Karma mit Chrome aus

Befehl: cmd.exe

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

Anfangsverzeichnis: $ (SolutionDir)

Ausgabefenster verwenden: true

Stefan
quelle
6

Wenn Sie einen Karma-Test mit Winkel ausführen möchten, müssen Sie nur Ihre test.tsDatei ändern .

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

Wenn Sie die your.component.spec.tsÄnderungszeile ausführen möchten, um:const context = require.context('./', true, /your\.component\.spec\.ts$/);

Shashi Ranjan
quelle
1
Hier ist die erste Winkelantwort!
Luis Limas
2

Das Ändern von it () in iit () sollte für die Ausführung eines einzelnen Tests funktionieren. In ähnlicher Weise können wir für den Block verify () ddescribe () verwenden.

stanislav.chetvertkov
quelle
2
Abhängig von Ihrer Karma-Version müssen Sie möglicherweise verwenden fdescribe()und fit()wie brendan betont
mgojohn
0

Ändern Sie Ihre Karma-Konfiguration so, dass nur der Test, den Sie ausführen möchten, anstelle eines vollständigen Verzeichnisses enthalten ist.

In den Dateien: [...]

Möglicherweise möchten Sie die Präprozessoren kommentieren, wenn Sie Ihren Test in Chrome debuggen müssen / möchten, um zu vermeiden, dass Ihre JS minimiert werden.

Ronan Quillevere
quelle
0

Ja, das ist ein alter Thread.

Die folgende Situation ist bei mir in den letzten Jahren 2 - 3 Mal aufgetreten. Mehr noch, wenn ich nicht viel Unit-Tests durchgeführt habe und darauf zurückgekommen bin.

Ich startete mein Karma und stellte fest, dass die Tests nach dem ersten Start innerhalb von 1 Sekunde abgeschlossen sein sollten, um jetzt 20 Sekunden zu dauern. Darüber hinaus wurde der Versuch, die Komponententests in Chrome zu debuggen, mühsam. Auf der Registerkarte "Netzwerk" wurden alle Dateien angezeigt, die pro Datei 2 bis 3 Sekunden dauerten.

Lösung: Ich wusste nicht, dass Fiddler offen war. Schließen Sie es und starten Sie Ihre Tests neu.

Esaith
quelle
0

Antwortvorschlag für einen speziellen Angular / IE-Fall: Das einzige, was bisher für mich mit "karma-ie-launcher" funktioniert hat, um IE als Browser auszuführen, war das Ändern der Eigenschaft "include" von tsconfig.spec.json, um explizit darauf zu verweisen Zieltestdatei unter Verwendung eines universell qualifizierten Pfads und nicht von Globs, z. B. "C: \ Dateipfad \ my-test.spec.ts", für Kompilierungszwecke. "Zusätzlich" sollte die Datei test.ts entsprechend geändert werden, um sie auf Zwecke der Einschränkung der Testdatei auszurichten . Beachten Sie, dass der Cache zunächst im IE gelöscht werden muss, damit dieses Schema wirksam wird.

(Für Angular / Chrome-Fälle wäre eine Änderung von test.ts allein ausreichend.)

Kieran Ryan
quelle