Mundarija (22)
- Bu darsda
- 1. Nega bu kerak?
- 2. Fixture va factory
- 3. Fabrika qoidalari
- 3.1 Minimal va yaroqli sukut
- 3.2 Noyob maydonlar: ketma-ket raqam
- 3.3 Bog'lanishli fabrika
- 3.4 Faqat kerakli miqdor
- 4. Faker: real ko'rinishdagi ma'lumot
- 4.1 O'zbekcha lokal
- 4.2 Seed — takrorlanadigan tasodif
- 4.3 Faker tuzoqlari
- 5. Builder va fishery
- 6. Loyiha qadami: test/fabrika.ts (holat 65, 4-qism)
- 7. Ko'p uchraydigan xatolar
- 8. Mashqlar
- 1-mashq (oson): to'ldiring
- 2-mashq (o'rta): umumiy fabrika yasovchi
- 3-mashq (qiyin): bog'lanishli fabrika
- 9. Real ishda
- Xulosa
- Manbalar
Test factory va fixture'lar: faker uz_UZ_latin, seed va bog'lanishli fabrikalar
Qisqacha: Factory (fabrika) — test ma'lumotini yaratadigan funksiya: testda faqat shu test uchun muhim maydon yoziladi (
vazifa(db, { matn: "Non olish" })), qolgani — yaroqli sukut qiymat. Bog'langan narsa kerak bo'lsa, fabrika uni o'zi yaratadi (egasi berilmasa — yangi foydalanuvchi). Tasodifiy, lekin real ko'rinishdagi ma'lumot — faker (fakerUZ_UZ_latin), va seed bilan har ishga tushirishda bir xil: biz ishga tushirdik —seed(27)dan keyin doimSadoqat Tohirova. Fixture esa — oldindan yozib qo'yilgan qat'iy ma'lumot to'plami; kichik va o'zgarmas holatlar uchun yaxshi, lekin tez eskiradi.
Bu darsda
- Fixture va factory farqini va qachon qaysi biri kerakligini tushuntirasiz.
- Testda faqat muhim maydonlarni yozadigan fabrika yasaysiz.
- Bog'lanishli fabrika (vazifa → egasi) va noyob maydonlar uchun ketma-ket raqam ishlatasiz.
@faker-js/fakerni o'zbekcha lokal va seed bilan deterministik qilasiz.- Builder naqshi va fishery kutubxonasi haqida bilasiz.
Oldin bilishingiz kerak: Test DB strategiyalari, Testcontainers, Seeding va test ma'lumotlari, Vaqt va tasodifni boshqarish.
Oldingi darsda har test toza bazada boshlanadigan qildik. Bo'sh baza — yaxshi boshlanish. Endi har test unga o'ziga kerakli ma'lumotni qanday qo'yishini tartibga solamiz.
1. Nega bu kerak?
Test "boshqa foydalanuvchida xuddi shu matnli vazifa bo'lishi mumkin"ni tekshiradi. Qo'lda yozilgan variant:
const { rows: [a] } = await db.query(
"INSERT INTO foydalanuvchilar (email, toliq_ism) "
+ "VALUES ('a@test.example', 'Aziz Karimov') RETURNING id");
const { rows: [b] } = await db.query(
"INSERT INTO foydalanuvchilar (email, toliq_ism) "
+ "VALUES ('b@test.example', 'Malika Tosheva') RETURNING id");
await db.query(
"INSERT INTO vazifalar (egasi_id, matn) VALUES ($1, $2)",
[a.id, "Non olish"]);
await db.query(
"INSERT INTO vazifalar (egasi_id, matn) VALUES ($1, $2)",
[b.id, "Non olish"]);Uch muammo:
- Shovqin. Test nimani tekshirayotgani (matn bir xil, egalar har xil) INSERT'lar orasida yo'qolib ketgan.
- Mo'rtlik. Ertaga
foydalanuvchilarga majburiy ustun qo'shilsa (masalantil), yuzlab testdagi INSERT'lar yiqiladi. - Takror. Har test bir xil INSERT'larni nusxalaydi.
Fabrika bilan:
await vazifa(db, { matn: "Non olish" });
assert.ok(await vazifa(db, { matn: "Non olish" }));Har chaqiruv o'z egasini yaratadi — ikki xil foydalanuvchi. Testda faqat muhim narsa qoldi: matn.
O'xshatish: restoranda "osh bering" deysiz. Oshpaz qozon, guruch, sabzi va go'shtni o'zi tanlaydi. "Go'shtsiz" desangizgina tafsilot aytasiz. Fabrika — shu oshpaz: siz faqat muhim farqni aytasiz.
2. Fixture va factory
Fixture — testlar uchun oldindan tayyorlangan qat'iy ma'lumot: JSON fayl yoki SQL skript ("3 ta foydalanuvchi, 10 ta vazifa"). Playwright darslarida "fixture" so'zini boshqa ma'noda ko'rgansiz — test uchun tayyorlangan muhit (Playwright I: e2e testlar asoslari); ma'lumot fixture'i ham shu oiladan.
| Fixture | Factory | |
|---|---|---|
| Ma'lumot | oldindan yozilgan, bir xil | test chaqirganda yaratiladi |
| Testda ko'rinadimi | yo'q — boshqa faylda | ha — muhim maydonlar testda |
| Sxema o'zgarsa | hamma fixture qayta yoziladi | bitta fabrika tuzatiladi |
| Yaxshi joyi | katta qat'iy namuna, hisobot testi | ko'p kichik, mustaqil testlar |
Fixture'ning yashirin xavfi — sirli mehmon (mystery guest): test "3-foydalanuvchining 7-vazifasi bajarilgan" deb kutadi, lekin nega — fixture faylini ochmaguncha bilib bo'lmaydi. Fabrikada test kerakli holatni o'zi aniq yaratadi.
vazifalar-api da ikkalasi bor. 26-qism namuna fayllari (003-namuna-asosiy.sql va boshqalar) — jonli server va qo'lda sinash uchun fixture. Seeding va test ma'lumotlari darsidagi prisma/seed.ts — demo ma'lumot. Konteyner testlari esa bo'sh bazada fabrika bilan ishlaydi.
3. Fabrika qoidalari
3.1 Minimal va yaroqli sukut
Fabrika chaqirilganda hech narsa bermasangiz ham — yaroqli obyekt chiqishi kerak: hamma NOT NULL va CHECK cheklovlaridan o'tadigan. Test faqat o'zi tekshirayotgan maydonni o'zgartiradi (ust — ustidan yoziladigan qiymatlar):
export async function vazifa(
pool: Pool,
ust: Partial<Pick<VazifaQatori,
"egasi_id" | "matn" | "bajarildi">> = {},
): Promise<VazifaQatori> { … }Partial<Pick<…>> — faqat ruxsat etilgan maydonlar, hammasi ixtiyoriy (Utility tiplar). Test id yoki versiya ni bera olmaydi — ularni baza va trigger'lar beradi.
3.2 Noyob maydonlar: ketma-ket raqam
foydalanuvchilar.email — noyob. vazifalar.matn — bir egasining faol vazifalari orasida noyob (014-migratsiyadagi EXCLUDE). Tasodifiy qiymat bir kun to'qnashadi va test "ba'zan" yiqiladi. Shuning uchun noyob maydonga ketma-ket raqam qo'shiladi: f1@test.example, f2@test.example, Non olish 3.
Email domeni — test.example: .example — hech kimga tegishli bo'lmagan zaxira domen (RFC 2606). Test hech qachon haqiqiy odamga xat yubormaydi.
3.3 Bog'lanishli fabrika
Vazifaga egasi kerak (tashqi kalit). Test egasini bermasa — fabrika uni o'zi yaratadi:
const egasi = ust.egasi_id ?? (await foydalanuvchi(pool)).id;Test "bitta foydalanuvchining ikki vazifasi" ni tekshirsa — egasini bir marta yaratib, ikkalasiga beradi. Muhim narsa testda ko'rinadi.
flowchart TD
T["vazifa(db, ust)"] --> E{ust.egasi_id bormi?}
E -->|yo'q| F["foydalanuvchi(db)"]
F --> I
E -->|ha| I[INSERT vazifalar]
I --> S{ust.matn bormi?}
S -->|yo'q| M[faker + ketma-ket raqam]
S -->|ha| R[test bergan matn]
M --> Q[RETURNING id, tartib, versiya]
R --> QDiagrammaga qarang: test bermagan har narsani fabrika o'zi to'ldiradi — bog'langan foydalanuvchini ham, matnni ham. Test bergan qiymat esa doim ustun.
3.4 Faqat kerakli miqdor
Fabrika test so'ragandan ortiq yaratmasin. "Har vazifaga 3 ta izoh va 2 ta teg" ni sukut qilish oson, lekin har test sekinlashadi va chalg'ituvchi ma'lumot paydo bo'ladi (ro'yxat testida kutilmagan izohlar). Izoh kerak bo'lsa — test o'zi chaqiradi.
4. Faker: real ko'rinishdagi ma'lumot
4.1 O'zbekcha lokal
@faker-js/faker — ism, manzil, telefon, matn kabi soxta, lekin real ko'rinadigan ma'lumot generatori. U lokallarga bo'lingan: fakerUZ_UZ_latin — o'zbek lotin ismlari.
npm i -D --save-exact @faker-js/faker@10.6.0vazifalar-api da u 39-holatdan beri bor (seed uchun). Biz ishga tushirdik (Node 24.21.0, @faker-js/faker 10.6.0). Chiqishda birinchi va oxirgi qatorni solishtiring:
import { fakerUZ_UZ_latin as faker } from "@faker-js/faker";
faker.seed(27);
for (let i = 0; i < 3; i++) console.log(faker.person.fullName());
faker.seed(27);
console.log("qayta seed:", faker.person.fullName());Sadoqat Tohirova
Umar Sadriddinov
Sulton Toyipov
qayta seed: Sadoqat Tohirova4.2 Seed — takrorlanadigan tasodif
faker.seed(27) — tasodifiy sonlar generatorini aniq nuqtadan boshlaydi (Vaqt va tasodifni boshqarish dagi urug'li generator). Bir xil seed — bir xil ketma-ketlik: biz skriptni ikki marta yurgizdik, chiqish bir xil. Qayta seed(27) dan keyin yana Sadoqat Tohirova.
Nega bu muhim? Test CI'da yiqildi, xabarda — "Sulton Toyipov". Seed bo'lmasa, lokalda bu holatni qayta yaratib bo'lmaydi: har safar boshqa ism. Seed bilan — xuddi o'sha ma'lumot. Kanon fabrikasi har test oldidan seed'ni qayta o'rnatadi: testlar tartibi o'zgarsa ham, har test o'z ma'lumotini bir xil oladi.
4.3 Faker tuzoqlari
Biz yana bir nechta maydonni sinadik (seed(1)):
faker.seed(1);
console.log("seed 1:", faker.person.fullName());
console.log(faker.location.city(), "|", faker.phone.number());
console.log(faker.internet.email());seed 1: Oynur Halilyeva
Bo`ka | 435-562-8064 x5118
Omina16@yahoo.comUchta topilma:
- **Shahar
Bo\ka** — lokal ma'lumotida tutuq belgisi ```` (backtick) bilan. Kursimizda esa oddiy'ishlatiladi. Test bunday matnni ko'rsatsa — qo'rqmang, lekin o'quvchiga ko'rinadigan demo ma'lumotda tekshiring. - Telefon — AQSh formati: o'zbek lokalida telefon shabloni yo'q, faker zaxira (inglizcha) lokalni oldi.
+998kerak bo'lsa — o'zingiz yasang:`+998 90 ${faker.string.numeric(3)} …`. - Email —
yahoo.com: haqiqiy domen. Testdan xat ketib qolsa — kimningdir haqiqiy qutisiga. Domenni majburlang:
faker.seed(1);
console.log(faker.internet.email({ provider: "example.com" }));
console.log(faker.phone.number({ style: "international" }));Oynur.Avazyeva@example.com
+15547280645provider — example.com. Xalqaro telefon ham +1 (AQSh). Kanon fabrikasi emailni faker'ga umuman bermaydi — f<n>@test.example: noyob va xavfsiz.
Tekshirib ko'ring: Nega fabrikada
faker.internet.email()dan ko'ra`f${n}@test.example`yaxshiroq?
Javob
Ikki sabab. (1) Noyoblik: faker tasodifiy, 1 000 ta testda ikkita bir xil email chiqishi mumkin — UNIQUE cheklovi testni "ba'zan" yiqitadi; ketma-ket raqam to'qnashmaydi. (2) Xavfsizlik: faker haqiqiy domenlar (yahoo.com) beradi; .example esa hech kimga tegishli emas. Faker'ni faqat "ko'rinishi muhim, noyobligi muhim emas" maydonlarga bering (ism).
5. Builder va fishery
Kanon fabrikasi — oddiy funksiyalar. Katta loyihalarda ikki naqsh uchraydi (kanonda sinalmagan, hujjat bo'yicha):
- Builder naqshi — zanjir bilan:
vazifaBuilder().bajarilgan().tegBilan("uy").egasi(f).build(). Ko'p "holat" (bajarilgan, o'chirilgan, muddati o'tgan) bo'lsa o'qilishi oson. - fishery — fabrikalar uchun TypeScript kutubxonasi:
Factory.define<Vazifa>(({ sequence }) => ({ id: sequence, matn: \Vazifa ${sequence}` })),vazifaFactory.build({ matn: "Non" }),buildList(5),onCreate(bazaga yozish),transientparametrlar. Ketma-ket raqam (sequence) vaparams(bizningust`) — xuddi shu g'oyalar.
Kichik loyihada o'z funksiyalaringiz yetarli: 40 qator, bog'liqliksiz. Fabrikalar ko'payib, "holatlar" murakkablashsa — fishery.
6. Loyiha qadami: test/fabrika.ts (holat 65, 4-qism)
Yangi fayl test/fabrika.ts (kanon kodi; qatorlar telefon uchun bo'lingan):
// fabrika.ts — test ma'lumoti FACTORY bilan: testda faqat test
// uchun MUHIM maydonlar yoziladi, qolgani yaroqli sukut.
// Faker (uz_UZ_latin) har test boshida seed bilan — deterministik
// (yiqilgan testni qayta yaratish mumkin). Ketma-ket raqam (n) —
// noyob maydonlar (email, matn) to'qnashmasin (014: faol vazifalar
// orasida matn noyob).
import { fakerUZ_UZ_latin as faker } from "@faker-js/faker";
import type { Pool } from "pg";
let n = 0;
export function fabrikaniBoshla(seed = 27): void {
faker.seed(seed);
n = 0;
}
export type FoydalanuvchiQatori = {
id: number; email: string; toliq_ism: string;
};
export type VazifaQatori = {
id: number; egasi_id: number; matn: string; bajarildi: boolean;
tartib: number; versiya: number;
};
export async function foydalanuvchi(
pool: Pool,
ust: Partial<Pick<FoydalanuvchiQatori,
"email" | "toliq_ism">> = {},
): Promise<FoydalanuvchiQatori> {
n++;
const { rows: [f] } = await pool.query<FoydalanuvchiQatori>(
"INSERT INTO foydalanuvchilar (email, toliq_ism) VALUES ($1, $2) "
+ "RETURNING id, email, toliq_ism",
[ust.email ?? `f${String(n)}@test.example`,
ust.toliq_ism ?? faker.person.fullName()]);
if (f === undefined) throw new Error("foydalanuvchi yaratilmadi");
return f;
}
/** Egasi berilmasa — o'zi yaratadi (relation bilan factory) */
export async function vazifa(
pool: Pool,
ust: Partial<Pick<VazifaQatori,
"egasi_id" | "matn" | "bajarildi">> = {},
): Promise<VazifaQatori> {
const egasi = ust.egasi_id ?? (await foydalanuvchi(pool)).id;
n++;
const bajarildi = ust.bajarildi ?? false;
const { rows: [v] } = await pool.query<VazifaQatori>(
`INSERT INTO vazifalar
(egasi_id, matn, bajarildi, bajarilgan_vaqt)
VALUES ($1, $2, $3, CASE WHEN $3 THEN now() END)
RETURNING id, egasi_id, matn, bajarildi, tartib, versiya`,
[egasi, ust.matn ?? `${faker.helpers.arrayElement(
["Hisobot", "Non olish", "Kitob o'qish", "Mashq"],
)} ${String(n)}`, bajarildi]);
if (v === undefined) throw new Error("vazifa yaratilmadi");
return v;
}E'tibor bering:
bajarilgan_vaqt— bazada "bajarildi bo'lsa, vaqt ham bo'lsin" degan cheklov bor:CHECK (bajarildi = (bajarilgan_vaqt IS NOT NULL))(CREATE TABLE va cheklovlar). Fabrika buni o'zi to'g'ri qiladi: test faqat{ bajarildi: true }deydi. Sxemaning bunday qoidalarini bilish — fabrikaning vazifasi, testniki emas.RETURNING— fabrika baza bergan qiymatlarni (id,tartib,versiya— trigger'lardan) qaytaradi. Test ularni tekshira oladi.- SQL parametrli —
$1, $2(Parametrli so'rovlar va SQL injection); faker matnida'bo'lsa ham hech narsa buzilmaydi. fabrikaniBoshla()— seed va hisoblagichni nolga qaytaradi.
test/konteyner.test.ts da importni qo'shing va har beforeEach da fabrikani boshlang:
import { fabrikaniBoshla, foydalanuvchi, vazifa } from "./fabrika.ts";
// "BT-11: migratsiyalar konteynerda" blokida:
beforeEach(async () => { db = await toza(); fabrikaniBoshla(); });Fabrikani ishlatadigan testlar — keyingi darsda. Hali commit qilmang.
7. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
duplicate key … email ba'zan |
tasodifiy noyob maydon | ketma-ket raqam |
| CI'da yiqilgan testni lokalda qaytarib bo'lmaydi | seed yo'q | faker.seed() har test oldidan |
| Sxemaga ustun qo'shildi — 200 test yiqildi | testlarda qo'lda INSERT | bitta fabrika |
| Test nimani tekshirishi tushunarsiz | fixture'dagi "sirli mehmon" | muhim maydon testda, fabrika bilan |
| Testlar sekin | fabrika keraksiz izoh/teg yaratadi | minimal sukut |
| Testdan haqiqiy odamga xat ketdi | faker'ning real domenlari | .example domen |
violates check constraint fabrikada |
sukut qiymat cheklovga mos emas | sukutni sxema qoidalari bilan moslang |
8. Mashqlar
Mashqlar kurs/mashqlar/27/64-fabrika/ da.
1-mashq (oson): to'ldiring
- Testlar uchun oldindan yozilgan qat'iy ma'lumot —
- Takrorlanadigan tasodif uchun faker metodi —
- Noyob email uchun fabrika ishlatadigan narsa —
- Hech kimga tegishli bo'lmagan domen —
test. - O'zbek lotin lokali —
faker
Yechim
- fixture — kichik qat'iy holatlar uchun; sxema o'zgarsa qayta yoziladi.
- seed — kanonda
fabrikaniBoshla(27). - ketma-ket raqam —
f1@,f2@… - example — RFC 2606 zaxira domeni.
- UZ_UZ_latin —
fakerUZ_UZ_latin.
2-mashq (o'rta): umumiy fabrika yasovchi
fabrikaYasa(sukut) funksiyasini yozing: sukut — (n) => obyekt (n — ketma-ket raqam, 1 dan). Qaytgan fabrikada build(ust) (sukut + ust birlashmasi) va buildList(soni, ust) bo'lsin; boshla() — hisoblagichni nolga. foydalanuvchiF fabrikasini (id, email: f<n>@test.example, til: "uz") yasab sinang: bitta oddiy, bitta { til: "ru" }, 2 talik ro'yxat, keyin boshla() va yana bitta.
Yechim
function fabrikaYasa(sukut) {
let n = 0;
return {
build(ust = {}) {
n++;
return { ...sukut(n), ...ust };
},
buildList(soni, ust = {}) {
return Array.from({ length: soni }, () => this.build(ust));
},
boshla() {
n = 0;
},
};
}
const foydalanuvchiF = fabrikaYasa((n) => ({
id: n,
email: `f${n}@test.example`,
til: "uz",
}));
console.log(foydalanuvchiF.build());
console.log(foydalanuvchiF.build({ til: "ru" }));
console.log(foydalanuvchiF.buildList(2).map((f) => f.email));
foydalanuvchiF.boshla();
console.log(foydalanuvchiF.build().id);Konsolda:
{ id: 1, email: 'f1@test.example', til: 'uz' }
{ id: 2, email: 'f2@test.example', til: 'ru' }
[ 'f3@test.example', 'f4@test.example' ]
1{ ...sukut(n), ...ust } — keyingi spread oldingisini yozib yuboradi: test bergan qiymat ustun (Spread va rest operatori). Har fabrikaning o'z hisoblagichi bor (closure). boshla() — kanondagi fabrikaniBoshla() ning vazifasi: har test bir xil raqamlardan boshlansin. fishery'dagi sequence, build, buildList — xuddi shu g'oya.
3-mashq (qiyin): bog'lanishli fabrika
Xotiradagi "baza" ({ foydalanuvchilar: [], vazifalar: [] }) bilan foydalanuvchi(db, ust) va vazifa(db, ust) fabrikalarini yozing. vazifa egasi berilmasa — o'zi foydalanuvchi yaratsin. bajarildi: true bo'lsa — bajarilganVaqt ham qo'yilsin (soxta soat: "2026-10-25T10:00:00Z"), aks holda null. Uch ssenariy: (a) vazifa(db) ikki marta — nechta foydalanuvchi? (b) bitta egaga ikki vazifa; (c) { bajarildi: true }. Har ssenariydan keyin bazadagi sonlarni chiqaring.
Yechim
let n = 0;
const SOAT = "2026-10-25T10:00:00Z";
function foydalanuvchi(db, ust = {}) {
n++;
const f = { id: db.foydalanuvchilar.length + 1,
email: `f${n}@test.example`, ...ust };
db.foydalanuvchilar.push(f);
return f;
}
function vazifa(db, ust = {}) {
const egasiId = ust.egasiId ?? foydalanuvchi(db).id;
n++;
const bajarildi = ust.bajarildi ?? false;
const v = {
id: db.vazifalar.length + 1,
egasiId,
matn: ust.matn ?? `Vazifa ${n}`,
bajarildi,
bajarilganVaqt: bajarildi ? SOAT : null,
};
db.vazifalar.push(v);
return v;
}
const sanoq = (db) =>
`foydalanuvchi ${db.foydalanuvchilar.length}, ` +
`vazifa ${db.vazifalar.length}`;
let db = { foydalanuvchilar: [], vazifalar: [] };
vazifa(db);
vazifa(db);
console.log("a)", sanoq(db));
db = { foydalanuvchilar: [], vazifalar: [] };
const aziz = foydalanuvchi(db);
vazifa(db, { egasiId: aziz.id });
vazifa(db, { egasiId: aziz.id });
console.log("b)", sanoq(db));
db = { foydalanuvchilar: [], vazifalar: [] };
const v = vazifa(db, { bajarildi: true });
console.log("c)", sanoq(db), "|", v.bajarilganVaqt);Konsolda:
a) foydalanuvchi 2, vazifa 2
b) foydalanuvchi 1, vazifa 2
c) foydalanuvchi 1, vazifa 1 | 2026-10-25T10:00:00Z(a) — har vazifa o'z egasini yaratdi: test "egasi kim" deb qiziqmasa, bu to'g'ri va izolyatsiyalangan. (b) — test egani o'zi yaratib berdi, chunki "bir egada ikki vazifa" testning mazmuni. (c) — fabrika bog'liq maydonni (bajarilganVaqt) o'zi to'ldirdi: bazadagi cheklov hech qachon testni chalg'itmaydi. Soatni o'zgarmas qildik — natija deterministik (Vaqt va tasodifni boshqarish).
9. Real ishda
- Rails (FactoryBot), Django (factory_boy), Laravel (model factories) — fabrika naqshi backend testlarining standarti; Node'da fishery,
@mswjs/datayoki o'z funksiyalari. - Demo va ko'rgazma — seed skriptlari ham ko'pincha o'sha fabrikalarni ishlatadi (Seeding va test ma'lumotlari).
- Shaxsiy ma'lumot — testlarda va staging'da haqiqiy foydalanuvchi ma'lumoti emas, faker; production nusxasi ishlatilsa — anonimlashtirish.
- Intervyuda: "Test ma'lumotini qanday tayyorlaysiz?", "Fixture va factory farqi?", "Beqaror testlarning sabablari?"
Xulosa
- Fabrika — testda faqat muhim maydon, qolgani yaroqli sukut; sxema o'zgarsa — bitta joyda tuzatiladi.
- Noyob maydonlar — ketma-ket raqam; email —
.exampledomen. - Bog'lanishli fabrika: egasi berilmasa o'zi yaratadi; bog'liq maydonlar (bajarilgan vaqt) fabrikada.
- Faker
uz_UZ_latin+seed— real ko'rinadigan, lekin takrorlanadigan ma'lumot (biz sinadik:seed(27)→Sadoqat Tohirova). - Faker tuzoqlari:
`tutuq belgisi, AQSh telefoni, haqiqiy email domenlari.
Keyingi dars: Repository va SQL'ni testlash — cheklovlar, trigger'lar va RLS'ni haqiqiy bazada tekshiramiz; nega pg-mem 15 ta migratsiyadan birortasini ham ko'tarolmadi; va holat 65 ni commit qilamiz.
Manbalar
- @faker-js/faker — lokallar,
seed,internet.email({ provider }): https://fakerjs.dev/guide/localization, https://fakerjs.dev/api/faker#seed - fishery: https://github.com/thoughtbot/fishery
- RFC 2606 —
.examplezaxira domeni: https://www.rfc-editor.org/rfc/rfc2606 - G. Meszaros, "xUnit Test Patterns" — Mystery Guest, Test Data Builder naqshlari.
- Kanon: holat 65 —
vazifalar-api/test/fabrika.ts. Faker chiqishlari — biz ishga tushirdik (Node 24.21.0, @faker-js/faker 10.6.0, 2026-10-27).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!