{"id":13362,"library":"it-each","title":"Mocha Async Test Looping with it.each","description":"it-each is a JavaScript module designed to extend Mocha's testing capabilities by enabling asynchronous test looping. It allows developers to iterate over data sets, executing a test case for each item with configurable titles and data extraction. The package, currently at version 0.5.0, explicitly states it is below v1.0.0 due to an unclear roadmap, implying potential breaking changes, though stability is aimed for. It operates by modifying Mocha's global `it` handler and works with Mocha v2.1.0 and likely newer versions, though no guarantees are made for future compatibility. Key features include automatic adjustment of `timeout` and `slow` values for collective tests, and an option (`testPerIteration`) to generate a separate test entry for each iteration, which helps in isolating failures. Its primary differentiator is its simplicity and direct integration into Mocha's existing `it` interface, making it easy to adapt existing tests for data-driven scenarios.","status":"maintenance","version":"0.5.0","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/whitfin/it.each","tags":["javascript","async","mocha","iterable"],"install":[{"cmd":"npm install it-each","lang":"bash","label":"npm"},{"cmd":"yarn add it-each","lang":"bash","label":"yarn"},{"cmd":"pnpm add it-each","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"it-each extends Mocha's 'it' handler and requires Mocha to be loaded in the test environment to function.","package":"mocha","optional":false}],"imports":[{"note":"This module uses CommonJS `require` and extends Mocha's global `it` object upon invocation. It does not provide named exports for ESM `import` statements. The function returned by `require('it-each')` must be called to enable the functionality.","wrong":"import { each } from 'it-each';","symbol":"it.each","correct":"require('it-each')();\n// it.each is then available globally or via Mocha's `it` context"},{"note":"Configuration options like `testPerIteration` are passed as an object to the initial invocation of the module. This call can be made multiple times to update settings across different test suites.","wrong":"const itEach = require('it-each'); itEach.testPerIteration = true;","symbol":"it.each with options","correct":"require('it-each')({ testPerIteration: true });"},{"note":"Similar to Mocha's `it.skip`, `it.each.skip` is available for skipping entire `it.each` blocks.","wrong":"it.skip.each(iterable, title, fields, process);","symbol":"it.each.skip","correct":"it.each.skip(iterable, title, fields, process);"}],"quickstart":{"code":"const assert = require('assert');\nconst { expect } = require('chai');\n\n// Require and activate it-each before your test suites\nrequire('it-each')();\n\ndescribe('User Data Processing', () => {\n  const users = [\n    { id: 1, name: 'Alice', age: 30, email: 'alice@example.com' },\n    { id: 2, name: 'Bob', age: 24, email: 'bob@example.com' },\n    { id: 3, name: 'Charlie', age: 35, email: 'charlie@example.com' }\n  ];\n\n  // Asynchronous function to simulate a database call\n  async function fetchUserData(userId) {\n    return new Promise(resolve => {\n      setTimeout(() => {\n        const user = users.find(u => u.id === userId);\n        resolve(user ? { ...user, fetchedAt: new Date() } : null);\n      }, 50);\n    });\n  }\n\n  it.each(users, 'should process user %s correctly', ['name'], async (user, next) => {\n    const fetchedUser = await fetchUserData(user.id);\n    expect(fetchedUser).to.not.be.null;\n    expect(fetchedUser.name).to.equal(user.name);\n    expect(fetchedUser.age).to.be.at.least(20);\n    console.log(`Processed user: ${fetchedUser.name} (Fetched at: ${fetchedUser.fetchedAt.toLocaleTimeString()})`);\n    next(); // IMPORTANT: Call next() for async tests with a callback signature\n  });\n\n  // Example with testPerIteration: true\n  describe('Individual User Age Validation', () => {\n    require('it-each')({ testPerIteration: true }); // Enable per-iteration tests for this suite\n\n    const ageData = [\n      { name: 'David', age: 18, expectedAdult: false },\n      { name: 'Eve', age: 25, expectedAdult: true }\n    ];\n\n    it.each(ageData, 'User %s should have adult status as %s', ['name', 'expectedAdult'], (data) => {\n      expect(data.age >= 18).to.equal(data.expectedAdult);\n    });\n  });\n});","lang":"javascript","description":"This quickstart demonstrates how to set up `it-each` in a Mocha test file, iterating over an array of user data. It shows both an asynchronous `process` function using `next()` and a synchronous one, along with how to enable `testPerIteration` for granular test reporting."},"warnings":[{"fix":"Monitor the project's GitHub repository for updates and test thoroughly when upgrading to new patch versions, as they might introduce unexpected behavior changes given the pre-1.0.0 status.","message":"The `it-each` module is currently below v1.0.0 and explicitly states that breaking changes are possible, although they are avoided where possible. Its roadmap is unclear.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Ensure you test your `it-each` based tests thoroughly when upgrading your Mocha version. If compatibility issues arise, consider pinning an older Mocha version or exploring alternatives like `mocha-each` or `jest-each` (if migrating to Jest).","message":"`it-each` is confirmed to work with Mocha v2.1.0, but compatibility with future major versions of Mocha is not guaranteed by the maintainers.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Always call `next()` when using asynchronous operations within your `process` function, typically after all async tasks are resolved, similar to how Mocha's `done` callback is used. If `next` is not in the parameters, the function is treated as synchronous.","message":"If the `process` function provided to `it.each` is asynchronous and includes `next` in its parameter list, `next()` MUST be called to signal completion of the test iteration. Forgetting to call `next()` will cause the test to time out.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"For clearer feedback on individual test performance and easier debugging of specific iterations, consider setting `testPerIteration: true` in `require('it-each')({ testPerIteration: true })`. This generates a separate test entry for each iteration.","message":"When `testPerIteration` is `false` (the default), Mocha's `timeout` and `slow` values for the test are multiplied by the number of elements in the array. This prevents premature timeouts but can mask performance issues in individual iterations.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are calling `require('it-each')()` as a function, rather than just `require('it-each')`. For example: `require('it-each')();`","cause":"The `it-each` module exports a function that must be invoked immediately to extend Mocha's `it` handler.","error":"TypeError: it.each is not a function"},{"fix":"Verify that your `process` function, if it contains asynchronous operations (e.g., Promises, `async/await`), correctly calls the `next()` callback after all operations have finished.","cause":"This Mocha timeout error typically occurs when an asynchronous `process` function passed to `it.each` fails to call its `next` callback, preventing Mocha from knowing the test has completed.","error":"Timeout of 2000ms exceeded. For more information see https://mochajs.org/..."},{"fix":"Ensure that Mocha is properly installed and your test files are executed using the Mocha test runner (e.g., `mocha your-test-file.js`). Also, ensure `require('it-each')()` is called after Mocha has been 'instantiated' or loaded in your test environment.","cause":"`it-each` relies on the global `it` function provided by Mocha. This error indicates that `it-each` was either required before Mocha was loaded or the test file is not being run within a Mocha test runner context.","error":"ReferenceError: it is not defined"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}