Mocha: Сгенерированные данные тестовые случаи (параметризованные тесты)

Созданный на 28 нояб. 2014  ·  31Комментарии  ·  Источник: mochajs/mocha

На данный момент создание нескольких тестовых случаев, которые отличаются только входными данными, довольно громоздко:

describe('prime number checker', function() {
  [2,3,5,7].forEach(function(value) {
    it('returns true for prime number ' + value, function() {
      expect(isPrime(value)).to.be.true();
    });

  [4,6,8,9].forEach(function(value) {
    it('returns false for composite number ' + value, function() {
      expect(isPrime(value)).to.be.false();
    });
});

Я предлагаю расширить текущий API синтаксическим сахаром для тестовых примеров, сгенерированных данными, добавив необязательный второй параметр как к it и к describe , этот параметр будет массивом точек данных для тестирования .

describe('prime number checker', function() {
  it('returns true for prime numbers', [2,3,5,7], function(data) {
    expect(isPrime(data)).to.be.true();
  });

  it('returns false for composite number', [4,6,8,9], function(data) {
    expect(isPrime(data)).to.be.false();
  });
});

Более сложный пример:

var SAMPLES = [
  { scheme: 'http', host: 'localhost', path: '/', url: 'http://localhost/' },
  { scheme: 'https', host: '127.0.0.1', path: '/test', url: 'https://127.0.0.1/test' }
];

describe('url helper', SAMPLES, function(data) {
  it('builds url from components', function() {
    var str = urlHelper.build({ scheme: data.scheme, host: data.host, path: data.path });
    expect(str).to.equal(data.url);
  });

  it('parses url into components', function() {
    var components = urlHelper.parse(data.url);
    expect(components).to.eql({ scheme: data.scheme, host: data.host, path: data.path });
  });
});

Я рад внести свой вклад в реализацию.

Цель этого выпуска - обсудить необходимые детали и получить одобрение специалистов по сопровождению, прежде чем я начну писать код.

Относится к # 57.

/ cc @mcollina

Самый полезный комментарий

При всем моем уважении, предлагаемое решение - отстой.

Прежде всего, сообщение об ошибке будет иметь вид «ожидается, что ложь будет истинной», что совершенно бесполезно. Это можно обойти с помощью expect(isPrime(value), value).to.be.true() , но это еще более шаблонный код.

Во-вторых, первый сбой остановит тестовый пример, поэтому вы не узнаете, не прошла ли тест только одна точка данных или их больше. Т.е. при сбое 3 5 и 7 вообще не запускаются.

Есть ли способ реализовать эту функцию как плагин для мокко?

Все 31 Комментарий

describe('prime number checker', function() {
  [2,3,5,7].forEach(function(value) {
    it('returns true for prime number ' + value, function() {
      expect(isPrime(value)).to.be.true();
    });
});

это должно быть сделано как imo:

describe('prime number checker', function() {
    it('should return true for prime numbers', function() {
      [2,3,5,7].forEach(function(value){
        expect(isPrime(value)).to.be.true();  
      });
    });
});

и кажется, что chai мог бы добавить, может даже уже иметь, сопоставитель, который бы взял массив и применил бы к нему fn - в данном случае isPrime.

спасибо за вопрос, но я закрою. я не думаю, что api для этого должен быть в мокко, должен быть в chai et al. если что-нибудь.

При всем моем уважении, предлагаемое решение - отстой.

Прежде всего, сообщение об ошибке будет иметь вид «ожидается, что ложь будет истинной», что совершенно бесполезно. Это можно обойти с помощью expect(isPrime(value), value).to.be.true() , но это еще более шаблонный код.

Во-вторых, первый сбой остановит тестовый пример, поэтому вы не узнаете, не прошла ли тест только одна точка данных или их больше. Т.е. при сбое 3 5 и 7 вообще не запускаются.

Есть ли способ реализовать эту функцию как плагин для мокко?

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

  • .NET NUnit поддерживает параметризованные тесты с версии 2.5, выпущенной в 2009 году.
  • Как и Java JUnit ( документы )
  • Ruby rspec имеет плагины, добавляющие поддержку параметризованных тестов ( param_test , rspec-parameterized )

и кажется, что chai мог бы добавить, может даже уже иметь, сопоставитель, который бы взял массив и применил бы к нему fn - в данном случае isPrime.

Это может помочь в простых примерах, подобных описанному выше, но становится громоздким по мере увеличения длины метода тестирования.

Пример:

it('should return custom 404 response', 
  ['/Products/unknown-id', '/unknown-root', '/images/unknown.jpg'],
  function(url, done) {
    supertest(app).get(url)
      .expect(404)
      .expect('Content-Type', /html/)
      .end(function(err, res) {
        if (err) return done(err);
        expect(res.body).to.contain('<title>Lost your way?</title>');
        done();
      });
  }
);

Прежде всего, сообщение об ошибке будет иметь вид «ожидается, что ложь будет истинной», что совершенно бесполезно. Это можно обойти с помощью expect(isPrime(value), value).to.be.true() , но это еще более шаблонный код.

Позвольте мне перефразировать это.

Сообщение об ошибке «Ожидается, что ложь будет истинной» очень бесполезна, поскольку в нем отсутствует контекст - какое значение проверялось? Это можно обойти с помощью expect(isPrime(value), value).to.be.true() , но это еще больше шаблонный код для написания. И давайте посмотрим правде в глаза, большинство разработчиков не станут этим беспокоиться. Мое решение - это « Яма успеха» , где естественное использование API Mocha предоставляет полезные сообщения об ошибках.

Однако наиболее важным является второй аргумент (первая ошибка прерывает тестовый пример). И опять же, большинство разработчиков не осознают, насколько важно сделать это правильно, и с радостью сделают такие вещи, как

it('returns true for prime numbers', function() {
  expect(isPrime(2)).to.be.true();
  expect(isPrime(3)).to.be.true();
});

Хотя предложенное мной решение не помешает им сделать это, оно, по крайней мере, упростит исправление их тестового кода, чтобы он поступал правильно:

it('returns true for prime numbers', [2, 3], function(num) {
  expect(isPrime(num)).to.be.true();
});

@travisjeffery, не могли бы вы подробнее объяснить, почему вы отклоняете мою идею, и, возможно, дать совет о том, как я могу получить эту функцию без разветвления мокко, например, изменив мокко, чтобы позволить плагинам настраивать it и describe ?

Хорошие моменты там @bajtos.

Я не уверен, что копаю добавление необязательных параметров к функциям it и describe . Как только мы это сделаем, мы практически убьем любые предложения о добавлении любых других необязательных параметров, таких как теги, которые предлагаются в другом потоке. (не похоже, что я тоже добавляю их ..)

Некоторые другие варианты:

var SAMPLES = [
  { scheme: 'http', host: 'localhost', path: '/', url: 'http://localhost/' },
  { scheme: 'https', host: '127.0.0.1', path: '/test', url: 'https://127.0.0.1/test' }
];

describe('url helper', function() {
  it('builds url from components', {using:SAMPLES, tags: [tag1, tag2, tag3]}, function(data) {
    var str = urlHelper.build({ scheme: data.scheme, host: data.host, path: data.path });
    expect(str).to.equal(data.url);
  });
  using(SAMPLES).it('builds url from components', function(data) {
    var str = urlHelper.build({ scheme: data.scheme, host: data.host, path: data.path });
    expect(str).to.equal(data.url);
  });
});

@dasilvacontin Да, я больше думал о тегах. Я не думаю, что добавление дополнительных параметров - это ответ на этот вопрос, но вкратце синтаксис вроде:

this.tags = ['foo', 'bar', 'baz'];

Намного вкуснее.

Во всяком случае, по поводу этого:

  it('returns true for prime numbers', [2,3,5,7], function(data) {
    expect(isPrime(data)).to.be.true();
  });

Что предлагается для обработки асинхронных тестов таким образом? Я представляю себе «больше параметров».

describe('prime number checker', function() {
  [2,3,5,7].forEach(function(value) {
    it('returns true for prime number ' + value, function() {
      expect(isPrime(value)).to.be.true();
    });

  [4,6,8,9].forEach(function(value) {
    it('returns false for composite number ' + value, function() {
      expect(isPrime(value)).to.be.false();
    });
});

Вышеупомянутое выглядит очень похоже на param-test , хотя я не читаю Ruby.

@bajtos Я не уверен, можно ли написать «плагин», который сделает это, но правильным способом будет интерфейс, который, вероятно, «расширяет» интерфейс BDD. Если вы можете предоставить 3p-интерфейс в командной строке (я не могу вспомнить, можете ли вы), тогда вы можете использовать все, что придумаете. Если вы _не__ можете предоставить интерфейс 3p, то вы должны иметь возможность, что станет отличным пиаром.

Это может помочь в простых примерах, подобных описанному выше, но становится громоздким по мере увеличения длины метода тестирования.

it('should return custom 404 response', 
  ['/Products/unknown-id', '/unknown-root', '/images/unknown.jpg'],
  function(url, done) {
    supertest(app).get(url)
      .expect(404)
      .expect('Content-Type', /html/)
      .end(function(err, res) {
        if (err) return done(err);
        expect(res.body).to.contain('<title>Lost your way?</title>');
        done();
      });
  }
);

проблема здесь в том, что у вас есть огромный fn, определенный в середине вашего теста. просто создайте и используйте именованный fn - например, assertUnknown , который также поможет с ясностью и удобочитаемостью, и это не проблема.

вы можете написать свой собственный интерфейс, поддерживающий параметр массива.

В двух словах: для ядра Mocha это не обязательно.

@dasilvacontin Мне нравится предложенный вами using() API:

using(SAMPLES).it('builds url from components', function(data) {

Что предлагается для обработки асинхронных тестов таким образом? Я представляю себе «больше параметров».

См. Пример супертеста в моих комментариях выше: когда тестовый пример параметризован, функция асинхронного тестирования принимает два параметра.

it('should return custom 404 response', 
  ['/Products/unknown-id', '/unknown-root', '/images/unknown.jpg'],
  function(url, done) {
    // etc.
  });

@travisjeffery

проблема здесь в том, что у вас есть огромный fn, определенный в середине вашего теста. просто создайте и используйте именованный fn - например, assertUnknown, который также поможет с ясностью и удобочитаемостью, и это не проблема.

По моему опыту, довольно часто тестовые функции содержат 5-10 строк кода. Есть два способа очистить тестовый код: либо извлечь разделяемую функцию, либо написать параметризованный тест. Оба подхода действительны.

В вашем предложении слишком много ненужных повторяющихся шаблонов.

it('should return custom 404 response for /Products/unknown-id'', function(done) {
  assertUnknown('/Products/unknown-id', done);
});

it('should return custom 404 response for /unknown-root'', function(done) {
  assertUnknown('/Products/unknown-root', done);
});

it('should return custom 404 response for /images/unknown.jpg'', function(done) {
  assertUnknown('/images/unknown.jpg', done);
});

Сравните это с тем, что я предлагаю:

it('should return custom 404 response', 
  ['/Products/unknown-id', '/unknown-root', '/images/unknown.jpg'],
  assertUnknown);

// or perhaps
it('should return custom 404 response', 
  ['/Products/unknown-id', '/unknown-root', '/images/unknown.jpg'],
  function(url, done) {
    assertUnknown(url, done);
  });

В любом случае, ваше предложение написать специального репортера - разумный обходной путь.


Честно говоря, я устаю бороться с тем, что я считаю плохими решениями на стороне мокко, и я, скорее всего, найду другой тестовый фреймворк, который ближе к моему мышлению, и внесу свой вклад в него. Вот некоторые из других проблем, которые у меня есть с Mocha, если вам интересно: # 1218, # 1401, # 1065.

@bajtos

В любом случае, ваше предложение написать специального репортера - разумный обходной путь.

Это интерфейс, а не репортер. См. Bdd.js для начала.

Честно говоря, я устаю бороться с тем, что считаю плохими решениями на стороне мокко.

Какие решения? Не стесняйтесь, напишите мне или присоединитесь к нам в комнате Mocha Slack для обсуждения ( напишите Трэвису, если вы хотите присоединиться к Slack ), если вы не хотите делать это здесь. Я не могу обещать никаких решений, но подобные заявления требуют дополнительной информации.

1218, 1401, 1065

Ни одна из этих заявок не закрыта - они ожидают рассмотрения и / или принятия мер; здесь действительно ничего не «решено».

Это интерфейс, а не репортер. См. Bdd.js для начала.

Это была опечатка с моей стороны, спасибо, что исправили меня и добавили ссылку на исходный файл.

Какие решения?

Что ж, может быть «решение» было не тем словом. У меня сложилось впечатление, что вопросы, которые важны для определенного подмножества пользователей мокко, таких как я, не придают такого же значения разработчикам мокко.

Ни одна из этих заявок не закрыта - они ожидают рассмотрения и / или принятия мер; здесь действительно ничего не «решено».

Объявление № 1065: Сначала я отправил запрос на перенос № 949. Поскольку он был отклонен, я создал проблему, чтобы обсудить, как лучше всего решить проблему. Выпуск открыт в течение года без каких-либо комментариев со стороны мейнтейнеров проекта. Тем временем частичное решение было отправлено через # 993.

Теперь я очень хорошо знаю (по собственному опыту), что нельзя комментировать все вопросы. Тем не менее, я был бы признателен, если бы вы могли хотя бы прокомментировать проблемы, связанные с отклоненными запросами на перенос, поскольку такие проблемы могут превратиться в другой вклад (запрос на перенос).

Объявление №1218: Это очень раздражает всех, кто использует интеграцию Jenkins с JUnit, поскольку любые console.log и / или console.error портят вывод XML. По крайней мере, три запроса на внесение изменений пытались решить эту проблему, начиная с 13 июня 2013 г. (!!). С моей точки зрения, специалисты по сопровождению мокко не считают эту проблему достаточно важной, чтобы получить исправление. В StrongLoop мы закончили поддерживать собственный форк Mocha только из-за этой проблемы.

Объявление №1401 - я вижу, что скоро вы собираетесь объединить это, @boneskull , спасибо за это.

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

Я разделяю чувства @bajtos по поводу мокко. Долгое время мокко служил мне очень хорошо , но в какой-то момент я начал расходиться во мнениях относительно направления проекта. С моей стороны он почти не используется, в основном это относится к # 1401. Обычно я пишу инструменты / модули, но похоже, что сейчас мокко в основном фокусируется на приложениях.

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

Я писал свою собственную вещь по крайней мере 10 раз для этой конкретной проблемы, но вот менее уродливый https://github.com/nearform/nscale-planner/blob/master/test/integration/integration.js. ИМХО он превосходит все остальные предложения, но это мой вкус. Я тоже думаю, что это можно поддержать здесь:

var custom = it.gen("should be generic with", function(a, b) {
  //....
})

custom(1) // the test is reported as "should be generic with 1".
custom.skip(2)
custom.only("a string", 3) // the test is reported as "should be generic with a string".

Кроме того, его можно применить к describe , чтобы упростить обработку групп абстрактных тестов. Я могу поработать над пиаром, если хочешь.

@mcollina @bajtos Не могли бы вы поделиться некоторыми примерами, в которых вы чувствовали себя нежеланными?

Обычно я пишу инструменты / модули, но похоже, что сейчас мокко в основном фокусируется на приложениях.

@mcollina Почему ты так говоришь?

Выпуск открыт в течение года без каких-либо комментариев со стороны мейнтейнеров проекта. Тем временем частичное решение было отправлено через # 993.

@bajtos. Если критическая проблема (для вас) сохраняется в течение длительного времени, вероятно, это потому, что мы не понимаем, на скольких людей она влияет, и / или не полностью понимаем ее серьезность. Если что-то устаревает, оно (часто) закрывается. Если что-то продолжает сталкиваться, это обычно привлекает больше внимания, но это не всегда так (далее следует объяснение).

Я собираюсь немного побродить.


Есть два (2) активных сопровождающих этого проекта; @travisjeffery и я. После того, как TJ ушел, был приток новых сотрудников, но многие ушли. Если кто-то из нас кратко отвечает на вопросы, это все, что мы можем собрать.

Каждую неделю у меня есть три (3) часа, которые я могу посвятить этому проекту. Большую часть времени уходит на ответы на вопросы. В настоящее время мой список TO-DO для Mocha состоит из 158 пунктов , и я не знаю, с чего начать, если я _do_ получу шанс что-то реализовать.

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

Итак, извините, пожалуйста, за наше нежелание объединять PR функций. Если есть какое-либо жизнеспособное решение, это в значительной степени то, что необходимо прямо сейчас.

На мой взгляд, здесь есть две основные проблемы:

  1. У нас недостаточно ресурсов, чтобы добавить что-то в Mocha, и
  2. Вероятно, мы не очень хорошо рассказали об этом.

Для решения 1. нам нужна дополнительная помощь. _В настоящее время_ нам нужна помощь в управлении проблемами, проверке PR и привлечении внимания к критическим вопросам. Этот человек или человек (люди) должны действительно наслаждаться "управлением проектом", иначе они не продержатся долго. Если они умеют писать код, это тоже здорово. Этот потенциальный соавтор должен понимать, что ресурсы очень ограничены.

Я думаю, может быть, появлюсь в README и опубликую в группе Google, объявив, что мы ищем помощь в этой области. Есть другие идеи?

Относительно 2 .: Я недавно добавил CONTRIBUTING.md, чтобы немного объяснить статус проекта, но я думаю, что этого было недостаточно или, возможно, неправильно сформулировано.

Возможно, закрывая PR, мы можем быть более вежливыми и повторить текущие потребности проекта. Вместо публичного заявления, индивидуальное внимание, вероятно, облегчило бы некоторую боль.


Пользователи расстраиваются, когда вы не объединяете их PR. Я думаю, что этому способствовало то, что у пользователей нет четкого, задокументированного способа разработки плагина, поэтому они чувствуют, что единственный способ, которым их функция когда-либо увидит свет, - это объединение.

Если был опубликован хорошо документированный API плагина, то пользователи могли бы написать все странные функции, которые они хотят для Mocha, _и_ не допускать их использования в ядре. Никто не пострадает, все счастливы.

Я думаю, что это отличная идея, но где сделать ее приоритетной после 158 других вещей?

Будем признательны за любые дальнейшие комментарии или предложения.

Обычно я пишу инструменты / модули, но похоже, что сейчас мокко в основном фокусируется на приложениях.

@mcollina Почему ты так говоришь?

@boneskull , это чувство с моей стороны. Каждый раз, когда я пишу функцию, которая является _ жесткой_ (как и большинство LevelGraph , nscale , Mosca , MQTT.js ), у меня возникают проблемы с Mocha, так что она больше не _ простая, гибкая и забавная_ (как в слогане). Каждый раз, когда я тестирую приложение с помощью Mocha, я чувствую, что «это так здорово», и рекомендую его в курсах и т. Д.

Либо отсутствует функция, которая мне нужна, и я не вижу простого и легкого способа опубликовать ее как модуль, либо в ней есть какая-то досадная ошибка (например, # 1401), либо мне приходится прибегать к уродливым и одноразовым хакам. чтобы все заработало.

Можете ли вы привести несколько примеров того, когда вы чувствовали себя нежеланными?

Вы сами написали это более подробно, чем я когда-либо мог

Пользователи расстраиваются, когда вы не объединяете их PR. Я думаю, что этому способствовало то, что у пользователей нет четкого, задокументированного способа разработки плагина, поэтому они чувствуют, что единственный способ, которым их функция когда-либо увидит свет, - это объединение.
Если был опубликован хорошо документированный API плагина, то пользователи могли бы писать все странные функции, которые они хотят для Mocha, и держать их вне ядра. Никто не пострадает, все счастливы.

В файле CONTRIBUTING.md вы указываете «мы, скорее всего, не примем ваш PR», но у людей нет простого способа разработать необходимую им функцию с помощью плагина. Это заставляет людей чувствовать себя нежеланными.


Финансировать oss сложно, и я понимаю ваши проблемы , поскольку они часто являются моими. Тем не менее, очень много компаний и разработчиков заинтересованы в том, чтобы мокко продолжало развиваться, и я считаю, что найти новых участников можно. Я думаю, что громко сказать «нам нужна помощь» определенно важно.

Я постараюсь помочь в моих силах.

Боковое примечание: вы можете подать заявку на GSoC в качестве организации и, надеюсь, позволить Google спонсировать молодого коллегу-разработчика для создания и документирования этого API плагина.

@boneskull Спасибо, что поделились этим. Я вовремя не осознавал, насколько ты напряжен. Оглядываясь назад, я должен был предположить с самого начала, что нехватка времени была причиной кратких комментариев, вместо того, чтобы ожидать какой-то умышленной злобы. Прошу прощения за это.

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

Я полностью согласен, теперь, когда я понимаю вашу ситуацию.

Пользователи расстраиваются, когда вы не объединяете их PR. Я думаю, что этому способствовало то, что у пользователей нет четкого, задокументированного способа разработки плагина, поэтому они чувствуют, что единственный способ, которым их функция когда-либо увидит свет, - это объединение.

Если был опубликован хорошо документированный API плагина, то пользователи могли бы писать все странные функции, которые они хотят для Mocha, и держать их вне ядра. Никто не пострадает, все счастливы.

Я думаю, что это отличная идея, но где сделать ее приоритетной после 158 других вещей?

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

Я отправил PR, добавив заметку о плагинах на CONTRIBUTING.md: https://github.com/mochajs/mocha/pull/1459

Возможно, закрывая PR, мы можем быть более вежливыми и повторить текущие потребности проекта. Вместо публичного заявления, индивидуальное внимание, вероятно, облегчило бы некоторую боль.

+1000 за это.

ИМО, даже общий комментарий, который вы копируете и вставляете каждый раз, когда отклоняете проблему / запрос на перенос, очень поможет. Что-то вроде:

_Мы ценим ваш вклад. Однако, учитывая, как мало времени у нас есть на поддержку проекта, мы принимаем только критические исправления ошибок и абсолютно важные функции. Мы полностью понимаем, что это не очень хорошо, и вы можете быть недовольны тем, что ваша проблема не была решена. Вот несколько альтернативных способов получить то, что вам нужно: 1) переписать функцию как плагин для мокко 2) если вы исправляете ошибку в несущественном компоненте, подумайте о том, чтобы извлечь компонент в отдельный плагин и исправить ошибку там 3 ) помогают нам с сортировкой и управлением проблемами, чтобы у нас было больше времени для работы над кодом.

Я думаю, что, может быть, появлюсь в README и опубликую в группе Google, объявив, что мы ищем помощь в этой области. Есть другие идеи?

Добавьте баннер на сайт (http://mochajs.org/). Убедитесь, что в просьбе содержится информация из вашего комментария (_В настоящее время нам нужна помощь в управлении проблемами, проверке PR и привлечении внимания к критическим вопросам. Этому человеку или лицам, возможно, действительно понравится «управление проектом», иначе они выиграют » t длится долго. Если они умеют программировать, это тоже здорово.)

Честно говоря, у меня есть другие проекты OSS, где мне трудно справляться с проблемами и запросами на вытягивание, поэтому, к сожалению, я не могу предложить гораздо больше помощи, хотя я бы хотел :(

TL; DR: как я могу использовать параметризованные тесты?

Единственное решение, которое я нашел, - использовать async.each

Что-то вроде этого может сработать :)

var assert = require('assert');

describe('suite', function() {
  [1, 2, 3].forEach(function(n) {
    it('correctly handles ' + n, function() {
      assert(n);
    });
  });
});

// =>

  suite
    ✓ correctly handles 1
    ✓ correctly handles 2
    ✓ correctly handles 3


  3 passing (7ms)

Очень важно:

  • describe не может быть параметризовано из-за проблем

    • причина?

  • только it

описание не может быть параметризовано из-за проблем

Какие проблемы?

[1, 2, 3, 4].forEach(function (val) {
  describe('test ' + val, function () {
    it('bla', function () {

    })
  })
})
➜  js  mocha describe-parameterized.js


  test 1
    ✓ bla

  test 2
    ✓ bla

  test 3
    ✓ bla

  test 4
    ✓ bla


  4 passing (8ms)

Я согласен с @dasilvacontin , это тот подход, который мы используем, и он работает достаточно хорошо. Не уверен, что загрязнение API мокко параметризацией необходимо вообще TBH.

FWIW, решение @dasilvacontin только кажется работающим, но значение val не изменяется в блоках it :

[1, 2, 3, 4].forEach(function (val) {
  describe('test ' + val, function () {
    it('bla', function () {
      console.log(val);
    })
  })
})

test 1
  ✓ bla
  4
test 2
  ✓ bla
  4
test 3
  ✓ bla
  4
test 4
  ✓ bla
  4

@btelles Какую версию мокко вы используете? Потому что это работает для меня.

$ cat test.js
[1, 2, 3, 4].forEach(function (val) {
  describe('test ' + val, function () {
    it('bla', function () {
      console.log(val);
    })
  })
})
dstjules:~/Desktop
$ mocha --version
2.4.5
dstjules:~/Desktop
$ mocha test.js


  test 1
1
    ✓ bla

  test 2
2
    ✓ bla

  test 3
3
    ✓ bla

  test 4
4
    ✓ bla


  4 passing (10ms)

@danielstjules Здесь тоже работает.

@btelles - это действительно код, который вы используете? Из вывода это выглядит так, как если бы вы ссылались на переменную итератора - как только it s фактически выполнено, цикл завершен, и итератор указывает / имеет предельное значение.

FWIW, Я написал модуль Unroll, который предоставляет параметризованные тесты, подобные приведенным выше, но с именованными параметрами, которые также отражены в заголовке теста. Полезно, если вы хотите, чтобы заголовки тестов были информативными по параметрам.

Я знаю, что это старый, но теперь есть действительно простой пакет npm, чтобы упростить это: mocha-param
screen shot 2017-03-05 at 23 45 16

@mikejsdev Я не понимаю, mocha -param: https://mochajs.org/#dynamically -generating-tests. Последний позволяет использовать уникальные имена для каждого теста, что довольно много. Предположительно, мы можем использовать эту же динамическую технику для исключения нескольких описаний (хотя я этого не пробовал). Можете ли вы помочь мне понять случаи использования, в которых mocha-param предпочтительнее динамической генерации тестов?

Я согласен с @binduwavell
И это также было одобрено ранее @dasilvacontin и @danielstjules, а

У всех людей, которые пишут модули и публикуют их как @mikejsdev
Пожалуйста, добавьте примечание о мотивации в README:

  • Зачем вы написали модуль?
  • Какие проблемы вы пытаетесь решить?
  • Что вы делаете иначе по сравнению с X?

Ненавижу копать эту резервную копию, но мне интересно, может ли возможность указать параметры таким образом, чтобы контекст мокко знал о них, могла бы улучшить поддержку использования хуков beforeEach / afterEach . Я только что наткнулся на # 4072, и он кажется здесь актуальным 🤷‍♂

Есть ли способ сделать что-то вроде it.only и it.skip с (одним конкретным экземпляром) параметризованным тестом? Для меня это была бы единственная причина использовать вспомогательный пакет, а не динамически генерировать тесты.

@binduwavell @timaschew

Всего два цента, но из мира Python синтаксис, предложенный в https://mochajs.org/#dynamically -generating-tests, мне кажется очень плохим:

  1. Параметры должны быть получены через переменную test хотя на самом деле они должны быть просто параметрами функции.
  2. Каждая запись tests должна содержать объект с ключом: значение для каждого параметра. Это делает исходные параметрические данные более подробными, чем следовало бы.
  3. Сама тестовая функция (та, что передана в it(...) имеет нулевые параметры, что не является очень явным и читаемым
describe('add()', function() {
  var tests = [
   // See 2., extra key and values just for re-defining function parameters.
    {args: [1, 2], expected: 3},
    {args: [1, 2, 3], expected: 6},
    {args: [1, 2, 3, 4], expected: 10}
  ];

  tests.forEach(function(test) {
    it('correctly adds ' + test.args.length + ' args', 
      // See 3., no parameters to this function. Except it does have some
      function() {
      // See 1., cannot directly use `args` as a variable, need to go through `test.args`
      var res = add.apply(null, test.args);
      assert.equal(res, test.expected);
    });
  });
});

(Гипотетический) синтаксис, который я считаю лучшим:

describe('add()', function() {
  var tests = [
    // values, expected
    [[1, 2],  3],
    [[1, 2, 3],  6],
    [[1, 2, 3, 4], 10]
  ];

  using(tests).it('correctly adds with args', function(values, expected) {
      var res = add.apply(null, values);
      assert.equal(res, expected);
    });
  });
});
Была ли эта страница полезной?
0 / 5 - 0 рейтинги