IlmHamroh
JavaScript Full-stack/27-qism. Ma'lumotlar bazasi chuqur: Postgres, ORM, Mongo, Redis62/65-dars14 daqiqa
Mundarija (20)

Test DB strategiyalari: alohida baza, ROLLBACK, TRUNCATE va template

Qisqacha: Integration test haqiqiy bazada ishlashi kerak, lekin testlar bir-birining ma'lumotini ko'rmasligi shart. To'rt usul bor. (1) Har testni tranzaksiyada boshlab, oxirida ROLLBACK — eng arzon (kanon: 19 ms), lekin o'zi COMMIT qiladigan kodni sinab bo'lmaydi. (2) Har testdan oldin TRUNCATE … RESTART IDENTITY CASCADE — sodda va ishonchli (106 ms). (3) Template'dan yangi baza (CREATE DATABASE … TEMPLATE) — to'liq izolyatsiya (350 ms). (4) Parallel test fayllariga alohida baza. Asosiy qoida: test bazasi — production yoki dev bazasi emas, alohida.

Bu darsda

  • Nega test bazasi alohida bo'lishini va uni qanday nomlashni bilasiz.
  • Tranzaksiya + ROLLBACK, TRUNCATE va template baza usullarini yozasiz va narxini solishtirasiz.
  • TRUNCATE ning RESTART IDENTITY va CASCADE parametrlarini tushuntirasiz.
  • node --test parallel ishlaganda testlar nega bir-birini buzishini va davosini bilasiz.

Oldin bilishingiz kerak: Supertest bilan HTTP integration test, Migratsiya tushunchasi, Tranzaksiya asoslari.

Oldingi darsda Redis bo'limini yakunladik. Endi qismning oxirgi mavzusi — bazali kodni testlash. vazifalar-api da Postgres testlari 26-qismdan beri bor; bu to'rt darsda ularni tartibga solamiz va kuchaytiramiz.

1. Nega bu kerak?

Backend test strategiyasi darsida backend uchun eng qimmatli test — integration ekanini aytgandik: haqiqiy baza, haqiqiy SQL. Soxta (mock) baza bilan test o'tadi, production'da esa cheklov yoki trigger xato beradi.

Lekin haqiqiy baza yangi muammo olib keladi. Test A vazifa yaratdi. Test B "ro'yxatda 0 ta vazifa" deb kutyapti — va yiqiladi. Yoki testlar faqat ma'lum tartibda o'tadi: birini alohida ishga tushirsangiz — yiqiladi. Bu beqaror (flaky) testlar (Coverage va test sifati).

O'xshatish: kimyo laboratoriyasi. Har tajriba toza probirkada boshlanishi kerak. Oldingi tajriba qoldig'i bo'lsa — natija yolg'on. Test bazasi strategiyasi — probirkani qanday tozalash.

flowchart TD
  T{Test qanday yozadi?} -->|faqat o'qiydi| A[Umumiy tayyor baza]
  T -->|yozadi, COMMIT kodda yo'q| B[Tranzaksiya + ROLLBACK]
  T -->|kod o'zi COMMIT qiladi| C[TRUNCATE har testdan oldin]
  C --> P{Fayllar parallelmi?}
  P -->|ha| D[Har faylga alohida baza]
  P -->|to'liq izolyatsiya kerak| E[Template'dan yangi baza]

Diagrammaga qarang: tanlov ikki savolga bog'liq — kod tranzaksiyani o'zi boshqaradimi va testlar parallel ishlaydimi.

2. Alohida test bazasi

Birinchi qoida: testlar hech qachon dev yoki production bazasiga ulanmaydi. Test TRUNCATE qiladi — siz qo'lda kiritgan namuna ma'lumotlar yo'qoladi. Production'da esa — haqiqiy foydalanuvchilarning ma'lumotlari.

vazifalar-api da test bazasi alohida env o'zgaruvchidan:

ts
const URL = process.env["TEST_DATABASE_URL"]
  ?? "postgres://postgres@127.0.0.1:5499/vazifalar_test";
  • Nomi _test bilan tugaydi — ko'rinib turadi.
  • DATABASE_URL emas, TEST_DATABASE_URL — tasodifan production manzili ishlatilmaydi.
  • Baza yo'q bo'lsa, testlar SKIP bo'ladi, yiqilmaydi: npm test Postgres'siz kompyuterda ham ishlaydi (node:test va node:assert dagi skip).

Test bazasining sxemasi production bilan bir xil bo'lishi kerak — xuddi shu migratsiyalar bilan quriladi (Migratsiya tushunchasi). Ma'lumoti esa bo'sh: har test o'ziga kerakli narsani o'zi yaratadi.

3. Usul 1: tranzaksiya va ROLLBACK

G'oya: test boshida BEGIN, oxirida ROLLBACK. Test ichidagi hamma yozuv bekor bo'ladi — baza testdan oldingi holatiga qaytadi.

Biz ishga tushirdik (PostgreSQL 17.6, holat 65 sxemasi va namuna ma'lumoti):

sql
SELECT count(*) AS vazifalar FROM vazifalar;
BEGIN;
INSERT INTO vazifalar (egasi_id, matn) VALUES (1, 'Test vazifasi');
SELECT count(*) AS vazifalar FROM vazifalar;
ROLLBACK;
SELECT count(*) AS vazifalar FROM vazifalar;
text
 vazifalar 
-----------
        48
(1 row)

BEGIN
INSERT 0 1
 vazifalar 
-----------
        49
(1 row)

ROLLBACK
 vazifalar 
-----------
        48
(1 row)

Tranzaksiya ichida 49 ta, ROLLBACK'dan keyin yana 48. Kanon narxini o'lchadi (20 marta, mediana; 1 foydalanuvchi + 20 vazifa yozish):

text
BEGIN…ROLLBACK: 19.3 ms

Eng tez usul. Lekin ikki jiddiy chegara:

  1. Kod o'zi COMMIT qilsa — usul ishlamaydi. PgOmbori dagi tranzaksiyada(fn) yordamchisi (Tranzaksiya asoslari) o'zi BEGIN … COMMIT qiladi. Test tashqi tranzaksiya ochsa ham, Postgres'da ichma-ich BEGIN yo'q — ichki COMMIT hammasini saqlaydi. SAVEPOINT bilan aylanib o'tish mumkin, lekin kodni test uchun o'zgartirishga to'g'ri keladi.
  2. Bitta ulanish — test va kod bitta Client dan foydalanishi kerak. Hovuz (Connection pooling) har so'rovni boshqa ulanishga berishi mumkin — u tranzaksiyani ko'rmaydi.

Yana bir nozik joy: sequence (id hisoblagichi) ROLLBACK da orqaga qaytmaydi. Keyingi INSERT 50-raqamni oladi. "id 1 bo'ladi" deb kutgan test bu usulda yiqiladi.

Shuning uchun bu usul faqat o'qiydigan yoki oddiy yozadigan kodni sinashda yaxshi. vazifalar-api uni ishlatmaydi.

4. Usul 2: TRUNCATE

4.1 Asosiy shakl

Har testdan oldin hamma jadvalni bo'shatish:

sql
TRUNCATE foydalanuvchilar, vazifalar, teglar, vazifa_teglari, izohlar,
  vazifa_tarixi RESTART IDENTITY CASCADE;
INSERT INTO foydalanuvchilar (email, toliq_ism)
  VALUES ('test@example.com', 'Test') RETURNING id;
SELECT count(*) AS vazifalar FROM vazifalar;
text
TRUNCATE TABLE
 id 
----
  1
(1 row)

INSERT 0 1
 vazifalar 
-----------
         0
(1 row)
  • TRUNCATE — jadvalni bir zumda bo'shatadi (qatorlarni birma-bir o'chirmaydi, fayllarni almashtiradi). Katta jadvalda DELETE dan ancha tez.
  • RESTART IDENTITY — id hisoblagichlari 1 dan boshlanadi. Shuning uchun yangi foydalanuvchi id'si — 1. Testda "birinchi vazifa id 1" deb yozish mumkin.
  • CASCADE — bu jadvallarga tashqi kalit bilan bog'langan boshqa jadvallar ham bo'shatiladi.

4.2 CASCADE nega kerak

sql
TRUNCATE foydalanuvchilar;
text
ERROR:  cannot truncate a table referenced in a foreign key constraint
DETAIL:  Table "vazifalar" references "foydalanuvchilar".
HINT:  Truncate table "vazifalar" at the same time, or use TRUNCATE ... CASCADE.

"Tashqi kalit bilan murojaat qilinadigan jadvalni bo'shatib bo'lmaydi. vazifalar → foydalanuvchilar ga ishora qiladi. Ikkalasini birga bo'shating yoki CASCADE ishlating". ON DELETE CASCADE (Foreign key va referential actions) TRUNCATE ga ta'sir qilmaydi — u faqat DELETE uchun. Hamma jadvalni bitta TRUNCATE da sanash eng aniq yo'l: nima tozalanayotgani ko'rinib turadi. Yolg'iz CASCADE ehtiyotsiz ishlatilsa, kutilmagan jadvalni ham bo'shatishi mumkin.

4.3 DELETE bilan farqi

sql
DELETE FROM foydalanuvchilar;
INSERT INTO foydalanuvchilar (email, toliq_ism)
  VALUES ('ikki@example.com', 'Ikki') RETURNING id;
text
DELETE 1
 id 
----
  2
(1 row)

INSERT 0 1

DELETE qatorlarni o'chirdi (ON DELETE CASCADE bilan bog'liqlari ham), lekin hisoblagich joyida qoldi — yangi id 2. Testlar natijasi oldingi testlar soniga bog'liq bo'lib qoladi. Shuning uchun test tozalashda TRUNCATE … RESTART IDENTITY.

4.4 Narxi

text
TRUNCATE: 105.8 ms

Kanon: 6 jadvalni TRUNCATE + test ma'lumotini yozish, 20 marta mediana — ~106 ms. ROLLBACK'dan 5 baravar sekin: TRUNCATE jadval fayllarini almashtiradi va qulf oladi. 100 ta testda — 10 soniya. Ko'p loyihalar uchun qabul qilinadigan narx, evaziga har qanday kod (COMMIT qiladigani ham) sinaladi.

vazifalar-api aynan shu usulni ishlatadi (test/pg-ombor.test.ts, 26-qismdan):

ts
/** Bo'sh ombor: hamma jadval tozalanadi, id hisoblagichlari 1 dan,
 *  bitta foydalanuvchi (id 1) */
async function tozala(pool: Pool): Promise<void> {
  await pool.query("TRUNCATE foydalanuvchilar, vazifalar, teglar, "
    + "vazifa_teglari, izohlar, vazifa_tarixi "
    + "RESTART IDENTITY CASCADE");
  await pool.query("INSERT INTO foydalanuvchilar (email, toliq_ism) "
    + "VALUES ('test@example.com', 'Test'), "
    + "('boshqa@example.com', 'Boshqa')");
}

Tozalash testdan oldin, keyin emas. Yiqilgan test o'z ma'lumotini qoldiradi — uni psql'da ochib, nima bo'lganini ko'rish mumkin. Keyingi test esa baribir toza boshlanadi.

Tekshirib ko'ring: Test POST /v1/vazifalar ni chaqiradi; ombor kodi ichida BEGIN … COMMIT bor. Tranzaksiya + ROLLBACK usuli ishlaydimi?

Javob

Yo'q. Ombor o'z ulanishida COMMIT qiladi — testning ROLLBACK i unga yetmaydi (boshqa ulanish yoki ichki COMMIT allaqachon saqlagan). Bunday kodni sinash uchun TRUNCATE (yoki template baza) kerak.

5. Usul 3: template baza

Postgres yangi bazani boshqa bazadan nusxa qilib yarata oladi: CREATE DATABASE yangi TEMPLATE manba. Test strategiyasi: bir marta migratsiyalangan bo'sh "shablon" baza tayyorlanadi, har test (yoki test fayli) uning nusxasini oladi.

text
DROP + CREATE … TEMPLATE: 350.2 ms
CREATE DATABASE … STRATEGY FILE_COPY (PG15+ sukut WAL_LOG): 788.4 ms
template'ga ulanish bor paytda: 55006 source database "t62_shablon" is being accessed by other users
  • Nusxa — 350 ms. TRUNCATE dan sekin, lekin to'liq izolyatsiya: har test o'z bazasida, hech narsa aralashmaydi. Sxema ham noldan yaratilmaydi (migratsiyalarni qayta qo'llash soniyalar oladi).
  • STRATEGY FILE_COPY — eski usul (fayllarni to'g'ridan nusxalash). Postgres 15 dan sukut WAL_LOG va kanonda u ikki baravar tez chiqdi.
  • 55006 — "manba bazaga boshqa foydalanuvchilar ulangan". Shablonga kimdir ulangan bo'lsa (masalan ochiq psql yoki hovuzdagi ulanish), nusxa olinmaydi. Shuning uchun shablonga faqat tayyorlash paytida ulaniladi, keyin hamma ulanish yopiladi.

Keyingi darsdagi Testcontainers'ning snapshot() / restoreSnapshot() metodlari ichida aynan shu mexanizm ishlaydi (Testcontainers).

6. Parallel testlar

node --test test fayllarini sukut bo'yicha alohida jarayonlarda, parallel ishga tushiradi (node:test va node:assert). Ikkita fayl bitta bazaga ulanib, ikkalasi ham TRUNCATE qilsa — bir-birining ma'lumotini o'chiradi. Xato tasodifiy paydo bo'ladi: bir safar o'tadi, bir safar yo'q. Bitta bazadagi ikki fayl vaqt bo'yicha:

Qadam Fayl A (jarayon 1) Fayl B (jarayon 2) Bazada
1 TRUNCATE, vazifa yaratdi — 1 ta vazifa
2 — TRUNCATE 0 ta
3 "ro'yxatda 1 ta" deb kutadi — 0 ta — A yiqildi
4 — vazifa yaratdi, tekshirdi B o'tdi

Jarayonlar tezligi har safar boshqacha — shuning uchun qaysi fayl yiqilishi ham har safar boshqacha.

Kanon buni Prisma testlarini qo'shganda topdi. Davosi — har test fayliga alohida baza:

Fayl Baza
pg-ombor.test.ts vazifalar_test (TEST_DATABASE_URL)
prisma-ombor.test.ts vazifalar_test_prisma (TEST_PRISMA_DATABASE_URL)
migratsiya.test.ts vazifalar_test_mig (vaqtinchalik)

Boshqa yo'llar: (1) node --test --test-concurrency=1 — fayllar ketma-ket (sodda, lekin sekin); (2) har faylga alohida sxema (CREATE SCHEMA test_<pid> + search_path) — bitta bazada, lekin trigger va funksiyalar sxemaga bog'liq bo'lsa murakkablashadi; (3) template'dan har faylga baza — eng toza.

Usul Narx (kanon) Izolyatsiya COMMIT qiladigan kod
Tranzaksiya + ROLLBACK 19 ms test ichida sinab bo'lmaydi
TRUNCATE 106 ms fayl ichida ketma-ket ha
Template'dan baza 350 ms to'liq ha
Noldan migratsiya soniyalar to'liq ha

7. Loyiha qadami: test strategiyasini hujjatlash (holat 65, 2-qism)

vazifalar-api kodi bu darsda o'zgarmaydi — strategiya allaqachon ishlayapti: Postgres testlari TRUNCATE bilan, Prisma testlari alohida bazada. Holat 65 da buni TESTLAR.md ga yozib qo'yamiz. Keyingi dasturchi nega bazalar uchta ekanini bilsin. TESTLAR.md oxiriga yangi bo'lim (kanon matni; oxirgi ikki band Testcontainers va fabrikaga tegishli — ularni keyingi ikki darsda yaratamiz):

text
## Prisma, kesh, migratsiya, Testcontainers (27-qism)
- `test/prisma-ombor.test.ts` — o'sha shartnoma + Postgres'ga xos holatlar;
  **alohida baza** `TEST_PRISMA_DATABASE_URL` (sukut `vazifalar_test_prisma`):
  `node --test` fayllarni parallel jarayonlarda ishlatadi — bitta bazada
  TRUNCATE qilinsa testlar bir-birini buzadi.
- `test/kesh-ombor.test.ts` — `KeshliOmbor` (xotira ombori + Redis
  `TEST_REDIS_URL`, sukut `redis://127.0.0.1:6380`): shartnoma, hit/miss,
  avlod, TTL, Redis'siz ishlash.
- `test/migratsiya.test.ts` — server ishga tushishidagi migratsiya
  tekshiruvi (vaqtinchalik baza `vazifalar_test_mig`).
- `test/konteyner.test.ts` — **Testcontainers** (opt-in:
  `TESTCONTAINERS=1 npm test`, Docker kerak): `postgres:18` konteyner
  (nomi `kanon27-tc-*`, Ryuk o'chiq, tmpfs), `prisma migrate deploy`,
  snapshot → har testdan oldin `restoreSnapshot()` (template baza);
  cheklovlar, trigger'lar, FK, RLS va shartnoma testlari.
- `test/fabrika.ts` — test ma'lumoti factory'si (faker `uz_UZ_latin`,
  seed bilan deterministik).
- Tozalash usullari narxi (20 marta, mediana): TRUNCATE + ma'lumot ~100 ms,
  tranzaksiya + ROLLBACK ~19 ms, template'dan yangi baza ~350 ms.

Kanon matnidagi qatorlar telefon uchun bo'lindi; oxirgi qatordan ichki fayl havolasi olib tashlandi. Hali commit qilmang — holat 65 ning commit'i Repository va SQL'ni testlash darsida.

8. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
Testdan keyin dev bazasi bo'sh test DATABASE_URL ni oldi alohida TEST_DATABASE_URL, nomida _test
cannot truncate a table referenced in a foreign key constraint bitta jadval yoki CASCADE siz hamma jadval bitta TRUNCATE da
"id 1" kutilgan, 7 keldi DELETE yoki ROLLBACK — hisoblagich qoldi RESTART IDENTITY
Testlar ba'zan yiqiladi, alohida o'tadi parallel fayllar bitta bazada har faylga baza yoki ketma-ket
ROLLBACK'dan keyin ham ma'lumot qoldi kod o'zi COMMIT qildi TRUNCATE yoki template
55006 … is being accessed by other users shablonga ulanish ochiq shablon ulanishlarini yoping

9. Mashqlar

Mashqlar kurs/mashqlar/27/62-test-db/ da.

1-mashq (oson): usulni tanlang

  • Eng arzon usul, lekin COMMIT qiladigan kodni sinab bo'lmaydi —
  • TRUNCATE da id'larni 1 dan boshlash —
  • Tashqi kalit bilan bog'langan jadvallarni ham bo'shatish —
  • Shablondan baza nusxasi: CREATE DATABASE …
  • node --test test fayllarini sukut bo'yicha qanday ishga tushiradi —
Yechim
  • ROLLBACK — kanonda 19 ms.
  • RESTART IDENTITY — DELETE da hisoblagich qoladi.
  • CASCADE — ehtiyotkorlik bilan; jadvallarni aniq sanang.
  • TEMPLATE — shablonga boshqa ulanish bo'lmasligi kerak (55006).
  • parallel — alohida jarayonlarda; bitta bazani bo'lishsa — beqaror testlar.

2-mashq (o'rta): test bazasi nomi

Parallel test fayllari uchun baza nomi yasang. testBazaNomi(fayl, pid): fayl nomidan (test/prisma-ombor.test.ts) papka va .test.ts ni olib tashlang, kichik harf, harf/raqam bo'lmagan belgilar _ ga; natija vazifalar_test_<nom>_<pid>. Postgres identifikatori 63 baytdan oshmasin — oshsa nomni qisqartiring (pid saqlanib qolsin). Sinang: test/prisma-ombor.test.ts, test/Migratsiya.test.ts, juda uzun nomli fayl.

Yechim
js
const MAKS = 63;

function testBazaNomi(fayl, pid) {
  const asos = fayl.split("/").pop().replace(/\.test\.ts$/, "");
  const toza = asos.toLowerCase().replace(/[^a-z0-9]+/g, "_");
  const oxiri = `_${pid}`;
  const boshi = `vazifalar_test_${toza}`;
  return boshi.slice(0, MAKS - oxiri.length) + oxiri;
}

console.log(testBazaNomi("test/prisma-ombor.test.ts", 4120));
console.log(testBazaNomi("test/Migratsiya.test.ts", 77));
const uzunFayl = `test/${"juda-uzun-".repeat(8)}.test.ts`;
const uzun = testBazaNomi(uzunFayl, 9);
console.log(uzun, uzun.length);

Konsolda:

text
vazifalar_test_prisma_ombor_4120
vazifalar_test_migratsiya_77
vazifalar_test_juda_uzun_juda_uzun_juda_uzun_juda_uzun_juda_u_9 63

Postgres 63 baytdan uzun identifikatorni jim qisqartiradi (NOTICE: identifier … will be truncated). Ikki uzun nom bir xil qisqarsa — ikki fayl bitta bazaga tushib qoladi. Shuning uchun qisqartirishni o'zimiz qilib, farqlovchi qismni (pid) oxirida saqladik. Kichik harf — qo'shtirnoqsiz identifikator Postgres'da kichik harfga o'giriladi.

3-mashq (qiyin): tozalash tartibi

Ba'zi muhitda TRUNCATE … CASCADE ishlatib bo'lmaydi (masalan huquq cheklangan). Unda jadvallar DELETE bilan tozalanadi va tartib muhim: avval bola jadvallar, keyin ota jadvallar. tozalashTartibi(boglanishlar) funksiyasini yozing: boglanishlar — { bola: [otalar] } obyekti; natija — har jadval o'zining hamma bolalaridan keyin keladigan tartib (topologik saralash). vazifalar sxemasidagi tashqi kalitlar: vazifalar → foydalanuvchilar, teglar → foydalanuvchilar, vazifa_teglari → vazifalar, teglar, izohlar → vazifalar, foydalanuvchilar, vazifa_tarixi → vazifalar.

Yechim
js
function tozalashTartibi(boglanishlar) {
  const jadvallar = new Set(Object.keys(boglanishlar));
  for (const otalar of Object.values(boglanishlar)) {
    for (const o of otalar) jadvallar.add(o);
  }
  const natija = [];
  const qoldi = new Set(jadvallar);
  while (qoldi.size > 0) {
    // bolasi qolmagan jadval — hech kim unga ishora qilmaydi
    const tayyor = [...qoldi].filter((j) =>
      ![...qoldi].some((b) => (boglanishlar[b] ?? []).includes(j)));
    if (tayyor.length === 0) throw new Error("aylana bog'lanish");
    tayyor.sort();
    for (const j of tayyor) {
      natija.push(j);
      qoldi.delete(j);
    }
  }
  return natija;
}

console.log(tozalashTartibi({
  vazifalar: ["foydalanuvchilar"],
  teglar: ["foydalanuvchilar"],
  vazifa_teglari: ["vazifalar", "teglar"],
  izohlar: ["vazifalar", "foydalanuvchilar"],
  vazifa_tarixi: ["vazifalar"],
}).join(" → "));

Konsolda:

text
izohlar → vazifa_tarixi → vazifa_teglari → teglar → vazifalar → foydalanuvchilar

Har qadamda "hech kim ishora qilmaydigan" jadvallar olinadi — ularni o'chirish hech qanday tashqi kalitni buzmaydi. foydalanuvchilar eng oxirida: hamma unga ishora qiladi. Bir qadamdagi jadvallarni alifbo bo'yicha saraladik — natija har safar bir xil. Bu — Topologik saralash va sikl aniqlash algoritmi. TRUNCATE bilan bu shart emas: bitta buyruqda sanalgan jadvallar birga bo'shatiladi.

10. Real ishda

  • CI — testlar oldidan bazani migratsiyalar bilan noldan quriladi (33–34-qismlarda), har job o'z bazasida.
  • Katta loyihalar — template yoki Testcontainers bilan har test faylga baza; tezlik uchun tmpfs (xotiradagi disk).
  • Rails, Django kabi framework'lar tranzaksiya + ROLLBACK'ni sukut qilib beradi — Node'da buni o'zingiz tanlaysiz.
  • Intervyuda: "Integration testlar bir-biriga ta'sir qilmasligi uchun nima qilasiz?", "TRUNCATE va DELETE farqi?", "Parallel testlarda baza qanday ajratiladi?"

Xulosa

  • Test bazasi — alohida (TEST_DATABASE_URL, nomida _test), sxemasi production bilan bir xil migratsiyalardan.
  • Tranzaksiya + ROLLBACK — 19 ms, lekin COMMIT qiladigan kod va hovuz bilan ishlamaydi.
  • TRUNCATE … RESTART IDENTITY CASCADE — ~106 ms, har qanday kod uchun; tozalash testdan oldin.
  • Template baza — ~350 ms, to'liq izolyatsiya; shablonga ulanish bo'lsa 55006.
  • node --test fayllari parallel — har faylga alohida baza yoki ketma-ket.

Keyingi dars: Testcontainers — test o'zi haqiqiy Postgres konteynerini ko'taradi, migratsiyalarni qo'llaydi va har testdan oldin snapshot'dan tiklaydi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Test DB strategiyalari: alohida baza, ROLLBACK, TRUNCATE va template — IlmHamroh