У мене є код, де певні тести завжди будуть провалюватися в середовищі CI. Я хотів би відключити їх на основі стану навколишнього середовища.
Як програмно пропустити тест на мокко під час виконання програми?
У мене є код, де певні тести завжди будуть провалюватися в середовищі CI. Я хотів би відключити їх на основі стану навколишнього середовища.
Як програмно пропустити тест на мокко під час виконання програми?
Відповіді:
Ви можете пропустити тести, поставивши х перед описом або блоком, або розмістивши .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
гачок не запуститься.
Існує недокументований спосіб програмно пропускати тести:
// 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/isissue/1901 .
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', () => {
(it)('my test', () => {})
Я використовую пропуск у 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. Щоб виключити ці тести, ви можете визначити конкретну "цільову ціль" у своєму пакеті.json та використовувати --grep
та --invert
такі параметри, як:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Ви можете використовувати мій пакунок mocha-припустити, щоб пропустити тести програмно, але тільки ззовні тестів. Ви використовуєте його так:
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
вами часто можна уникати таких помилкових позитивних результатів.
beforeAll
Крюк не гарантована працювати , перш ніж всі тести зібрані. Насправді, дуже ймовірно, що він буде запущений лише після цього, але в цьому випадку він assuming(someAssumption)
би вже отримав початкове (невизначене) значення. Цю частину потрібно також загорнути у функцію, щоб досягти бажаного ефекту.
Ми можемо написати гарну чисту функцію обгортки для умовного виконання тестів наступним чином:
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();
});
Скажіть, що я хотів пропустити параметризований тест, якщо мій опис тесту містив рядок "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 документація для NodeJS 'process.env знаходиться тут: https://nodejs.org/api/process.html#process_process_env )
Я не візьму на себе повну оцінку за першу частину цього рішення, я знайшов і перевірив відповідь, і він прекрасно працював, щоб пропустити тести на основі простої умови через цей ресурс: https://github.com/mochajs/mocha/isissue / 591
Сподіваюся, це допомагає! :)
Це насправді не використовує особливості моккі, скоріше налаштовуючи її, щоб отримати таку поведінку, яку я хотів.
Я хотів пропустити будь-яке наступне "це" в моїх тестах транспортування мотора, і одне "це" не вдалося. Це було тому, що коли один крок тестування не вдався, майже було впевнене, що решта не вдасться, і це може зайняти тривалий час та зависнути сервер збірки, якщо вони використовують браузер, чекає, коли елементи з’являться на сторінці тощо.
Якщо ви просто виконуєте стандартні тести на мокко (не транспортир), це можна досягти за допомогою глобальних гаків передEEE і AfterEach, додавши прапор 'skipSubsequent' до батьківського тесту (опишіть) так:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
При спробі цього за допомогою транспортира та мокше його сфера застосування "це" змінилася, і код вище не працює. У вас з'являється повідомлення про помилку, наприклад "помилка виклику зроблено ()" і транспортир зупиняється.
Натомість я опинився з кодом нижче. Не найкрасивіший, але він закінчується заміною реалізації інших тестових функцій на 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'
}
});
mocha test/ --grep <pattern>
Як тут відповів @danielstjules є спосіб пропустити тест. @author з цієї теми скопіював відповідь з дискусії github.com mochajs, але немає інформації, у якій версії mocha вона доступна.
Я використовую модуль 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();
}
...
Будь ласка, не варто. Тест, який не працює послідовно в різних середовищах, повинен бути визнаний вашою інфраструктурою побудови. І це може бути дуже дезорієнтуючим, коли в побудовах CI працює інша кількість тестів, ніж у місцевих.
Також він прикручує повторюваність. Якщо на сервері та локальному сервері працюють різні тести, я можу мати тести, що не спрацьовують у програмі dev та проходять у CI або навпаки. Немає функції примушування, і я не маю можливості швидко та точно виправити помилкову збірку.
Якщо ви повинні вимкнути тести між середовищами, замість умовно запущених тестів, позначте свої тести та використовуйте фільтр для усунення тестів, які не працюють у певних цілях збирання. Таким чином, всі знають, що відбувається, і це гартує їхні очікування. Це також дає всім знати, що в тестовій структурі є непослідовність, і хтось може мати рішення, яке знов запустить їх належним чином. Якщо ви просто заглушите тест, вони можуть навіть не знати, що є проблема.
this.skip()
в mochajs.org/#inclusive-tests та відповіді @ zatziky нижче. Решта відповідей застаріла для Mocha v3 +