CategoryNodeJS

TypeScript: unit testy s Jest

Jest je, jak píše Facebook co by jeho tvůrce, skvělý JavaScriptový testovací framework. Jedná se o přímou náhradu, či konkurenci jinému, v současné době asi rozšířenějšímu, testovacímu frameworku, kterým je Mocha.

Proč Jest?

  • méně nutné konfigurace pro okamžité použití
  • velice jednoduché vše rozjet a okamžitě začít pokrývat zdroják testmi
  • na rozdíl od Mocha obsahuje i assert knihovnu (Chai) a mock knihovnu (SinonJS)
  • performance

Nicméně žádný z těchto důvodů nebrání použítí Mocha frameworku pro váš kokrétní projekt, či tým.

Jak na to?

Instalace

Předpokádám, že už máte nějaký NodeJS projekt a v něm package.json. Pak stačí jen doinstalovat pár balíčků nasledujícím způsobem:

Hotovo 🙂

Konfigurace

Do pakcage.json vložit konfiguraci pro Jest a následně upravit sekci script:test pro spuštění testů:

Samotná konfigurace Jestu může být alternativně uložena mimo package.json přímo do jest.config.js:

Vytvořte adresář __tests__ v root adresáři vašeho projektu. Adresář s testy se může samozřejmě pojmenovat jakkoliv jinak, stačí korektně přenastavit v konfiguraci.

Hotovo 🙂

Kódování, develop, vývoj…

Založte si src adresář a v něm vytvořte svůj nějaký soubor, který bude obsahovat váš TypeScript kód. Řekněme sum.ts, pro nějaké matematické funkce…

Hotovo. Máme knihovnu, která v tuto chvíli exportuje jednu jedinou funkcionalitu pro sčítání 2 čísel.

Konečně testování

V dříve založeném adresáři __tests__ vytvořte stejně jmenující se typescriptový soubor který bude obsahovat samotné testy, tentokrát s příponou .test.ts:

Hotovo 🙂 Můžeme testovat:

Výstupem je krom informace s výsledky testů i informace o tom, jak máte svůj zdroják testy pokrytý:

TDD

V rámci TDD si pak dokážu představit, že pro každou nově vyvíjenou funkcionalitu si nejdřív napíšete její testovací sekci, ve které pokryjete všechny scénáře, kterou mahou nastat a pak teprve začnete vyvíjet a píšete tak dlouho, dokud všechny zadefinované testy nejsou zelené 🙂

Zdroje

Jest homepage, dokumentace, blog

NVM, NPM problém

Pro běh NodeJS runtime používám NVM, který mi dovoluje do produkce dostat novější verzi NodeJS, než je v oficiálních balíčcích použité linuxové distribuce. A je v podstatě jedno, jestli běžíte na Centosu, Fedoře nebo Debianu, protože situace je v tomto ohledu všude stejná…

Vedle toho jsem v současné době začal vytvářet a distribuovat privátní NPM balíčky s funkcionalitami, které chci opakované používat ve více projektech. NPM je super. Vyvíjím v TypeScriptu, builduji balíček do čistého JavaScriptu, přidávám definice types (respektive se při vhodné konfiguraci generují sami), aby ostatní konzumenti mého balíčku věděli jak je použít.

Konfigurace produkce

Ale v podstatě i jakéhokoliv develop stroje, kde chcete mít přístup k privátním NPM balíčkům. Aby vám vše fungovalo jak má, je potřeba jen jemně dokonfigurovat prostředí. Úprava spočívá v úpravě .bashrc a .npmrc. Nic složitého:

1. Konfiguracve NVM

Někde na konci vašeho .bashrc přidejte pro NVM následující

Tím máte NVM funkční a můžete skrze něj instalovat požadované NodeJS runtimy:

A NodeJS vám běží v poslední dostupné stabilní verzí:

2. Konfigurace NPM
Vytvořte ~/.mpmrc a do něj vložte

A do svého .bashrc přidejte následující řádek:

Hotovo 🙂

No a tady přišel problém.

Pokud zmodifikujete své, nebo produkční prostředí, tak jak jsem popsal, přestane vám NodeJS fungovat 🙂
Problém je v nevinně vypadajícím export env proměnné NPM_TOKEN na konci vašeho .basrc. Pokud jej odeberete, nebo zakomentujete, bude vám NVM opět fungovat a tím pádem j node poběží…

Řešení

Stačí přemístit v .bashrc příkaz exportující NPM_TOKEN před příkazy exportující proměnné pro NVM…
Výsledná konfigurace v .bashrc by měla vypadat takto:

Funguje 🙂

SocketIO v NodeJS (předpověď počasí)

Našel jsem moc hezký článek jednoduše popisující SocketIO. Takže jestli hledáte technologické řešení, jak komunikovat s návštevníkem vaší www stránky v reálném čase, pak věřte, že to už nejde jednodušeji…

NodeJS: NODE_ENV dev || production

Taková ta uplná klasika: vyvíjíte aplikaci na svém stroji, kde máte samozřejmě úplně jinou konfiguraci, než na produkčním serveru, respektive také odlišnou od konfigurace kolegy, který se snaží psát pod Windejsi.
Tou jinou konfigirací může být cokoliv. Od propojení na externí služby až po způsob logování toho co a jak chcete vidět. Jasně že na developu vás zajíma víc věcí, které chcete na produkci vidět až když řešíte nějaký problém…

A řeči o tom, že byste měli kontejnerovat, dokrovat a tak vás taky nebaví. Nevidím jediný důvod, proč bych měl na svém lokále sestavovat nějaký dokr a pak spouštět virtuální stroj… WTF! Jediné co chci je spustit apku na mém mekovi prostě jinak nakonfigurovanou, ale funkčně pokud možná co nejvíc identickou s produkčním prostředím…

Dřív jsem rozdílnou konfiguraci do aplikace zaváděl skrze parametr příkazové řadky. Vstupní JS modul aplikace rozparsoval parametry příkazové řádky. Pokud našel parametr udávající soubor s konfigurací, pak se jej pokusil naimportovat. Pokud nic takové, pak natáhnul nějakou defaultní konfiguraci… Super. Funguje skvěle a umožnuje opravdu dobře nakonfigurovat kde co a to pokaždé úplně jinak. Prostě jak je libo…

Jenže jsem línější a línější a i tohle mi připadalo jako opruz. Je to přece jen nějaký kód navíc.. Já vím, že ne moc, ale je… Stačilo mi prostě něco lehčího.

NODE_ENV

A tak jsem se vrátil k NODE_ENV. Ne že bych o ní nevěděl, ale protože jsem vytvářel přece jen složitější struktury, mírně jsem podcenil možnosti této enviroment proměnné, a proto jí nějak moc rychle přeskočil. Chyba. NODE_ENV mi umožňuje dál lenošit a odpadl problém s konfigurací.

Jediné co jsem musel ořešit je jak NODE_ENV propašovat v různých způsobech spouštění, či využívání přímo do aplikace. Apku spouštím různě a nechtěl jsem se připravit o konfort kastomizovaných konfiguráků specifikovaných z příkazové řádky.

Základní implementace v package.json skrze sekci script:

Pokdud spouštíte apku z shellu, pak takto:

No a pokud potřebujete NODE_ENV sdílet s dalšími nástroji, jako je gulp, nebo cokoliv jiného, pak:

Samotný JS kód se pak k proměnné prostředí dostane odkudkoliv skrze globální promenou process, která obsahuje celý ENV, včetně toho co sami nějak nadefinujete:

Takže můj konfig dnes může vypadat i takto:

Samozřejmě se i tohle dá napsát jinak, dle libosti… 🙂

Nicméně tohle je obecný přístup, kterým se dá do vaší apky propašovat jakákoliv proměnná z prostředí operačního systému…

__main__ v NodeJS

Kdysi jsem tady popisoval jak v NodeJS připodobnit chování runtime při spouštění daného modulu. Něco, co se běžně v Pythonu dělá takto, ale v NodeJS se to moc nevidí:

Původně jsem v NodeJS tohle řešil následovně:

Další, možná o něco lépe vypadající řešení

Tahle podmínka mi prostě připadá logičtější 🙂

A k čemu je to dobré?

No třeba k samotnému testování… Jsem líný a někdy mi dělá problém dokopat se udělat nějaké testování nad modulem, kyterý je přece úplně jasnej: tady nemůže být žádná chyba…. A právě proto přímo dodaného modulu napíšu tuhle podmínku, která má nějakou sekci, která se provádí jen v případě, že modul spouštím přímo pod NodeJS a nerequiruji ho do nějakého dalšího, nadřazeného modulu.

Geolokalizace IP adresy

Z důvodů pořešení nějakých bezpečnostních praktik jsem potřeboval nějak blíže geolokalizovat IP přihlašovaného uživatele, respektive záškodníka, abych věděl odkud se fyzicky přihlašuje:

NodeJS: geolokalizace IP adresy

Python: geolokalizace IP adresy

Zvýšení limitu RAM pro NodeJS aplikaci

Defaultně dostane NodeJS script maximálně 1.76GB RAM na 64bitovém systému. Což je asi na jednovláknové aplikace dost, nicméně se vám může stát, tak jako mě, že potřebujete zaalokovat nějaké opravdu větší pole a byť máte stroj s 16GB RAM, Node vám vráti chybu při pokusu alokovat paměť.

Pak se vám bude hodit parametr příkazové řádky –max_old_space_size, který V8 říká kolik si má vzít RAMky a posune defaultní limit na vámi zadanou hodnotu:

Vypnutí kešování www stránek

Někdy budete muset na úrovni HTML hlaviček vypnout kešování požadované stránky (cache). Důvod je zřejmý: měnící se obsah a snaha o zajištění distribuce aktuálního obsahu. Pak by se mohlo hodit info jak na to.

Nejdřív finta…

Možná nejjednodušším řešením jak zamezit kešování je změna adresy v samotném odkazu na stránku, kterou nechcete kešovat:

Ze serveru se generuje stránka, která obsahuje pokaždé jiný odkaz. Ten se mění díky vkládání časového razítka přímo do URL odkazu a proto bude stránka po každé znovu načtena…

A nebo pak jinak…

HTML

NodeJS

PHP

Python s Flaskem

Nginx

Apache .htaccess

IED: alternativa k NPM

ied
NPM je skvělý a určitě je jedním z hlavních důvodů, proč NodeJS zažívá takový boom.
V současné době se NPM prokousalo k 3. verzi, která řeší víceméně všechny neduhy 2. verze, jako je rychlost, adresářová struktura, velikost stahovaných dat a podobně.

IED

I když je NPM 3 opravdu daleko lepší než 2, stále má své rezervy. A na ně příjdete například v momentě, kdy si vyzkoušíte alternativního správce balíčků jako je IED, který je v rámci NodeJS plně kompatabilní, což znamená, že i přes velké změny v interní struktůře uložiště pozžívaných knihoven ve vaší aplikaci, poběží vše jak má.

Asi nejvýraznější výhodou je jeho opravdová rychlost při instalaci požadovaných balíčků specifikovaných v package.json. Otestoval jsem NPM i IED na ne příliš velké aplikaci, která používá cca 20 knihoven z NPM repozitáře. Pomocí NPM jsem měl nainstalováno za 24 sekund, ale s IED jen za 6. A to je opravdu fofr!

Protože 3. verze NPM už má flat model instalovaných balíčků, neni úspora místa a vše co s tím ouvisí (velikost stahovaných dat a podobně..) tak významné. Cca 44MB zabíral adresář node_modules instalovaný jak pomocí NPM i IED.

Asi jedinou nevýhodou na kterou jsem u IED narazil je absence příkazu udate, pro aktualizaci stažených, nainstalovaných NPM balíčků. NPM má příkaz npm command, který se pokusí aktualizovat všechny balíčky definované v package.json. A to dělá docela rychle: očekování nových verzí cca 20 balíčků v projektu trvalo cca 1.5 sekund. Dobrý.

NPM závislosti

Jednou z neskutečných výhod NodeJS je jeho NPM. Jedná se o dnes nejrychleji rostoucí balíčkovací systém. Repozitář obsajuje hotové balíčky snad na vše co vás napadne. Stačí jen stáhnout a použít.

No a pak se může hodit online grafická vizualizace závislostí jakéhokoliv baličku. Jedná se o webovou stránku, kde zadáte název NPM modulu a získáte pěkný obrázek s grafickým znázorněním závislosti zadaného balíčku. Výsledek můžete prohlížet i jako 3D model… 🙂

npm-zavislosti
Tohle je graf závislostí populárního balíčku express.

© 2018 pepa.holla.cz

Theme by Anders NorénUp ↑