J'ai un code où certains tests échoueront toujours dans l'environnement CI. Je voudrais les désactiver en fonction d'une condition d'environnement.
Comment ignorer par programme un test dans mocha pendant l'exécution du runtime?
J'ai un code où certains tests échoueront toujours dans l'environnement CI. Je voudrais les désactiver en fonction d'une condition d'environnement.
Comment ignorer par programme un test dans mocha pendant l'exécution du runtime?
Réponses:
Vous pouvez sauter les tests en plaçant un x devant le bloc describe ou it, ou en plaçant un .skip
après.
xit('should work', function (done) {});
describe.skip('features', function() {});
Vous pouvez également exécuter un seul test en plaçant un .only
sur le test. par exemple
describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
Seul le bloc fonctionnalité 2 s'exécuterait dans ce cas.
Il ne semble pas y avoir de moyen d'ignorer les tests par programme, mais vous pouvez simplement effectuer une sorte de vérification dans une beforeEach
instruction et exécuter le test uniquement si l'indicateur a été défini.
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
appel s'exécute, Mocha enregistre la fonction anonyme (le «hook») pour une utilisation future , lorsque l' describe
appel s'exécute, Mocha exécute immédiatement la fonction anonyme qui lui est passée. Ainsi, au moment de l' if (runTest)
exécution, le beforeEach
hook ne sera pas exécuté.
Il existe un moyen non documenté de sauter des tests par programme:
// test.js
describe('foo', function() {
before(function() {
this.skip();
});
it('foo', function() {
// will not run
console.log('This will not be printed');
});
});
fonctionnement:
$ mocha test.js
foo
- foo
0 passing (9ms)
1 pending
Ceci est discuté dans https://github.com/mochajs/mocha/issues/1901 .
describe
comme ignoré (c'est-à-dire que tous les tests du describe
sont sautés).
Cette réponse fonctionne pour ES6 .
Au lieu de:
describe('your describe block', () => {
Tu veux:
(condition ? describe : describe.skip)('your describe block', () => {
Cela saute conditionnellement tous les tests du bloc de description SI la condition est fausse.
Ou, au lieu de:
it('your it block', () => {
Tu veux:
(condition ? it : it.skip)('your it block', () => {
Cela saute conditionnellement un test SI la condition est fausse.
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
vous pouvez ensuite l'utiliser: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
J'utilise le saut d'exécution de Mocha pour le même scénario que celui que vous décrivez. C'est le copier-coller de la documentation :
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
Comme vous pouvez le voir, il ignore le test basé sur l'environnement. Ma propre condition est if(process.env.NODE_ENV === 'continuous-integration')
.
if (/* skipTestCondition */) return this.skip();
- edit: works: D
describe.skip
ouit.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
ouit.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Plus d'informations sur https://mochajs.org/#inclusive-tests
Cela dépend de la manière dont vous souhaitez ignorer le test par programmation. Si les conditions de saut peuvent être déterminées avant l'exécution de tout code de test, vous pouvez simplement appeler it
ou it.skip
au besoin, en fonction d'une condition. Par exemple, cela sautera certains tests si la variable d'environnement ONE
est définie sur une valeur quelconque:
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!");
});
});
Si les conditions que vous souhaitez vérifier ne peuvent être déterminées qu'au moment du test, c'est un peu plus compliqué. Si vous ne souhaitez pas accéder à quelque chose qui ne fait pas à proprement parler partie de l'API de test, vous pouvez le faire:
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!");
});
});
Alors que mon premier exemple marquait les tests comme étant formellement ignorés (aka "en attente"), la méthode que je viens de montrer évitera simplement d'effectuer le test proprement dit, mais les tests ne seront pas marqués comme formellement ignorés. Ils seront marqués comme réussis. Si vous voulez absolument les faire sauter, je ne connais aucun moyen d'accéder à des parties qui ne font pas à proprement parler partie de l'API de 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!");
});
});
Je ne suis pas sûr que cela soit qualifié de «saut de programmation», mais afin de sauter de manière sélective certains tests spécifiques pour notre environnement CI, j'utilise la fonction de marquage de Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ). Dans describe()
ou it()
messages, vous pouvez ajouter une balise comme @ no-ci. Pour exclure ces tests, vous pouvez définir une "cible ci" spécifique dans votre package.json et utiliser --grep
et des --invert
paramètres tels que:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Vous pouvez utiliser mon package mocha-assume pour sauter les tests par programme, mais uniquement en dehors des tests. Vous l'utilisez comme ceci:
assuming(myAssumption).it("does someting nice", () => {});
Mocha-assume n'exécutera votre test que lorsque myAssumption
c'est true
, sinon il l'ignorera (en utilisant it.skip
) avec un joli message.
Voici un exemple plus détaillé:
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... */
});
});
});
En l'utilisant de cette façon, vous pouvez éviter les échecs en cascade. Supposons que le test "Does something cool"
échoue toujours lorsque certaines hypothèses ne tiennent pas - Mais cette hypothèse a déjà été testée ci-dessus (in Tests that verify someAssuption is always true"
).
L'échec du test ne vous donne donc aucune nouvelle information. En fait, c'est même un faux positif: le test n'a pas échoué parce que "quelque chose de cool" n'a pas fonctionné, mais parce qu'une condition préalable au test n'était pas remplie. avec mocha-assume
vous pouvez souvent éviter ces faux positifs.
beforeAll
exécution du hook n'est pas garantie avant que tous les tests ne soient collectés. En fait, il est très probable qu'il ne s'exécute qu'après, mais dans ce cas, assuming(someAssumption)
il aurait déjà reçu la valeur initiale (non définie). Il est également nécessaire d'envelopper cette partie dans une fonction pour obtenir l'effet souhaité.
Nous pouvons écrire une belle fonction de wrapper propre pour exécuter des tests conditionnellement comme suit:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
Cela peut ensuite être requis et utilisé dans vos tests comme suit:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
Disons que je voulais ignorer mon test paramétré si ma description de test contenait la chaîne "foo", je ferais ceci:
// 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
});
});
Dans votre cas, je crois que si vous vouliez vérifier les variables d'environnement, vous pourriez utiliser NodeJS:
process.env.ENV_VARIABLE
Par exemple (Attention: je n'ai pas testé ce bout de code!), Peut-être quelque chose comme ceci:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
Là où vous pouvez définir ENV_VARIABLE comme étant ce que vous saisissez, et en utilisant cette valeur, ignorez ou exécutez le test. (Pour info, la documentation du process.env de NodeJS est ici: https://nodejs.org/api/process.html#process_process_env )
Je ne prendrai pas le crédit complet pour la première partie de cette solution, j'ai trouvé et testé la réponse et cela a parfaitement fonctionné pour sauter des tests basés sur une condition simple via cette ressource: https://github.com/mochajs/mocha/issues / 591
J'espère que cela t'aides! :)
Cela n'utilise pas vraiment les fonctionnalités de moka, mais plutôt le peaufiner pour obtenir le comportement que je voulais.
Je voulais sauter tout «c'est» ultérieur dans mes tests de moka de rapporteur et un «il» a échoué. En effet, une fois qu'une étape d'un test de parcours a échoué, il était presque certain que le reste échouerait, et pourrait prendre beaucoup de temps et monopoliser le serveur de construction s'ils utilisent le navigateur, attend que les éléments apparaissent sur une page, etc.
Lorsque vous exécutez simplement des tests moka standard (pas de rapporteur), cela peut être réalisé avec les crochets globaux beforeEach et afterEach en attachant un drapeau `` skipSubsequent '' au parent du test (décrire) comme ceci:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
En essayant cela avec le rapporteur et le moka, la portée de «ceci» a changé et le code ci-dessus ne fonctionne pas. Vous vous retrouvez avec un message d'erreur comme «erreur d'appel terminé ()» et le rapporteur s'arrête.
Au lieu de cela, j'ai fini avec le code ci-dessous. Pas la plus jolie, mais elle finit par remplacer l'implémentation des fonctions de test restantes par un this.skip (). Cela cessera probablement de fonctionner si / quand les éléments internes de mocha changent avec les versions ultérieures.
Il a été découvert grâce à des essais et des erreurs en déboguant et en inspectant les composants internes de mocha ... cela permet de compléter les suites de tests du navigateur plus tôt lorsque les tests échouent.
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>
Comme @danielstjules a répondu ici il existe un moyen de sauter le test. @author of this topic a copié la réponse de la discussion mochajs de github.com, mais il n'y a aucune information sur la version de mocha disponible.
J'utilise le module grunt-mocha-test pour intégrer la fonctionnalité de test moka dans mon projet. Passer à la dernière version (pour l'instant) - 0.12.7 m'apporte la version 2.4.5 mocha avec l'implémentation de this.skip ().
Donc, dans mon package.json
"devDependencies": {
"grunt-mocha-test": "^0.12.7",
...
Puis
npm install
Et ça me fait plaisir avec ce crochet:
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();
}
...
Veuillez ne pas le faire. Un test qui ne fonctionne pas de manière cohérente dans tous les environnements doit être reconnu comme tel par votre infrastructure de build. Et cela peut être très désorientant lorsque les builds CI ont un nombre de tests différents que local.
En outre, cela gâche la répétabilité. Si différents tests s'exécutent sur le serveur et en local, je peux avoir des tests échouant en dev et passant en CI ou vice versa. Il n'y a pas de fonction de forçage et je n'ai aucun moyen de corriger rapidement et avec précision une construction qui a échoué.
Si vous devez désactiver les tests entre les environnements, au lieu d'exécuter des tests de manière conditionnelle, marquez vos tests et utilisez un filtre pour éliminer les tests qui ne fonctionnent pas dans certaines cibles de build. De cette façon, tout le monde sait ce qui se passe et cela tempère leurs attentes. Cela permet également à tout le monde de savoir qu'il y a des incohérences dans le cadre de test, et que quelqu'un pourrait avoir une solution qui les remet en marche correctement. Si vous désactivez simplement le test, ils pourraient même ne pas savoir qu'il y a un problème.
this.skip()
dans mochajs.org/#inclusive-tests et la réponse de @ zatziky ci-dessous. Le reste des réponses est obsolète pour Mocha v3 +