Node.js: Огляд технологій розробки бібліотек загального призначення

    node.js
У цьому пості я хочу узагальнити і поділиться отриманим досвідом при розробці бібліотеки node-queue-lib . Я розповім про технології, які допомогли мені довести справу до фінального кінця — працездатного коду, який вже працює на одному з моїх сервісів. Особливістю даної бібліотеки є крос-платформний клієнт, тобто клієнт працює в node.js і браузері і заснований на одному і тому ж коді. У пості будуть описані наступні інструменти, без яких розробка цієї бібліотеки перетворилася б на пекло:
 
     
  • Тестування (jasmine_node )
  •  
  • Покриття коду тестами (istanbul )
  •  
  • Збірка клієнткою частини бібліотеки (browserify )
  •  
  • Автоматизоване тестування клієнта (phantomjs )
  •  
  • Пошук витоків пам'яті (memwatch )
  •  
Якщо Ви про це ще нічого не чули і маєте бажання написати закінчений продукт в надійності якого Ви будете впевнені, ця оглядова стаття допоможе Вам познайомиться з одним з варіантів комплекту інструментів для повноцінного контролю якості коду javascript бібліотеки.
 
І додатково, повторю, що стаття оглядова, і не ставить на меті навчити Вас віртуозно користуватися всіма перерахованими інструментами. Я лише покажу двері, але відкриєте Ви її самі…
 
 
 Відступ
Всі приклади будуть містити код для системи збирання grunt . Якщо Ви ще не знайомі з тим, що це таке, саме час це зробити, інакше на шляху до успіху ви будете регулярно спотикатися про консоль. Якщо Ви «просунутий», не кричіть в коментарях «gulp» , адаптувати код для вашої системи збірки для Вас не складе проблем.
 
 Тестування
Бібліотек для тестування в даний час предостатньо, щоб зробити вибір. І ви повинні його зробити і вибрати вподобану Вам модель тестування. Я не нав'язую Вам використовувану мною бібліотеку, тому що головне — це мати тести, а вибір бібліотеки другорядний. Мій вибір в даному випадку був зроблений з наступних причин:
 
     
  1. Деякі історичні моменти, в які я вже використав jasmine.
  2.  
  3. Підтримка node.js і браузера однієї бібліотекою, оскільки мається перевикористання коду.
  4.  
  5. Зрілість бібліотеки, і як наслідок, наявність інтеграції в різних інструментах.
  6.  
 
Установка
 
npm install grunt-jasmine-node --save-dev

 
Gruntfile.js конфігурація
 
jasmine_node: {
    options: {
        forceExit: true,
        match: '.',
        matchall: false,
        extensions: 'js',
        specFolders : ['./spec/']
    },
    all: ['spec/']
}

 
Як писати тести я Вас не буду вчити, такого матеріалу предостатньо. Краще я перейду до другого інструменту, мета якого показати, що Ви не тільки пишете тести, але і які ділянки коду ваші тести тестують. Адже абсолютно безглуздо писати тести, не уявляючи загальної картини протестованого коду.
 
 Аналіз покриття коду тестами
Немає жодної поважної причини, щоб код бібліотека не був покритий тестами на 100%. Кожна умова в коді має бути покрито тестом, інакше Ви зіткнетеся з непередбаченим поведінкою або напишіть код, який ніколи не працює. Якщо код не покритий тестами на 100% довіру до бібліотеці падає. Щоб перевірити покриття коду тестами необхідно скористатися бібліотекою istanbul. Сам по собі istanbul в «голому» вигляді нам не цікавий. Необхідно його інтегрувати в систему запуску тестів. Цим і займається модуль grunt-jasmine-node-coverage . Він дозволить Вам отримати звіт в html-вигляді (і не тільки) для комфортного аналізу покриття вихідного коду.
 
Установка
 
npm install grunt-jasmine-node-coverage --save-dev

 
Оскільки ми інтегруємо jasmine з istanbul, необхідно всього навсього змінити конфігурацію jasmine
 
jasmine_node: {
    coverage: {}, // включаем анализ покрытия кода
    options: {
        forceExit: true,
        match: '.',
        matchall: false,
        extensions: 'js',
        specFolders : ['./spec/']
    },
    all: ['spec/']
}

 
 речі, аналіз покриття коду тестами змусив мене трохи по іншому поглянути на деякі фрагменти. Наприклад, з аналізу деяких ділянок коду я виявив, що не визначено поведінку функції в деяких конструкціях if. Простіше кажучи не було блоку else. Рефакторинг однією з таких функцій привів мене до розуміння, що весь клас і взаємодія з ним написано неправильно і було переписано пристойну кількість коду. Так само було виявлено досить багато слабких місць при контролі помилок. Десь їх не було взагалі, десь слабо перевірялося ну і т.д. Так що користуйтеся аналізом покриття коду — це реально змусить Вас подивитися на свій код зовсім інакше . Тим більше, що використання інструменту таке просте, а звіти побудовані абсолютно передбачувано.
 
Цих інструментів цілком достатньо, щоб бути впевненим що Ви контролюєте якість свого коду. А подальший матеріал розкриє складніші аспекти розробки бібліотек.
 
 Збірка клієнткою частини бібліотеки
Якщо Ви створюєте крос-платформену бібліотеку (node.js і браузер) Вам знадобиться інструмент для збірки клієнтської частини бібліотеки. Щоб перетворити код для node.js в код, який можна буде підключити до браузеру, необхідно скористатися інструментом browserify .
 
Установка
 
npm install grunt-browserify --save-dev

 
Конфігурація
 
browserify: {
    dist: {
        files: {
            'dist/my-library.js': ['lib/my-library.js']
        }
    }
}

Конфігурація досить зрозуміла за умови, що в папці / dist у вас збираються фінальні файли, а в папці / lib лежать исходники. Не забувайте мініміфіціровать отриманий файл за допомогою uglify. Тема настільки заїжджена, що я не буду її розкривати у своїй статті. На всякий випадок залишу тільки посилання .
 
 Автоматизоване тестування клієнта
Не потрібно сподіватися на прозорість, яку дає технологія з попередньої глави. Протестуйте свій код в браузері. Особливо, якщо він використовує зовнішні бібліотеки подібні вашої, зібраної за допомогою browserify. Враховуючи що jasmine є і під node.js і під браузер тести можна перевикористати. Просто додайте в конфігурацію browserify файл з тестами і налаштуйте jasmine на їх запуск. Конфігурація буде виглядати приблизно так:
 
browserify: {
    dist: {
        files: {
            'dist/my-library.js': ['lib/my-library.js'],
            'dist/my-library.spec.js': ['spec/my-library.spec.js']
        }
    }
}

 
 У моєму випадку я використав досить популярну бібліотеку socket.io і при першому запуску інтеграційних тестів в браузері виявив, що жоден тест не пройшов, оскільки я абсолютно марно встановив опцію socket.io, яка на кожен запит створює нове з'єднання. Для браузера це було фатально і мені довелося досить пристойно порефакторіть, щоб мій код під node.js заробив без вищезгаданої опції. Тестируйте свій код в браузері після застосування різних інструментів .
 
Отже, тестування клієнта обов'язково, але воно поки не автоматизовано. jasmine передбачає відкриття браузером html-сторінки (так званий TestRunner). Але нам необхідно щоб тестування проводилося в автоматичному режимі. Для цього нам допоможе проект під назвою phantomjs . Суть технології в тому, що це повноцінний браузер, але тільки без UI. Тобто взагалі без якого або UI, — графічного або текстового. Управляється такий браузер простим скриптом на javascript запускаються в phantomjs.
 
Установка
 
npm install phantomjs --save-dev

 
Використання. Щоб запустити наш TestRunner.html і отримати результати тестування необхідно наступне:
1. Написати файл специфікації node.js який запустить phantom.js (для автоматичного запуску в jasmine)
2. Написати скрипт для phantomjs, який буде робити наступне:
 
     
  • Чи дочекається закінчення роботи jasmine.
  •  
  • Пропарсіт DOM получившейся сторінки і з'ясує скільки тестів впало. (Є підозри, що є кращий шлях окрім як парсити DOM).
  •  
  • Завершить роботу phantomjs.
  •  
3. Проаналізувати результат роботи phantomjs на предмет повідомлень про падіння тестів.
 
Взагалі з цією частиною доведеться непогано повозитися. Я прекрасно уявляю, що людина, яка вперше чує про технології phantom.js взагалі нічого не зрозумів з вище наведеного списку. Це не біда. Потрібно тільки відкрити відповідні сторінки документації на phantomjs, почитати і вникнути. І варто тільки освоїти це технологію, перед вами відкриваються досить хороші перспективи з автоматизації тестування UI.
Для натхнення можна подивитися на вже реалізований сценарій у вищезгаданій бібліотеці, на досвіді розробки якої з'явилася ця стаття.
 Посилання на файли для натхнення 1. Офіційний скрипт автоматизації запуску jasmine-тестів для phantomjs .
2. Реальний spec-файл . 1 і 3-й пункти.
3. Реальний phantomjs скрипт для завантаження jasmine `івського TestRunner.html та його аналізу . 2-й пункт. На даний момент вже кардинально відрізняється від офіційної версії.
 
 
Ну і тепер, коли ваш код протестований на 100%; протестований в різних оточеннях, з деякими невеликими застереженнями звичайно, вас має цілком обгрунтовано розпирати від гордості за своє дітище. Але… є на вашому шляху ще одну перешкоду не подолана яке Вам найімовірніше відрубають пальці.
 
 Пошук витоків пам'яті
Навіть якщо Ви все зробили правильно і Ваш код протестований на 100% це не дає Вам ніякої гарантії того, що бібліотека не «тече». І якщо в браузері з об'єктивних причин на це забивали, то «текучий» серверний сервіс як не важко здогадатися — це провал.
Більш менш робочим інструментом для пошуку витоків пам'яті який я зміг знайти — це memwatch (стаття на Хабре ). На жаль автоматизувати його використання у мене не вийшло. Відсутня стабільність результатів (або я щось упустив).
Як стверджується в самому memwatch дамп «Хіпа» знімається завжди після запуску garbage collector `а. Але проте все одно в звіті миготять якісь нібито не звільнені об'єкти. Реальний тест з мільярдами ітерацій шаблонних test-case `ів показував, що бібліотека пам'ять не їсть і працює стабільно.
Але це, природно, не аргумент проти використання інструменту. Можливо в майбутньому він буде працювати стабільно. Навіть сподіваюся, що це не його проблеми, а node.js. І в нових версіях він може показати кращі результати.
 
 речі, за допомогою даного інструменту я виявив, що socket.io не тече. І знайшов пристойну кількість витоків у своєму коді. І витоку ці були виключно у використанні одного і того ж класу: EventEmitter. В принципі про це багато написано, що EventEmitter — «дари приносить ...». Але як то кажуть, — досвід безцінна річ. Купуйте його, користуйтеся інструментами автоматизації в своїй роботі і ми побачимо багато якісних робіт.
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.