У меня есть код, в котором определенные тесты всегда терпят неудачу в среде CI. Я хотел бы отключить их в зависимости от условий окружающей среды.
Как программно пропустить тест в мокко во время выполнения?
У меня есть код, в котором определенные тесты всегда терпят неудачу в среде CI. Я хотел бы отключить их в зависимости от условий окружающей среды.
Как программно пропустить тест в мокко во время выполнения?
Ответы:
Вы можете пропустить тесты, поместив x перед блоком description или it или поставив .skip
после него.
xit('should work', function (done) {});
describe.skip('features', function() {});
Вы также можете запустить одиночный тест, поместив .only
на него значок. например
describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
В этом случае будет работать только блок функции 2.
Кажется, не существует способа программно пропустить тесты, но вы могли бы просто выполнить какую-то проверку в beforeEach
инструкции и запустить тест только в том случае, если был установлен флаг.
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
вызов выполняется, Mocha записывает анонимную функцию («ловушку») для будущего использования, при выполнении describe
вызова Mocha немедленно выполняет переданную ему анонимную функцию. Таким образом, к моменту if (runTest)
выполнения beforeEach
хук не сработает.
skip()
функцию MochaЕго можно использовать либо для статического отключения теста или всего набора, либо для динамического пропуска его во время выполнения.
Вот пример использования среды выполнения:
it('should only test in the correct environment', function() {
if (/* check test environment */) {
// make assertions
} else {
this.skip();
}
});
describe
как пропущенное (т.е. все тесты в describe
списке пропускаются).
Этот ответ работает для ES6 .
Вместо того:
describe('your describe block', () => {
Вы хотите:
(condition ? describe : describe.skip)('your describe block', () => {
Это условно пропускает все тесты в блоке описания, ЕСЛИ условие ложно.
Или вместо:
it('your it block', () => {
Вы хотите:
(condition ? it : it.skip)('your it block', () => {
Это условно пропускает один тест, ЕСЛИ условие ложно.
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
затем вы можете его использовать: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
function
или, async function
а затем вы можете вызывать по this.skip()
мере необходимости, возможно, после выполнения некоторой асинхронной операции, чтобы проверить, нужно ли вам запускать тест.
Я использую пропуск времени выполнения из Mocha для того же сценария, который вы описываете. Это копипаст из документов :
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
Как видите, тест пропускается в зависимости от среды. Мое собственное состояние такое if(process.env.NODE_ENV === 'continuous-integration')
.
if (/* skipTestCondition */) return this.skip();
- редактировать: работает: D
describe.skip
илиit.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
илиit.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Больше информации на https://mochajs.org/#inclusive-tests
Это зависит от того, как вы хотите программно пропустить тест. Если условия пропуска могут быть определены до запуска любого тестового кода, вы можете просто вызвать it
или по it.skip
мере необходимости в зависимости от условия. Например, это приведет к пропуску некоторых тестов, если для переменной среды ONE
установлено любое значение:
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!");
});
});
Если условия, которые вы хотите проверить, можно определить только во время теста, это немного сложнее. Если вы не хотите получать доступ к чему-либо, кроме строго говоря, части API тестирования, вы можете сделать это:
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!");
});
});
В то время как в моем первом примере тесты помечались как формально пропущенные (также известные как «ожидающие»), метод, который я только что показал, просто не будет выполнять фактический тест, но тесты не будут отмечены как формально пропущенные. Они будут отмечены как пройденные. Если вы абсолютно хотите, чтобы они были пропущены, я не знаю другого способа получить доступ к частям, которые, собственно, не являются частью API тестирования:
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!");
});
});
Я не уверен, можно ли это квалифицировать как «программный пропуск», но для того, чтобы выборочно пропустить некоторые конкретные тесты для нашей среды CI, я использую функцию тегов Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ). В сообщениях describe()
или it()
вы можете добавить тег, например @ no-ci. Чтобы исключить эти испытания, можно определить специфический «CI целевой» в вашем package.json и использования --grep
и --invert
параметров , как:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Мы можем написать красивую чистую функцию-оболочку для условного запуска тестов следующим образом:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
Затем это может потребоваться и использоваться в ваших тестах следующим образом:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
Вы можете использовать мой пакет mocha-accept для программного пропуска тестов, но только вне тестов. Вы используете это так:
assuming(myAssumption).it("does someting nice", () => {});
Mocha-accept будет запускать ваш тест только тогда , когда он myAssumption
есть true
, иначе он пропустит его (используя it.skip
) с приятным сообщением.
Вот более подробный пример:
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... */
});
});
});
Таким образом можно избежать каскадных сбоев. Скажем, тест "Does something cool"
всегда будет терпеть неудачу, если какое-то предположение не выполняется - но это предположение уже было проверено выше (в Tests that verify someAssuption is always true"
).
Таким образом, ошибка теста не дает вам никакой новой информации. Фактически, это даже ложноположительный результат: тест не прошел, потому что «что-то классное» не сработало, а потому, что предварительное условие для теста не было выполнено. с mocha-assume
вами часто можно избежать таких ложных срабатываний.
beforeAll
ловушки не гарантируется, пока не будут собраны все тесты. На самом деле, скорее всего, он запустится только после этого, но в этом случае assuming(someAssumption)
он уже получил бы начальное (неопределенное) значение. Эту часть также необходимо обернуть функцией, чтобы добиться желаемого эффекта.
На самом деле это не использование функций мокко, а скорее настройка его для получения желаемого поведения.
Я хотел пропустить любое последующее «это» в моих тестах на транспортир мокко, и одно «оно» не удалось. Это было связано с тем, что после того, как один шаг теста не пройден, почти наверняка остальное не удастся, и это может занять много времени и перегружать сервер сборки, если они используют браузер, ожидая появления элементов на странице и т. Д.
При запуске стандартных тестов мокко (не транспортира) это может быть достигнуто с помощью глобальных хуков beforeEach и afterEach, прикрепив флаг skipSubsequent к родительскому элементу теста (описать) следующим образом:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
При попытке сделать это с транспортиром и мокко он изменился, и приведенный выше код не работает. Вы получаете сообщение об ошибке, такое как «вызов ошибки done ()», и транспортир останавливается.
Вместо этого я получил код ниже. Не самое красивое, но в итоге реализация оставшихся тестовых функций заменяется this.skip (). Это, вероятно, перестанет работать, если / когда внутреннее устройство мокко изменится с более поздними версиями.
Это было выяснено путем проб и ошибок путем отладки и проверки внутренних компонентов мокко ... тем не менее, это помогает ускорить завершение тестов браузера, когда тесты терпят неудачу.
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'
}
});
Скажем, я хотел бы пропустить параметризованный тест, если бы мое описание теста содержало строку «foo», я бы сделал следующее:
// 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
});
});
В вашем случае я считаю, что если вы хотите проверить переменные среды, вы можете использовать NodeJS:
process.env.ENV_VARIABLE
Например (Предупреждение: я не тестировал этот фрагмент кода!), Может быть что-то вроде этого:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
Где вы можете установить ENV_VARIABLE как то, что вы отключили, и, используя это значение, пропустить или запустить тест. (К вашему сведению, документация для NodeJS process.env находится здесь: https://nodejs.org/api/process.html#process_process_env )
Я не буду полностью доверять первой части этого решения, я нашел и протестировал ответ, и он отлично сработал, чтобы пропустить тесты на основе простого условия через этот ресурс: https://github.com/mochajs/mocha/issues / 591
Надеюсь это поможет! :)
mocha test/ --grep <pattern>
Как @danielstjules отвеченного здесь есть способ , чтобы пропустить тест. @author этой темы скопировал ответ из обсуждения mochajs на github.com, но нет информации, в какой версии mocha он доступен.
Я использую модуль grunt-mocha-test для интеграции функциональности теста мокко в свой проект. Переходим к последней (на данный момент) версии - 0.12.7, принеси мне версию мокко 2.4.5 с реализацией this.skip ().
Итак, в моем package.json
"devDependencies": {
"grunt-mocha-test": "^0.12.7",
...
А потом
npm install
И меня радует этот крючок:
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();
}
...
Пожалуйста, не надо. Тест, который не работает единообразно в разных средах, должен признаваться вашей инфраструктурой сборки. И это может очень дезориентировать, когда в CI-сборках выполняется другое количество тестов, чем локальных.
Также это портит повторяемость. Если разные тесты выполняются на сервере и локально, у меня могут быть тесты, которые не проходят в dev и проходят в CI или наоборот. Нет функции принуждения, и у меня нет возможности быстро и точно исправить неудачную сборку.
Если вам необходимо отключить тесты между средами, вместо условного запуска тестов, пометьте свои тесты и используйте фильтр для исключения тестов, которые не работают в определенных целях сборки. Таким образом, все знают, что происходит, и это умеряет их ожидания. Это также позволяет всем узнать, что в тестовой среде есть несоответствия, и у кого-то может быть решение, которое снова заставит их работать правильно. Если вы просто отключите звук теста, они могут даже не знать о проблеме.
this.skip()
в ответах mochajs.org/#inclusive-tests и @ zatziky ниже. Остальные ответы устарели для Mocha v3 +