Динамическое создание тестов Mocha из большой коллекции MongoDB - PullRequest
1 голос
/ 31 мая 2019

В моем наборе тестов проекта Node.js я хочу проверить каждый элемент в коллекции MongoDB на соответствие схеме JSON.Используя Mocha тестовый фреймворк, я могу генерировать тесты динамически следующим образом:

describe('Lexemes', () => {
  // load schema validator
  var schema = JSON.parse(fs.readFileSync('public/schemas/lexeme.json'))
  var validate = ajv.compile(schema)

  it('receives data', async () => {
    // load all items in collection
    let items = await db.get('lexemes').find()
    items.forEach((item) => {
      // dynamically generated test for each result
      describe(item._id, () => {
        it('conforms to schema', () => {
          validate(item).should.be.true()
        })
      })
    })
  })
})

Это отлично работает для небольших коллекций.Однако с одной очень большой коллекцией (4,5 миллиона документов) я получаю тайм-аут:

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

Если я просто увеличу тайм-аут до 60 с, я в итоге получу кучу JavaScript из памяти ошибка.Ясно, что он пытается поместить всю коллекцию в память, которая не будет работать.

Я думал, что смогу использовать Поток результатов Монаха примерно так:

it('receives data', () => {
  return db.get('lexemes').find().each((item, { close, pause, resume }) => {
    describe(item._id, () => {
      it('conforms to schema', () => {
        validate(item).should.be.true()
      })
    })
  })
})

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

Редактировать 1

Я попытался вручную разбить данные на более мелкие куски, используя параметры limit / skip для запроса Mongo:

const limit = 1000 // page size
var skip = 0
do {
  it(`receives data ${skip} to ${skip + limit - 1}`, async () => {
    let items = await db.get('lexemes').find({}, { limit: limit, skip: skip })
    items.forEach((item) => {
      describe(item._id, () => {
        it('conforms to schema', () => {
          validate(item).should.be.true()
        })
      })
    })
  })
  skip += limit
} while (skip < 5000000)

Edit 2

Это позволяет избежатьошибки тайм-аута, и Mocha, кажется, делает успехи с тестами «получает данные от x до y», но когда он начинает выполнять тесты «соответствует схеме», он выдает ту же ошибку нехватки памяти, как указано выше.

Любые другие идеи о том, что я мог бы попробовать?

1 Ответ

0 голосов
/ 27 июня 2019

Что ж, это не решает исходную проблему, но мне пришлось довольствоваться только тестированием выборки данных из моей большой коллекции с использованием функции агрегирования $sample MongoDB:

const limit = 100000 // sample size
it(`receives data (${limit} samples)`, async () => {
  let items = await db.get('lexemes').aggregate([{ '$sample': { 'size': limit } }])
  items.forEach((item) => {
    describe(item._id}, () => {
      it('conforms to schema', () => {
        validate(item).should.be.true()
      })
    })
 })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...