Подтвердить что ты не робот

Как программно пропустить тест в мокко?

У меня есть код, в котором определенные тесты всегда будут терпеть неудачу в среде CI. Я хотел бы отключить их в зависимости от условий среды.

Как программно пропустить тест в мокко во время выполнения?

4b9b3361

Ответ 1

Существует недокументированный способ программного пропуска тестов:

// test.js

describe('foo', function() {
  before(function() {
    this.skip();
  });

  it('foo', function() {
    // will not run
    console.log('This will not be printed');
  });
});

Бег:

$ mocha test.js


  foo
    - foo


  0 passing (9ms)
  1 pending

Это обсуждается в https://github.com/mochajs/mocha/issues/1901.

Ответ 2

Вы можете пропустить тесты, поставив x перед описанием или блоком или разместив .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,
         }
    }
}

Ответ 3

Этот ответ действительно работает для ES6.

Вместо:

describe('your describe block', () => {

Ты хочешь:

(condition ? describe : describe.skip)('your describe block', () => {

Это условно пропускает все тесты в блоке описания, если условие ложно.

Или вместо:

it('your it block', () => {

Ты хочешь:

(condition ? it : it.skip)('your it block', () => {

Это условно пропускает один тест, если условие ложно.

Ответ 4

Я использую пропущение во время выполнения из 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').

Ответ 5

Это зависит от того, как вы хотите программно пропустить тест. Если условия для пропусков могут быть определены до запуска любого тестового кода, вы можете просто вызвать 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!");
    });

});

Ответ 6

пропустить тесты, использовать 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

Ответ 7

Мы можем написать красивую чистую функцию-обертку для условного запуска тестов следующим образом:

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();
});

Ответ 8

Вы можете использовать мой пакет mocha-assume, чтобы пропустить тесты программно, но только извне тестов. Вы используете его следующим образом:

assuming(myAssumption).it("does someting nice", () => {});

Mocha-предполагается запускать ваш тест только тогда, когда 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 вы можете часто избегать таких ложных срабатываний.

Ответ 9

Я не уверен, что это квалифицируется как "программный пропуск", но для того, чтобы выборочно пропустить некоторые конкретные тесты для нашей среды 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"
}

Ответ 10

Скажем, я хотел пропустить мой параметризованный тест, если в описании теста содержалась строка "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 как то, что вы отключаете, и используя это значение, пропустите или запустите тест. (FYI документация для процесса process.env для NodeJS находится здесь: https://nodejs.org/api/process.html#process_process_env)

Я не буду полностью отвечать за первую часть этого решения, я нашел и протестировал ответ, и он отлично работал, чтобы пропустить тесты на основе простого состояния через этот ресурс: https://github.com/mochajs/mocha/issues/591

Надеюсь, это поможет!:)

Ответ 12

На самом деле это не использование мокко-функций, а настройка его для получения желаемого поведения.

Я хотел пропустить любое последующее "это" в моих тестах мокко-протранграфа, и один "он" потерпел неудачу. Это было связано с тем, что, как только один шаг теста на поездку провалился, было почти наверняка, что остальное будет терпеть неудачу, и может занять много времени и запугать сервер сборки, если они используют браузер, ожидая появления элементов на странице и т.д.

Когда вы запускаете стандартные тесты mocha (а не транспортир), это может быть достигнуто с помощью global beforeEach и afterEach hooks, добавив флаг "skipSubsequent" в тестовый родительский элемент (описать) следующим образом:

    beforeEach(function() {
      if(this.currentTest.parent.skipSubsequent) {
            this.skip();
      }
    }); 


    afterEach(function() {
      if (this.currentTest.state === 'failed') {
        this.currentTest.parent.skipSubsequent = 'true'
      }
    })

При попытке сделать это с помощью транспортира и мокко, область действия 'this' изменилась, а код выше не работает. В результате вы получите сообщение об ошибке, например "Ошибка вызова 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'
    }
});

Ответ 13

Как @danielstjules ответил здесь, есть способ пропустить тест. @author этой темы скопировал ответ из обсуждения mathajs от github.com, но нет никакой информации о том, какая версия мокко доступна.

Я использую модуль grunt-mocha-test для интеграции функций тестирования мокки в моем проекте. Переход к последней (на данный момент) версии - 0.12.7 принесите мне мокко версию 2.4.5 с реализацией this.skip().

Итак, в моем пакете .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();
        }

        ...

Ответ 14

Пожалуйста, не надо. Тест, который не работает последовательно в разных средах, должен быть признан таковой вашей инфраструктурой построения. И это может быть очень дезориентирующим, когда CI-сборки имеют различное количество тестов, чем локальные.

Также он закручивает повторяемость. Если разные тесты выполняются на сервере и локальном, у меня могут быть неудачные тесты в dev и передача в CI или наоборот. Там нет принудительной функции, и у меня нет возможности быстро и точно исправить неудачную сборку.

Если вы должны отключить тесты между средами, вместо условно запускаемых тестов, пометьте свои тесты и используйте фильтр, чтобы исключить тесты, которые не работают в определенных целях сборки. Таким образом, все знают, что происходит, и это мешает их ожиданиям. Это также позволяет всем знать, что существует несогласованность в тестовой структуре, и у кого-то может быть решение, которое заставляет их работать должным образом снова. Если вы просто отключите тест, они могут даже не знать о проблеме.