Ich habe einen Code, in dem bestimmte Tests in der CI-Umgebung immer fehlschlagen. Ich möchte sie aufgrund einer Umgebungsbedingung deaktivieren.
Wie überspringe ich programmgesteuert einen Test in Mokka während der Laufzeitausführung?
Ich habe einen Code, in dem bestimmte Tests in der CI-Umgebung immer fehlschlagen. Ich möchte sie aufgrund einer Umgebungsbedingung deaktivieren.
Wie überspringe ich programmgesteuert einen Test in Mokka während der Laufzeitausführung?
Antworten:
Sie können Tests überspringen, indem Sie ein x vor die Beschreibung oder den Block setzen oder ein x .skip
danach setzen.
xit('should work', function (done) {});
describe.skip('features', function() {});
Sie können auch einen einzelnen Test ausführen, indem Sie ein .only
auf den Test setzen. zum Beispiel
describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
In diesem Fall würde nur der Feature-2-Block ausgeführt.
Es scheint keine Möglichkeit zu geben, Tests programmgesteuert zu überspringen, aber Sie können einfach eine beforeEach
Anweisung einchecken und den Test nur ausführen, wenn das Flag gesetzt ist.
beforeEach(function(){
if (wrongEnvironment){
runTest = false
}
}
describe('feature', function(){
if(runTest){
it('should work', function(){
// Test would not run or show up if runTest was false,
}
}
}
beforeEach
Aufruf ausgeführt wird, zeichnet Mocha die anonyme Funktion (den "Hook") für die zukünftige Verwendung auf. Wenn der describe
Aufruf ausgeführt wird, führt Mocha sofort die an ihn übergebene anonyme Funktion aus. Wenn die Zeit if (runTest)
ausgeführt wird, ist der beforeEach
Hook noch nicht ausgeführt.
Es gibt eine undokumentierte Möglichkeit, Tests programmgesteuert zu überspringen:
// test.js
describe('foo', function() {
before(function() {
this.skip();
});
it('foo', function() {
// will not run
console.log('This will not be printed');
});
});
Laufen:
$ mocha test.js
foo
- foo
0 passing (9ms)
1 pending
Dies wird unter https://github.com/mochajs/mocha/issues/1901 erläutert .
describe
als übersprungen markiert (dh alle Tests in der describe
werden übersprungen).
Diese Antwort funktioniert für ES6 .
Anstatt:
describe('your describe block', () => {
Sie wollen:
(condition ? describe : describe.skip)('your describe block', () => {
Dies überspringt bedingt alle Tests im Beschreibungsblock, wenn die Bedingung falsch ist.
Oder statt:
it('your it block', () => {
Sie wollen:
(condition ? it : it.skip)('your it block', () => {
Dies überspringt bedingt einen Test, wenn die Bedingung falsch ist.
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
Dann können Sie sie verwenden: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
Ich verwende das Laufzeit-Überspringen von Mocha für dasselbe Szenario, das Sie beschreiben. Es ist das Kopieren und Einfügen aus den Dokumenten :
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
Wie Sie sehen können, wird der Test basierend auf der Umgebung übersprungen. Mein eigener Zustand ist if(process.env.NODE_ENV === 'continuous-integration')
.
if (/* skipTestCondition */) return this.skip();
- bearbeiten: funktioniert: D
describe.skip
oderit.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
oderit.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Weitere Informationen unter https://mochajs.org/#inclusive-tests
Dies hängt davon ab, wie Sie den Test programmgesteuert überspringen möchten. Wenn die Bedingungen für das Überspringen festgelegt werden können, bevor ein Testcode ausgeführt wird, können Sie einfach it
oder it.skip
nach Bedarf basierend auf einer Bedingung anrufen . Dies überspringt beispielsweise einige Tests, wenn die Umgebungsvariable ONE
auf einen beliebigen Wert festgelegt ist:
var conditions = {
"condition one": process.env["ONE"] !== undefined
// There could be more conditions in this table...
};
describe("conditions that can be determined ahead of time", function () {
function skip_if(condition, name, callback) {
var fn = conditions[condition] ? it.skip: it;
fn(name, callback);
};
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
Wenn die Bedingungen, die Sie überprüfen möchten, nur zur Testzeit ermittelt werden können, ist dies etwas komplizierter. Wenn Sie nicht auf etwas zugreifen möchten, das nicht unbedingt Teil der Test-API ist, können Sie Folgendes tun:
describe("conditions that can be determined at test time", function () {
var conditions = {};
function skip_if(condition, name, callback) {
if (callback.length) {
it(name, function (done) {
if (conditions[condition])
done();
else
callback(done);
});
}
else {
it(name, function () {
if (conditions[condition])
return;
callback();
});
}
};
before(function () {
conditions["condition one"] = true;
});
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
Während mein erstes Beispiel darin bestand, die Tests als formal übersprungen (auch als "ausstehend" bezeichnet) zu markieren, wird mit der soeben gezeigten Methode die Durchführung des eigentlichen Tests vermieden, aber die Tests werden nicht als formal übersprungen markiert. Sie werden als bestanden markiert. Wenn Sie sie unbedingt überspringen lassen möchten, weiß ich nicht, wie Sie auf Teile zugreifen können, die nicht richtig Teil der Test-API sind:
describe("conditions that can be determined at test time", function () {
var condition_to_test = {}; // A map from condition names to tests.
function skip_if(condition, name, callback) {
var test = it(name, callback);
if (!condition_to_test[condition])
condition_to_test[condition] = [];
condition_to_test[condition].push(test);
};
before(function () {
condition_to_test["condition one"].forEach(function (test) {
test.pending = true; // Skip the test by marking it pending!
});
});
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
Ich bin nicht sicher, ob dies als „programmatisches Überspringen“ qualifiziert ist, aber um einige spezifische Tests für unsere CI-Umgebung selektiv zu überspringen, verwende ich die Tagging-Funktion von Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ). In describe()
oder it()
Nachrichten können Sie ein Tag wie @ no-ci hinzufügen. Um diese Tests auszuschließen, können Sie in Ihrer package.json ein bestimmtes "ci-Ziel" definieren --grep
und folgende --invert
Parameter verwenden:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Sie können mein Paket Mokka-Annahme verwenden , um Tests programmgesteuert zu überspringen, jedoch nur von außerhalb der Tests. Sie verwenden es so:
assuming(myAssumption).it("does someting nice", () => {});
Mokka-Annahme führt Ihren Test nur dann aus, wenn dies der Fall myAssumption
ist true
. Andernfalls wird er it.skip
mit einer netten Nachricht übersprungen.
Hier ist ein detaillierteres Beispiel:
describe("My Unit", () => {
/* ...Tests that verify someAssuption is always true... */
describe("when [someAssumption] holds...", () => {
let someAssumption;
beforeAll(() => {
someAssumption = /* ...calculate assumption... */
});
assuming(someAssumption).it("Does something cool", () => {
/* ...test something cool... */
});
});
});
Auf diese Weise können Sie Kaskadenfehler vermeiden. "Does something cool"
Angenommen, der Test würde immer fehlschlagen, wenn someAssumption nicht zutrifft. Diese Annahme wurde jedoch bereits oben (in Tests that verify someAssuption is always true"
) getestet .
Der Testfehler gibt Ihnen also keine neuen Informationen. Tatsächlich ist es sogar falsch positiv: Der Test ist nicht fehlgeschlagen, weil "etwas Cooles" nicht funktioniert hat, sondern weil eine Voraussetzung für den Test nicht erfüllt war. mit können mocha-assume
Sie oft solche Fehlalarme vermeiden.
beforeAll
wird nicht garantiert, dass der Haken läuft, bevor alle Tests gesammelt wurden. Eigentlich ist es sehr wahrscheinlich, dass es erst danach ausgeführt wird, aber in diesem Fall assuming(someAssumption)
hätte der bereits den anfänglichen (undefinierten) Wert erhalten. Es ist auch erforderlich, diesen Teil in eine Funktion einzuschließen, um den gewünschten Effekt zu erzielen.
Wir können eine schöne Clean-Wrapper-Funktion schreiben, um Tests wie folgt bedingt auszuführen:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
Dies kann dann wie folgt erforderlich und in Ihren Tests verwendet werden:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
Angenommen, ich wollte meinen parametrisierten Test überspringen, wenn meine Testbeschreibung die Zeichenfolge "foo" enthält. Ich würde dies tun:
// Skip parametrized test if description contains the string "foo"
(test.description.indexOf("foo") === -1 ? it : it.skip)("should test something", function (done) {
// Code here
});
// Parametrized tests
describe("testFoo", function () {
test({
description: "foo" // This will skip
});
test({
description: "bar" // This will be tested
});
});
In Ihrem Fall glaube ich, dass Sie NodeJS verwenden könnten, wenn Sie Umgebungsvariablen überprüfen möchten:
process.env.ENV_VARIABLE
Zum Beispiel (Warnung: Ich habe diesen Code nicht getestet!), Vielleicht so etwas:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
Wenn Sie ENV_VARIABLE so einstellen können, dass es sich um das handelt, was Sie gerade eingeben, und diesen Wert verwenden, überspringen Sie den Test oder führen Sie ihn aus. (Zu Ihrer Information, die Dokumentation für die process.env von NodeJS finden Sie hier: https://nodejs.org/api/process.html#process_process_env )
Ich werde den ersten Teil dieser Lösung nicht vollständig anerkennen. Ich habe die Antwort gefunden und getestet und es hat perfekt funktioniert, Tests basierend auf einer einfachen Bedingung über diese Ressource zu überspringen: https://github.com/mochajs/mocha/issues / 591
Hoffe das hilft! :) :)
Hierbei werden die Funktionen von Mokka nicht wirklich verwendet, sondern optimiert, um das gewünschte Verhalten zu erzielen.
Ich wollte jedes nachfolgende "es" in meinen Winkelmesser-Mokka-Tests überspringen und eines "es" schlug fehl. Dies lag daran, dass nach dem Fehlschlagen eines Schritts eines Reisetests fast sicher war, dass der Rest fehlschlagen würde. Dies kann lange dauern und den Build-Server belasten, wenn der Browser darauf wartet, dass Elemente auf einer Seite usw. angezeigt werden.
Wenn nur Standard-Mokka-Tests (nicht Winkelmesser) ausgeführt werden, kann dies mit globalen Vor-Jeder- und Nach-jedem-Hooks erreicht werden, indem dem übergeordneten (beschriebenen) Flag des Tests ein 'skipSubsequent'-Flag wie folgt hinzugefügt wird:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
Wenn Sie dies mit Winkelmesser und Mokka versuchen, hat sich der Umfang von 'dies' geändert und der obige Code funktioniert nicht. Am Ende wird eine Fehlermeldung wie "Fehleraufruf erledigt ()" angezeigt und der Winkelmesser wird angehalten.
Stattdessen habe ich den folgenden Code erhalten. Nicht die schönste, aber am Ende wird die Implementierung der verbleibenden Testfunktionen durch this.skip () ersetzt. Dies wird wahrscheinlich nicht mehr funktionieren, wenn sich die Interna von Mokka mit späteren Versionen ändern.
Es wurde durch einige Versuche und Irrtümer herausgefunden, indem Mochas Interna debuggt und inspiziert wurden. Dies hilft dabei, Browser-Testsuiten schneller abzuschließen, wenn die Tests fehlschlagen.
beforeEach(function() {
var parentSpec = this.currentTest.parent;
if (!parentSpec.testcount) {
parentSpec.testCount = parentSpec.tests.length;
parentSpec.currentTestIndex = 0;
} else {
parentSpec.currentTestIndex = parentSpec.currentTestIndex + 1;
}
if (parentSpec.skipSubsequent) {
parentSpec.skipSubsequent = false;
var length = parentSpec.tests.length;
var currentIndex = parentSpec.currentTestIndex;
for (var i = currentIndex + 1; i < length; i++) {
parentSpec.tests[i].fn = function() {
this.skip();
};
}
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
});
mocha test/ --grep <pattern>
Wie @danielstjules hier antwortete , gibt es eine Möglichkeit, den Test zu überspringen. @author dieses Themas hat die Antwort von github.com mochajs Diskussion kopiert, aber es gibt keine Informationen darüber, welche Version von Mokka verfügbar ist.
Ich verwende das Grunt-Mocha-Test-Modul zur Integration der Mocha-Test-Funktionalität in mein Projekt. Wenn ich zur letzten (vorerst) Version - 0.12.7 springe, bekomme ich die Mokka-Version 2.4.5 mit der Implementierung von this.skip ().
Also, in meinem package.json
"devDependencies": {
"grunt-mocha-test": "^0.12.7",
...
Und dann
npm install
Und es macht mich glücklich mit diesem Haken:
describe('Feature', function() {
before(function () {
if (!Config.isFeaturePresent) {
console.log('Feature not configured for that env, skipping...');
this.skip();
}
});
...
it('should return correct response on AB', function (done) {
if (!Config.isABPresent) {
return this.skip();
}
...
Bitte nicht. Ein Test, der in allen Umgebungen nicht konsistent funktioniert, sollte von Ihrer Build-Infrastruktur als solcher anerkannt werden. Und es kann sehr verwirrend sein, wenn in den CI-Builds eine andere Anzahl von Tests ausgeführt wird als in den lokalen.
Auch vermasselt es die Wiederholbarkeit. Wenn verschiedene Tests auf dem Server und lokal ausgeführt werden, kann es vorkommen, dass Tests in dev fehlschlagen und in CI bestanden werden oder umgekehrt. Es gibt keine Forcierungsfunktion und ich habe keine Möglichkeit, einen fehlgeschlagenen Build schnell und genau zu korrigieren.
Wenn Sie Tests zwischen Umgebungen deaktivieren müssen, anstatt Tests unter bestimmten Bedingungen auszuführen, kennzeichnen Sie Ihre Tests und verwenden Sie einen Filter, um Tests zu entfernen, die in bestimmten Build-Zielen nicht funktionieren. Auf diese Weise weiß jeder, was los ist und es erfüllt seine Erwartungen. Außerdem erfahren alle, dass das Testframework inkonsistent ist und dass jemand möglicherweise eine Lösung hat, mit der er wieder ordnungsgemäß ausgeführt werden kann. Wenn Sie den Test nur stumm schalten, wissen sie möglicherweise nicht einmal, dass ein Problem vorliegt.
this.skip()
in mochajs.org/#inclusive-tests und in der Antwort von @ zatziky unten behandelt. Der Rest der Antworten ist für Mocha v3 +