J'ai un code où certains tests échoueront toujours dans un environnement CI. Je souhaite les désactiver en fonction d'une condition de l'environnement.
Comment faire pour ignorer un test en mocha par programme lors de l'exécution?
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 .
Vous pouvez ignorer les tests en plaçant un x devant le bloc describe ou it ou en plaçant un .skip
après celui-ci.
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() {});
Dans ce cas, seul le bloc de fonctionnalité 2 sera exécuté.
Il ne semble pas y avoir de moyen de sauter des tests par programme, mais vous pouvez simplement vérifier dans une instruction beforeEach
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,
}
}
}
Cette réponse fonctionne pour ES6.
Au lieu de:
describe('your describe block', () => {
Tu veux:
(condition ? describe : describe.skip)('your describe block', () => {
Cela ignore conditionnellement tous les tests du bloc décrit SI la condition est fausse.
Ou au lieu de:
it('your it block', () => {
Tu veux:
(condition ? it : it.skip)('your it block', () => {
Cela ignore conditionnellement un test SI la condition est fausse.
J'utilise runtime en sautant de Mocha pour le même scénario que vous décrivez. C'est le copier/coller des docs :
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
Comme vous pouvez le constater, le test ignore l’environnement. Ma propre condition est if(process.env.NODE_ENV === 'continuous-integration')
.
Cela dépend de la façon dont vous voulez ignorer le test par programme. Si les conditions pour ignorer peuvent être déterminées avant tout code de test est exécuté, vous pouvez simplement appeler it
ou it.skip
, en fonction des conditions. Par exemple, certains tests seront ignorés 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 accéder à aucun élément ne faisant pas à proprement parler partie de l'API de test, vous pouvez procéder comme suit:
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 consistait à marquer les tests comme étant officiellement ignorés (ou "en attente"), la méthode que je viens de montrer évite simplement d'effectuer le test, mais les tests ne sont pas marqués comme étant officiellement ignorés. Ils seront marqués comme passés. Si vous voulez absolument les ignorer, 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!");
});
});
describe.skip
ou it.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
ou it.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Plus d'infos sur https://mochajs.org/#inclusive-tests
Nous pouvons écrire une fonction Nice clean wrapper pour exécuter conditionnellement des tests comme suit:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
Ceci peut alors être requis et utilisé dans vos tests comme suit:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
Je ne sais pas si cela peut être qualifié de "saut programmé", mais pour ignorer de manière sélective certains tests spécifiques à notre environnement CI, j'utilise la fonctionnalité de marquage de Mocha ( https://github.com/mochajs/mocha/wiki/Marquage ). Dans les messages describe()
ou it()
, vous pouvez ajouter une balise du type @ no-ci. Pour exclure ces tests, vous pouvez définir une "cible ci" dans votre package.json et utiliser les paramètres --grep
et --invert
tels que:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Vous pouvez utiliser mon paquetage mocha-assumer pour ignorer 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
est true
, sinon il le sautera (avec it.skip
) avec un message de Nice.
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 manière, vous éviterez les échecs en cascade. Dites que le test "Does something cool"
échouera toujours si une hypothèse ne tient pas - Mais cette hypothèse a déjà été testée ci-dessus (dans Tests that verify someAssuption is always true"
).
Donc, l'échec du test ne vous donne aucune nouvelle information. En fait, il s'agit même d'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'a pas été remplie. avec mocha-assume
vous pouvez souvent éviter de tels faux positifs.
Ceci n'utilise pas vraiment les fonctionnalités de moka, mais plutôt le peaufiner pour obtenir le comportement que je voulais.
Je voulais éviter tout "ça" dans mes tests de moka de rapporteur d'angles et un "ça" a échoué. En effet, une fois qu'une étape d'un test de voyage a échoué, il était presque certain que le reste échouerait et pourrait prendre beaucoup de temps et empêcher le serveur de génération de construire s'il utilise le navigateur en attente des éléments pour apparaître sur une page, etc.
Lorsque vous exécutez uniquement des tests standard moka (et non des rapporteurs), vous pouvez utiliser les points d'ancrage beforeEach et afterEach globaux en associant un indicateur 'skipSubsequent' au parent du test (décrire) comme suit:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
Lorsque vous essayez ceci avec un rapporteur et un moka, la portée de "ceci" a changé et le code ci-dessus ne fonctionne pas. Vous vous retrouvez avec un message d'erreur du type 'erreur appelant done ()' 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 this.skip (). Cela cessera probablement de fonctionner si/lorsque les éléments internes de mocha changent avec les versions ultérieures.
Il a été mis au point au moyen d'essais et d'erreurs en déboguant et en inspectant les éléments internes de Mocha ... aide à rendre les suites de tests de navigateurs terminées plus rapidement 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>
Dites que je voulais ignorer mon test paramétré si la description de ce test contenait la chaîne "foo", je le ferais:
// 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 pense que si vous voulez vérifier les variables d'environnement, vous pouvez utiliser NodeJS:
process.env.ENV_VARIABLE
Par exemple (Attention: je n'ai pas testé ce morceau de code!), Par exemple:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
Où vous pouvez définir ENV_VARIABLE pour être ce que vous voulez, et en utilisant cette valeur, ignorer ou exécuter le test. (Pour info, la documentation du fichier process.env de NodeJS se trouve 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 fonctionnait parfaitement pour ignorer les tests basés sur une condition simple via cette ressource: https://github.com/mochajs/mocha/issues/591
J'espère que cela t'aides! :)