Ho un codice in cui alcuni test falliranno sempre in ambiente CI. Vorrei disabilitarli in base a una condizione ambientale.
Come saltare programmaticamente un test in moka durante l'esecuzione di runtime?
Ho un codice in cui alcuni test falliranno sempre in ambiente CI. Vorrei disabilitarli in base a una condizione ambientale.
Come saltare programmaticamente un test in moka durante l'esecuzione di runtime?
Risposte:
È possibile saltare i test posizionando una x davanti al blocco descrittivo o bloccato oppure posizionando un .skip
dopo.
xit('should work', function (done) {});
describe.skip('features', function() {});
È inoltre possibile eseguire un singolo test inserendo un .only
test. per esempio
describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
In questo caso verrebbe eseguito solo il blocco funzione 2.
Non sembra esserci un modo per saltare i test a livello di programmazione, ma potresti semplicemente fare una sorta di controllo in beforeEach
un'istruzione ed eseguire il test solo se il flag è stato impostato.
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
viene eseguita la chiamata, Mocha registra la funzione anonima (l '"hook") per uso futuro , quando describe
viene eseguita la chiamata, Mocha esegue immediatamente la funzione anonima passata ad essa. Quindi, al momento if (runTest)
dell'esecuzione, l' beforeEach
hook non avrà funzionato.
Esiste un modo non documentato di saltare programmaticamente i test:
// test.js
describe('foo', function() {
before(function() {
this.skip();
});
it('foo', function() {
// will not run
console.log('This will not be printed');
});
});
in esecuzione:
$ mocha test.js
foo
- foo
0 passing (9ms)
1 pending
Questo è discusso in https://github.com/mochajs/mocha/issues/1901 .
describe
come saltato (cioè tutti i test nel describe
vengono saltati).
Questa risposta funziona per ES6 .
Invece di:
describe('your describe block', () => {
Tu vuoi:
(condition ? describe : describe.skip)('your describe block', () => {
Ciò salta condizionalmente tutti i test nel blocco di descrizione SE la condizione è falsa.
Oppure, anziché:
it('your it block', () => {
Tu vuoi:
(condition ? it : it.skip)('your it block', () => {
Ciò salta condizionalmente un test SE la condizione è falsa.
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
quindi puoi usarla: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
Uso il runtime saltando da Mocha per lo stesso scenario che stai descrivendo. È il copia incolla dai documenti :
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
Come puoi vedere, salta il test in base all'ambiente. La mia condizione è if(process.env.NODE_ENV === 'continuous-integration')
.
if (/* skipTestCondition */) return this.skip();
- modifica: funziona: D
describe.skip
oit.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
oit.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Maggiori informazioni su https://mochajs.org/#inclusive-tests
Dipende da come si desidera saltare il test a livello di programmazione. Se è possibile determinare le condizioni per saltare prima dell'esecuzione di qualsiasi codice di test, è possibile chiamare it
o it.skip
se necessario, in base a una condizione. Ad esempio, questo salterà alcuni test se la variabile di ambiente ONE
è impostata su qualsiasi valore:
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!");
});
});
Se le condizioni che si desidera verificare possono essere determinate solo al momento del test, è un po 'più complicato. Se non desideri accedere a qualcosa che non sia strettamente parte dell'API di test, puoi farlo:
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!");
});
});
Mentre il mio primo esempio è stato quello di contrassegnare i test come saltati formalmente (aka "in attesa"), il metodo che ho appena mostrato eviterà di eseguire il test effettivo ma i test non saranno contrassegnati come saltati formalmente. Saranno contrassegnati come passati. Se vuoi assolutamente farli saltare, non conosco affatto l'accesso alle parti che non stanno parlando correttamente dell'API di test:
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!");
});
});
Non sono sicuro che ciò si qualifichi come "salto programmatico", ma per saltare selettivamente alcuni test specifici per il nostro ambiente CI, utilizzo la funzione di tagging di Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ). In describe()
o it()
messaggi, puoi aggiungere un tag come @ no-ci. Per escludere questi test, si potrebbe definire un "target ci" specifica nel vostro package.json e l'uso --grep
e --invert
parametri come:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Puoi usare il mio pacchetto mocha-assume per saltare i test a livello di codice, ma solo dall'esterno dei test. Lo usi in questo modo:
assuming(myAssumption).it("does someting nice", () => {});
Mocha-assume eseguirà il test solo quando lo myAssumption
è true
, altrimenti lo salterà (usando it.skip
) con un bel messaggio.
Ecco un esempio più dettagliato:
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... */
});
});
});
Usandolo in questo modo, puoi evitare guasti a cascata. Supponiamo che il test "Does something cool"
fallisca sempre quando someAssumption non regge - Ma questo presupposto è già stato testato sopra (in Tests that verify someAssuption is always true"
).
Quindi il fallimento del test non ti dà nuove informazioni. In realtà, è persino un falso positivo: il test non è fallito perché "qualcosa di interessante" non ha funzionato, ma perché un prerequisito per il test non è stato soddisfatto. con mocha-assume
te puoi spesso evitare tali falsi positivi.
beforeAll
gancio non è garantito per l'esecuzione prima che tutti i test vengano raccolti. In realtà, è molto probabile che venga eseguito solo in seguito, ma in questo caso assuming(someAssumption)
avrebbe già ricevuto il valore iniziale (non definito). È necessario avvolgere anche quella parte in una funzione per ottenere l'effetto desiderato.
Possiamo scrivere una bella funzione wrapper pulito per eseguire in modo condizionale i test come segue:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
Questo può quindi essere richiesto e utilizzato nei test come segue:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
Supponiamo che volessi saltare il mio test parametrizzato se la mia descrizione del test contenesse la stringa "pippo", farei questo:
// 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
});
});
Nel tuo caso, credo che se volessi controllare le variabili di ambiente, potresti usare NodeJS:
process.env.ENV_VARIABLE
Ad esempio (Attenzione: non ho testato questo bit di codice!), Forse qualcosa del genere:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
Dove puoi impostare ENV_VARIABLE in modo che sia qualsiasi cosa tu stia digitando, e usando quel valore, salta o esegui il test. (Cordiali saluti, la documentazione per process.env di NodeJS è qui: https://nodejs.org/api/process.html#process_process_env )
Non mi prenderò completamente il merito per la prima parte di questa soluzione, ho trovato e testato la risposta e ha funzionato perfettamente per saltare i test basati su una semplice condizione attraverso questa risorsa: https://github.com/mochajs/mocha/issues / 591
Spero che questo ti aiuti! :)
Questo non sta davvero usando le funzionalità di moka, ma piuttosto modificandolo per ottenere il comportamento che volevo.
Volevo saltare qualsiasi "è" successivo nei miei test moka per goniometri e uno "esso" non è riuscito. Questo perché una volta fallito un passaggio di un test di viaggio, era quasi certo che il resto avrebbe avuto esito negativo e potrebbe richiedere molto tempo ed eseguire il build server se utilizzano il browser in attesa che gli elementi appaiano su una pagina ecc.
Quando si eseguono semplicemente test moka standard (non goniometro), questo può essere ottenuto con i ganci globali prima di ogni e dopo ogni attacco attaccando un flag 'skipSubsequent' al genitore del test (descrivendolo) in questo modo:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
Quando si tenta di farlo con goniometro e moka, l'ambito di "questo" è cambiato e il codice sopra non funziona. Si finisce con un messaggio di errore del tipo 'error call done ()' e il goniometro si ferma.
Invece ho finito con il codice qui sotto. Non il più bello, ma finisce per sostituire l'implementazione delle funzioni di test rimanenti con questo this.skip (). Questo probabilmente smetterà di funzionare se / quando gli interni di moka cambieranno con le versioni successive.
È stato scoperto attraverso alcuni tentativi ed errori eseguendo il debug e ispezionando gli interni di moka ... aiuta a completare le suite di test del browser prima che i test falliscano.
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>
Quando @danielstjules ha risposto qui c'è un modo per saltare il test. L'autore di questo argomento ha copiato la risposta dalla discussione su mochajs github.com, ma non ci sono informazioni su quale versione di mocha è disponibile.
Sto usando il modulo grunt-mocha-test per integrare la funzionalità del test mocha nel mio progetto. Passa all'ultima versione (per ora) - 0.12.7 portami mocha versione 2.4.5 con l'implementazione di this.skip ().
Quindi, nel mio package.json
"devDependencies": {
"grunt-mocha-test": "^0.12.7",
...
E poi
npm install
E mi rende felice con questo gancio:
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();
}
...
Per favore, no. Un test che non funziona in modo coerente in tutti gli ambienti dovrebbe essere riconosciuto come tale dall'infrastruttura di build. E può essere molto disorientante quando i build CI hanno un numero diverso di test eseguiti rispetto a quelli locali.
Inoltre, aumenta la ripetibilità. Se diversi test vengono eseguiti sul server e sul locale, posso avere test che falliscono in dev e passano in CI o viceversa. Non esiste alcuna funzione di forzatura e non ho modo di correggere in modo rapido e preciso una build fallita.
Se è necessario disattivare i test tra ambienti, anziché eseguirli in modo condizionale, contrassegnare i test e utilizzare un filtro per eliminare i test che non funzionano in determinati target di build. In questo modo tutti sanno cosa sta succedendo e tempera le loro aspettative. Inoltre, consente a tutti di sapere che esiste un'incoerenza nel framework di test e che qualcuno potrebbe avere una soluzione che li riavvia correttamente. Se si silenzia il test, potrebbero anche non sapere che c'è un problema.
this.skip()
a livello di programmazione un test è coperto da mochajs.org/#inclusive-tests e dalla risposta di @ zatziky di seguito. Le altre risposte sono obsolete per Mocha v3 +