Bismillah!
Taxminiy o'qish vaqti: ~5 daqiqa
Assalom Alaykum!
O'tgan qismimizda asosan frontend
dagi relizgacha bo'lgan barcha jarayonlarni umumlashtirilgan shaklda ko'rib chiqdik. Bu va bundan keyingi qismlarda dastlabki maqolada keltirilgan mavzularga kengroq kiramiz va ularni qanday oddiy setup qilishlikni ko'rib chiqamiz. Bugun shu mavzularga kirish qismi qilamiz!
Ushbu turkum maqolalarda ishlatilgan barcha kodlarni quyidagi github repodan topishingiz mumkin: testing-demo-app. Alohida repodan asosiy maqsad ham bu mavzularni iloji boricha amaliy ko'rinishga keltirishdir.
React Testing Demo App
This repo is developed for showing how to setup all necessary modern tooling and good practices for development and bootstrap tests with React (both Jest and Cypress)
Available Scripts
In the project directory, you can run:
yarn install
: run this after cloning project to install all necessary dependencies
yarn postinstall
: run this to setup pre-commit
yarn start
: run this to start an app
yarn test
: run this to run all tests
yarn start:msw
: run this to start app in mocking mode
yarn cy:open
: run this to open Cypress in UI mode
yarn cy:run
: run this to open Cypress in headless mode
npm run build
:Extra steps
Need to setup relative path resolving using
tspath
as tsconfig baseUrl is only helpful on compile time, in order to resolve after it is transpiled into JS it cannot resolve TS configs…
Testlash o'zi nimaga kerak, tinchgina yashasak bo'lmaydimi!
Spoiler: Ground truth of testing is the confidence! 😊
Hozirgi kunda sifatli dasturiy ta'minotni ishlab chiqish jarayonini testlarsiz tasavvur qilish qiyin. Yozayotgan kodimiz doimo to'g'ri ishlashiga ishonch hosil qilishimiz uchun albatta ularni testlar bilan himoyalab qo'yishimiz lozim. Chunki tabiatan har qanday dasturiy ta'minot vaqt o'tishi bilan o'zgarishlarga mahkum va har qanday o'zgarishlardan keyin ham uning to'g'ri ishlayotganiga ishonch hosil qilishimiz uchun ham testlarni yozamiz. Ho'p test yozish muhim ekan lekin ularni qanday yozamiz, ularning qanday turlari bor, ularni yozishda qandaydir usullar, qonun qoidalar ham bormi... Shu va shunga o'xshash savollar test yozishni yangi boshlayotganlarda bo'lishi tabiiy. Keling shular haqida biroz gaplashamiz.
Little story: Esimda, bundan taxminan 3 yilcha oldin Agoda bilan bo'lgan intervyumda Agodani senior engineeri mendan: hozirgi ishxonangda testlarni qanday yozaslar deb soragandi. Uhh dedim ichimda, xo'sh testlar yozish nimaligini bilaman, ahamiyatini ham, o'zimcha bir nechta test yozib ko'rganman, lekin baribir ishxonamda yozmaymizku. Aldashni keragi yo'q, deb to'g'risini aytdim. Bizda test yozilmaydi, chunki startup bo'lganimiz uchun vaqtimiz kam (oo ajoyib bahona keltirdim deb o'yladim ichimda). U esa menga kulib, bizni ham vaqtimiz kam, vaqtimiz yana ham kamaymasligi uchun test yozamiz deb javob berdi. Shu suhbatdan keyingina, testlarning haqiqiy ahamiyatini tushundim (shekilli?).
Har qanday ishga tizimli tarzda yondashish doimo yaxshi natija beradi. Testlarni yozishda bunday tizimli yondashuv odatda testlash strategiyasi deb nomlangan bo'lib ular turli test turlarini qanday kombinatsiyalarda bo'lishini muayyan bir qolipga solib tashkillashtirishni anglatadi. Dasturchilar orasida ko'p tarqalgan bunday strategiyalardan biri bu Testing Pyramiddir. Unga ko'ra UI
testlar (ba'zida e2e
testlar nazarda tutiladi) bu eng qimmat, eng ko'p vaqt talab qiladigan va eng sekin ishlaydigan testlardir, unit testlar esa aksincha eng tez va eng oson yoziladigan, kam mashaqqat talab qiladigan jarayondir.
Unit testlar bu dastur kodining eng kichik va o'zi mustaqil biron amal bajara oladigan bo'lagini testlaydi xuddi funksiya yoki React component kabi. Ularni
run
qilishimiz uchun bizga browser, server yoki database kerak emas shuning uchun ularni ishlashi juda tez.
UI testlarni (odatda e2e nazarda tutiladi)run
qilish uchun esa butun boshli dasturni browserda ishga tushirish kerak bo'ladi, odatda haqiqiy server va database bilan birgalikda, so'ngra esa bu testlar hosil qilgantrash data
ni tozalalashimiz (o'chirish) kerak. Yuqorida ham aytib o'tilganidek, bu ko'p vaqt oladigan jarayon, va ularni yozish ancha mashaqqatliroq.
Integration testlar esa (service yoki funksional deb ham nomlanadi ba'zida) bu ikki turdagi testlarni orasida joylashgan. Ular dasturning bir nechta o'zaro bo'gliq qismlarini tekshiradi lekin browsersiz va odatda haqiqiy serversiz.
Demak biz ko'plab unit testlar va birozgina UI testlar yozishimiz kerak, shundaymi?
Bu uslub sinalgan va ishlaydigan strategiya bo'lishiga qaramay, frontend
ga qo'llashda o'ziga yarasha kamchiliklari ham bor, bundan tashqari bu strategiya tanishtirilgan vaqtni ham hisobga olish juda muhim. Ajax
revolyutsiyasidan oldin JavaScript odatda formalarni validatsiya qilish va sodda animatsiyalarni hosil qilish kabi oddiy amaliyotlar uchungina ishlatilalardi va u paytlari testing uchun ayniqsa frontend
da testlar yozish uchun vositalar kam va imkoniyatlari cheklangan bo'lishiga qaramay o'sha vaqtdagi talab va ehtiyojlariga javob bera olardi. Lekin so'nggi 10 yillikda web va uning atrofidagi texnologiyalarning soni va imkoniyatlari ancha kengaydi bu esa frontend
ning ancha murakkablashuviga olib keldi. SPA ya'ni client-side routing
, client-side state management
va client-side rendering
kabi texnologiyalar va bular atrofidagi juda ko'plab framework
lar va library
lar web dasturlash olamiga kirib keldi va testlashdagi oldingi usullar, texnologiyalar va vositalar hozirgi kun frontend
dagi testlash talablarini va ehtiyojlarini to'liq qondira olmay qoldi. Bunga yana quyidagi sabablarni ham ko'rsatish mumkin:
-
frontend
da UI doimiy o'zgarishda (funksional hech narsa o'zgarmasa ham), bu esa ko'p yozilgan unit testlarni fail bo'lishiga olib kelaveradi va har doim bironstyling
bilan bog'liq o'zgarish qilganimizda unit testlarni o'zgartirishimizga to'g'ri keladi. - unit testlar qanchalik ko'p bo'lmasin va barchasi muvaffaqiyatli ishlamasin agar ular tasdiqlab bergan dasturning qismlari birgalikda to'g'ri ishlamasa unda ulardan katta naf bo'lmaydi. Buning muqobilida, agar bu qismlar birgalikda to'g'ri ishlasa unda juda ko'p unit testlarni yozishga ham hojat qolmaydi. Chunki shuning o'zi dasturning imkoniyatlari to'g'ri ishlayotgani haqida bizga yetarli
confidence
ya'ni ishonch darajasini bera oladi.
Balki frontendda test yozishda sal boshqacharoq yondashuv kerakdir?
Frontendda testlashning zamonaviy strategiyalardan biri bu Testing Trophy.
Modern Testing Trophy | Standard Testing Pyramid |
---|---|
Testing Trophy 🏆
Bu strategiya ko'ra eng katta ROI (return on investment
) bu integration testlarda.
ROI - sarflangan xarajat yoki mashaqqatlarga nisbatan keltirilgan natija yoki foyda.
Integration testlar dasturning muayyan imkoniyatlarini (feature
) yoki butun boshli sahifani to'liq tekshiradi lekin odatda haqiqiy backend va databasega ulanmagan holatda. Masalan, quyidagi auth flow
ni misol qilib olishimiz mumkin (Login sahifasini):
- Login sahifamizni
render
qilamiz (oldinlari odatda browsersiz JSDOM kabi headlessruntime
da edi hozir esa Cypress kabi zamonaviy testlash vositalari yordamida to'g'ridan to'g'ri browserni o'zida hamrender
qilsa bo'ladi) -
username va password input elementlarini topamiz va kerakli test user
credential
larni kirgazamiz. -
Sign In
buttonni topamiz vaClick
. - To'g'ri
request
yuborilganini tekshiramiz. - Oxirgi bosqich holatga qarab har xil, misol uchun:
- Login sahifasidan dasturning asosiy qismiga
redirect
qilinganligi va biron textning asosiy sahifada borligini tekshirish yoki... -
SessionId
yokiJWT token
ni cookie yoki localStoragega yozilganligini tekshiramiz yoki... - va hokazo
- Login sahifasidan dasturning asosiy qismiga
Lekin bu jarayonda network request
lar serverga yetib bormaydi va msw kabi vositalar yordamida bu request
lar intercept
qilinib mock natijalar qaytariladi bunga keyinroq to'liqroq misol bilan to'xtalamiz.
Keling endi unit va integration testlarni solishtiramiz:
Unit testlar | Integration testlar |
---|---|
|
|
Oxirgi farq bu yerda eng muhim jihatlardan biridir ya'ni turli testlar beradigan turli ishonch darajalari (level of confidence
)! Integration testlar bizga dasturiy ta'minotimiz kutilganidek ishlayotganiga yetarli darajada ishonch bera oladi. Bu qolgan testlarni yozish kerak emas degani ham emas, shunchaki asosiy vaqt va e'tiborni integration testlarga berish bizga yaxshi natija olib keladi.
user flow - dasturda muayyan natijaga foydalanuvchi qanday erishishini ko'rsatuvchi ketma-ketlikdir (
e-commerce
appda muayyan mahsulotni topish, uni korzinkaga qo'shish va checkout qilish).implementatsiya detallari - dasturimizning ichki ishlash mexanizmi bo'lib foydalanuvchilarga ko'rinmaydi va dasturning spesifikatsiyasida ham ko'rsatilmaydi. Dasturchini ishlashi jarayonida hosil bo'lib boradi va odatda vaqt o'tishi bilan o'zgarishlarga mahkum.
Quyida integration testlarni muhimroq ekanligi haqida keltirilgan ajoyib xazilomuz gif (original tweet muallifi Erin McGrath)
expect(umbrellaOpens).toBe(true)
tests: 1 passed, 1 total
**all unit tests passed, hooray**
Demak xulosa:
Xo'sh testlash, testlarning turlari va testlash strategiyasi haqida bilib oldik va Testing Trophy strategiyasini frontend
uchun tanlab oldik. Keyingi maqolalarda ularning har bir qatlami bilan alohida alohida tanishib chiqamiz.
Top comments (4)
Ajoyib post, kerakli malumotlar. Respect))
Ajoyib, juda tushunarli yozilgan, ko'p narsa oldim, rahmat.
O'zbek tilida shunday maqolalar ko'yaversin.
Ajoyib maqola chiqibti aka katta rahmat. O'sha payitlarda loyihaga qo'shilganimda bizda testlar endi yo'lga qo'yilayotgan edi ishxonada ))
Shunda Juniorlar ham test yozadimi ? Deb so'ragan edim )).
Good post and valuable knowledge.