Монорепозитарии на примерах с использованием Lerna. Часть 2

Spread the love

После краткого обзора проекта с монорепозитариями, использование Lerna для управления проекта и борьбы с дублированием зависимостей мы рассмотрим преимущества тестирования использования монорепозитарий.

Эта статья является частью серии, начинающейся с Монорепозитарии на примерах с использованием Lerna. Часть 1. Финальная версия проекта monorepo для этой серии доступна для скачивания.

Дублирование зависимостей

Я столкнулся с интересной проблемой в предыдущей статье;

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

  • apple и banana зависят от sillyname@0.0.3
  • grocery зависит от sillyname@0.1.0
  • grocery зависит от apple и banana

Текущее состояние

  • Когда мы запустим index.js в grocery, код в grocery использует sillyname@0.1.0 а код в apple и banana использует sillyname@0.0.3 .
  • Обычно не будет ни каких проблем с запуском sillyname, и все должно работать как ожидается.
  • Но в то же самое время если мы создадим фронтенд приложение, на нужно будет сохранить две версии  sillyname в одном bundle. Но размер bundle может иметь ограничение и это может стать проблемой.

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

Тестирование

Один из аргументов в пользу использования монорепозитарий заключается в том, что его проще тестировать; давайте рассмотрим это с помощью Jest.

примечание: эта статья подразумевает базовое понимание Jest;

У вас должен быть корневой package.json, который создатся по время установки lerna. Вы должны прописать запуск всех ваших тестов, и все другие схожие задачи. Корневой package.json так же должен содержать все “hoisted” пакеты зависимостей, что увеличить скорость запуска проекта при использование флага  — hoist.

С начало установим  Jest в: корне проекта

npm install jest --only=dev

И внесем изменения:

jest.config.js

module.exports = {
  collectCoverage: true,
  collectCoverageFrom: [
    'packages/**/*.{js}',
    '!**/node_modules/**',
  ],
  roots: [
    'packages/',
  ],
};

package.json

{
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "jest": "^22.4.2",
    "lerna": "^2.9.0"
  }
}

Далее, видим что у monorepo нет никаких преимуществ для юнит тестирования; так как нам нужно создать фейковый sillyname для sillyname и apple (так же как для banana) и написать отдельные тесты:

packages/(apple|banana)/__mocks__/sillyname.js

module.exports = () => 'TEST';

packages/(apple|banana)/index.test.js

const apple = require('./');
test('returns correct string', () => {
  expect(apple).toBe('apple and TEST');
});

Точно так же фейковые applebanana, и sillyname для тестирования  grocery модуля.

packages/grocery/__mocks__/(apple|banana|sillyname).js

module.exports = 'TEST';

packages/grocery/index.test.js

const log = jest.fn();
console.log = log;
const grocery = require('./');
test('outputs correct string', () => {
  expect(log.mock.calls.length).toBe(3);
  expect(log.mock.calls[0][0]).toBe('grocery and TEST');
  expect(log.mock.calls[1][0]).toBe('TEST');
  expect(log.mock.calls[2][0]).toBe('TEST');
});

Но monorepo действительно поможет нам написать интеграционные тесты, например нам нужно проверить связь apple и banana с grocery.

integration.test.js

jest.unmock('apple');
jest.unmock('banana');
const log = jest.fn();
console.log = log;
const grocery = require('./packages/grocery/');
test('outputs correct string', () => {
  expect(log.mock.calls.length).toBe(3);
  expect(log.mock.calls[0][0]).toBe('grocery and TEST');
  expect(log.mock.calls[1][0]).toBe('apple and TEST');
  expect(log.mock.calls[2][0]).toBe('banana and TEST');
});

В результате:

  • Мы создали интеграционный тест в корне проекта.
  • Вызов unmock запускает интеграционный тест; тест использует код apple и banana при загрузке grocery.

Сейчас мы можем запустить наши тесты командой:

npm run test

примечаниеJest будет предупреждать о дубликатах фейковых функций (mock) sillyname при запуске интеграционных тестов. Так как нам нужны эти mocks, я не знаю как избавиться от этих предупреждений.Следующий шаг

Оригинал: Monorepos By Example: Part 2


Spread the love