В Mocha, популярном тестовом фреймворке для JavaScript, вы можете изменить репортер спецификаций по умолчанию. Есть несколько опций, включенных по умолчанию, вы также можете установить различные сторонние репортеры, которые вы можете найти, например. в Репозиторий NPM. Однако, если вы хотите обработать результаты теста, JSON, вероятно, является подходящим форматом, и генератор отчетов JSON по умолчанию должен предоставить вам всю важную информацию.

Чтобы настроить Mocha, вы можете использовать .mocharc.json. Чтобы использовать генератор отчетов JSON, добавьте в файл следующие два свойства:

{
  "reporter": "json",
  "reporterOptions": [
    "output=./results.json"
  ]
}

После запуска тестов вы должны увидеть файл results.json в корне проекта. Пример вывода может выглядеть так:

{
  "stats": {
    "suites": 1,
    "tests": 7,
    "passes": 6,
    "pending": 0,
    "failures": 1,
    "start": "2022-11-11T19:43:36.376Z",
    "end": "2022-11-11T19:43:36.381Z",
    "duration": 5
  },
  "tests": [
    {
      "title": "return string",
      "fullTitle": "formatDay() return string",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 1,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "return correct format",
      "fullTitle": "formatDay() return correct format",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month undefined",
      "fullTitle": "formatDay() month undefined",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month null",
      "fullTitle": "formatDay() month null",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 1,
      "currentRetry": 0,
      "err": {
        "message": "expected undefined to equal 2",
        "showDiff": true,
        "expected": 2,
        "operator": "strictEqual",
        "stack": "AssertionError: expected undefined to equal 2\n    at Context.<anonymous> (file:///home/pavel/testing/useful/tests/formatDay.test.js:28:39)\n    at process.processImmediate (node:internal/timers:471:21)"
      }
    },
    {
      "title": "month primitive",
      "fullTitle": "formatDay() month primitive",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month string",
      "fullTitle": "formatDay() month string",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month object",
      "fullTitle": "formatDay() month object",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    }
  ],
  "pending": [],
  "failures": [
    {
      "title": "month null",
      "fullTitle": "formatDay() month null",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 1,
      "currentRetry": 0,
      "err": {
        "message": "expected undefined to equal 2",
        "showDiff": true,
        "expected": 2,
        "operator": "strictEqual",
        "stack": "AssertionError: expected undefined to equal 2\n    at Context.<anonymous> (file:///home/pavel/testing/useful/tests/formatDay.test.js:28:39)\n    at process.processImmediate (node:internal/timers:471:21)"
      }
    }
  ],
  "passes": [
    {
      "title": "return string",
      "fullTitle": "formatDay() return string",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 1,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "return correct format",
      "fullTitle": "formatDay() return correct format",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month undefined",
      "fullTitle": "formatDay() month undefined",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month primitive",
      "fullTitle": "formatDay() month primitive",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month string",
      "fullTitle": "formatDay() month string",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    },
    {
      "title": "month object",
      "fullTitle": "formatDay() month object",
      "file": "/home/pavel/testing/useful/tests/formatDay.test.js",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    }
  ]
}

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

Массив tests включает все выполненные тесты — неудачные, пройденные и ожидающие (пропущенные). Если тест не пройден, подробности будут в объекте err. Одно предостережение: если тест пропущен, соответствующий объект не будет иметь свойства duration.

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

Массив failures интересен тем, что содержит как неудачные тесты, так и другие части, такие как неудачные перехватчики. Если вы хотите получить все сбои, возникшие во время тестового прогона, синтаксический анализ этого массива — это то, что вам нужно.

Наконец, pendingarray должен включать пропущенные тесты. Mocha помечает все пропущенные как ожидающие.

Тем не менее, если вам нужно проанализировать этот файл, потому что, например, вы хотите отправить результаты куда-то еще (например, на какую-то платформу мониторинга, такую ​​​​как New Relic), я бы сказал, получить все отказы от failures, а затем получить только пройденные и пропущенные тесты из tests, например:

const isFailed = (testCase) => (Object.keys(testCase.err).length === 0 ? false : true);

Таким образом, вы не получите два сообщения о неудачных тестах.