QA 29: Amaliyot — Capstone loyiha va 30 ta topshiriq (Zero to Hero Challenge)
🧪 QA Engineer — Zero to Hero
QA 29: Amaliyot — Capstone loyiha va 30 ta topshiriq (Zero to Hero Challenge)
Holat: 2026-yil oktabr. Kursning yakuniy amaliy darsi: real amaliyot ilovasi (Toolshop) ustida 3 haftalik capstone loyiha va butun kursni qamraydigan 30 ta topshiriq. Kod yechimlari Playwright 1.64 (Chromium), Zod 4.6 va @axe-core/playwright 4.13 bilan, SQL yechimlari SQLite 3.51 da, Postman kolleksiyasi Newman 6.2 bilan ishga tushirib tekshirilgan; API misollari restful-booker va Toolshop'ning 2026-yil oktabrdagi haqiqiy javoblariga asoslangan.
Bu darsdan keyin siz: ishga topshirishda ko'rsatadigan to'liq QA portfolio'ga va 1–28-darslardagi har bir ko'nikmani amalda sinab ko'rgan tajribaga ega bo'lasiz.
- real ilova uchun strategiyadan CI'gacha bo'lgan butun QA siklini o'zingiz bajarasiz;
- 30 ta topshiriq orqali test dizayn, hujjatlar, API, SQL, mobil, avtomatlashtirish va "hero" ko'nikmalarini mustahkamlaysiz;
- har bir yechimni tekshirilgan namuna bilan solishtirib, o'z xatolaringizni topasiz.
Mundarija
- Bu dars qanday ishlaydi
- Capstone loyiha: Toolshop'ni to'liq QA qilish
- Topshiriqlar xaritasi
- Test dizayn: 1–8
- Hujjatlar va bug'lar: 9–13
- Web, API va SQL: 14–19
- Mobil va Proxyman: 20–22
- Avtomatlashtirish: 23–27
- Hero darajasi: 28–30
- Zero → Hero: bosib o'tgan yo'lingiz
- Xulosa
- Manbalar
1. Bu dars qanday ishlaydi {#qanday}
Dars ikki qismdan iborat:
- Capstone loyiha — 2–3 haftalik katta ish, natijasi GitHub'dagi portfolio (QA 28'da nega muhimligini ko'rdik);
- 30 ta topshiriq — har biri 15 daqiqadan 2 soatgacha; capstone'dan oldin "isinish" yoki keyin takrorlash uchun.
| Belgi | Daraja | Taxminiy vaqt |
|---|---|---|
| 🟢 | Oson | 15–30 daqiqa |
| 🟡 | O'rta | 30–60 daqiqa |
| 🔴 | Qiyin | 1–2 soat |
Qoidalar:
- Avval o'zingiz yeching, keyin yechimni oching. Yechim — to'g'ri variantlardan biri, yagona to'g'ri javob emas.
- Kod yechimlari biz tekshirgan muhitda ishlaydi: Node.js 24,
@playwright/test1.64.0 (Chromium),zod4.6.5,@axe-core/playwright4.13.0,newman6.2.3, SQLite 3.51. Boshqa versiyada kichik farqlar bo'lishi mumkin. - Amaliyot saytlari — umumiy ommaviy resurs. Ularga yuklama (load) testi, xavfsizlik skanerlari yoki yuzlab akkaunt yaratish bilan zarar yetkazmang.
- DemoBozor — kursdagi xayoliy mahsulot; uning qoidalari (QA 5 va boshqa darslarda) topshiriqlarda ham amal qiladi.
2. Capstone loyiha: Toolshop'ni to'liq QA qilish {#capstone}
Capstone: Toolshop'ni 3 haftada to'liq QA qilish — haftalar va natijalar
2.1. Nega aynan Toolshop
Practice Software Testing — "Toolshop" — testlashni o'rganish uchun maxsus yaratilgan ochiq loyiha: Angular'da yozilgan do'kon interfeysi, Laravel'dagi REST API va Swagger hujjati. Eng qimmatli tomoni — ataylab bug'lar qo'shilgan versiyasi bor: haqiqiy bug hunting mashqi uchun ideal.
| Nima | Manzil |
|---|---|
| UI (asosiy, v5) | https://practicesoftwaretesting.com |
| UI (ataylab bug'li) | https://with-bugs.practicesoftwaretesting.com |
| API | https://api.practicesoftwaretesting.com |
| Swagger hujjati | https://api.practicesoftwaretesting.com/api/documentation |
| API (bug'li versiya) | https://api-with-bugs.practicesoftwaretesting.com |
| Manba kod | https://github.com/testsmith-io/practice-software-testing |
Demo akkauntlar (loyiha README'sidan; customer va admin login'lari API orqali 2026-yil oktabrda tekshirildi):
| Rol | Parol | |
|---|---|---|
| admin | admin@practicesoftwaretesting.com | welcome01 |
| customer | customer@practicesoftwaretesting.com | welcome01 |
| customer | customer2@practicesoftwaretesting.com | welcome01 |
Nimalarni testlash mumkin: katalog (kategoriyalar, brendlar, eco-friendly filtri, saralash, qidiruv), mahsulot sahifasi, savatcha, checkout, kirish/ro'yxatdan o'tish/parolni tiklash, shaxsiy kabinet, aloqa formasi, ijara (rentals) bo'limi; v5'da 7 tilga o'tish (DE, EL, EN, ES, FR, NL, TR).
Texnik faktlar (2026-yil oktabrda tekshirilgan):
- UI elementlarida
data-testatributlari bor (email,password,login-submit,search-query,sort,product-name,product-price...) → Playwright'datestIdAttribute: 'data-test'; - v5 oddiy yo'llardan foydalanadi (
/auth/login,/category/hand-tools), bug'li versiya esa hash yo'llardan (/#/auth/login); POST /users/login→{ "access_token": "..." };GET /products?page=1→ sahifalangan javob (current_page,data,per_page,total,last_page).
💡 Maslahat: Soddaroq yo'l kerak bo'lsa — capstone'ni saucedemo + restful-booker juftligida bajaring. QA 18–QA 21dagi kod deyarli o'zgarishsiz ishlaydi. Lekin Toolshop real mahsulotga yaqinroq va bug'li versiyasi bug report'lar uchun haqiqiy material beradi.
2.2. Deliverable'lar va ball taqsimoti
| # | Deliverable | Format / joyi | Darslar | Ball |
|---|---|---|---|---|
| 1 | 1 sahifali test strategiya | docs/test-strategy.md | QA 27 | 5 |
| 2 | Risk matritsasi (kamida 8 funksiya) | docs/risk-matrix.md | QA 27 | 5 |
| 3 | Smoke va regression checklist | docs/checklist.md | QA 7 | 5 |
| 4 | 30 ta test case (EP, BVA, decision table, state) | docs/test-cases.csv | QA 5–7 | 15 |
| 5 | Bug'li versiyadan 10 ta bug report | docs/bugs/BUG-001.md ... | QA 8 | 15 |
| 6 | API kolleksiya (Postman yoki Bruno) + newman run | postman/ yoki bruno/ | QA 10–11 | 10 |
| 7 | Playwright framework: POM + fixtures + UI testlar | pages/, fixtures/, tests/ui/ | QA 18–19 | 15 |
| 8 | API testlar (Zod sxemalari bilan) | tests/api/, schemas/ | QA 20 | 10 |
| 9 | a11y (axe) va visual test | tests/a11y/, tests/visual/ | QA 25 | 5 |
| 10 | GitHub Actions CI + HTML report artifact | .github/workflows/ | QA 21 | 10 |
| 11 | README + 2–3 daqiqalik demo video | README.md | QA 28 | 5 |
| Jami | 100 |
2.3. Repo tuzilmasi
toolshop-qa-portfolio/
├── README.md
├── .env.example # BASE_URL, API_BASE_URL, TOOLSHOP_EMAIL, TOOLSHOP_PASSWORD
├── docs/
│ ├── test-strategy.md
│ ├── risk-matrix.md
│ ├── checklist.md
│ ├── test-cases.csv
│ ├── exploratory-sessions.md
│ └── bugs/ # BUG-001.md ... BUG-010.md + skrinshotlar
├── postman/ # yoki bruno/
├── pages/ # LoginPage.ts, CatalogPage.ts, ProductPage.ts, CartPage.ts
├── fixtures/test.ts
├── schemas/product.ts # Zod sxemalari
├── tests/
│ ├── ui/
│ ├── api/
│ ├── a11y/
│ └── visual/
├── playwright.config.ts
├── package.json
└── .github/workflows/playwright.yml
2.4. Boshlang'ich kod (tekshirilgan)
playwright.config.ts:
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests",
fullyParallel: true,
retries: process.env.CI ? 1 : 0,
reporter: [["list"], ["html", { open: "never" }]],
use: {
baseURL: process.env.BASE_URL ?? "https://practicesoftwaretesting.com",
testIdAttribute: "data-test",
trace: "on-first-retry",
},
projects: [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }],
});
Birinchi UI testi — tests/ui/login.spec.ts:
import { test, expect } from "@playwright/test";
test('customer tizimga kiradi va "My account" sahifasini ko\'radi @smoke', async ({ page }) => {
await page.goto("/auth/login");
await page
.getByTestId("email")
.fill(process.env.TOOLSHOP_EMAIL ?? "customer@practicesoftwaretesting.com");
await page.getByTestId("password").fill(process.env.TOOLSHOP_PASSWORD ?? "welcome01");
await page.getByTestId("login-submit").click();
await expect(page).toHaveURL(/\/account$/);
await expect(page.getByTestId("page-title")).toHaveText("My account");
});
Birinchi API testlari — tests/api/products.spec.ts:
import { test, expect } from "@playwright/test";
import { z } from "zod";
test.use({
baseURL: process.env.API_BASE_URL ?? "https://api.practicesoftwaretesting.com",
});
const ProductPage = z.object({
current_page: z.number(),
per_page: z.number(),
total: z.number(),
last_page: z.number(),
data: z.array(
z.object({
id: z.string(),
name: z.string(),
price: z.number(),
in_stock: z.boolean(),
}),
),
});
test("API: login token qaytaradi", async ({ request }) => {
const res = await request.post("/users/login", {
data: {
email: process.env.TOOLSHOP_EMAIL ?? "customer@practicesoftwaretesting.com",
password: process.env.TOOLSHOP_PASSWORD ?? "welcome01",
},
});
expect(res.status()).toBe(200);
const body = await res.json();
expect(typeof body.access_token).toBe("string");
});
test("API: mahsulotlar sahifalanadi va sxemaga mos", async ({ request }) => {
const res = await request.get("/products?page=1");
expect(res.ok()).toBeTruthy();
const page1 = ProductPage.parse(await res.json());
expect(page1.data.length).toBeLessThanOrEqual(page1.per_page);
expect(page1.last_page).toBe(Math.ceil(page1.total / page1.per_page));
});
Bu uchta test 2026-yil oktabrda Chromium'da o'tdi. Login ma'lumotlari koddan emas, muhit o'zgaruvchilaridan olinadi (TOOLSHOP_EMAIL, TOOLSHOP_PASSWORD, BASE_URL, API_BASE_URL); fallback qiymatlar faqat ommaviy demo akkaunt uchun. .env faylini o'qish uchun QA 19dagi kabi dotenv ulang va o'zgaruvchilarni prefiks bilan nomlang (USERNAME kabi tizim nomlaridan qoching). Shu yerdan boshlab QA 19'dagi kabi POM va fixture'larga o'ting.
💡 Maslahat: Network mocking uchun tayyor g'oya: QA 19da mahsulotlar API'si 500 qaytarganda Toolshop interfeysi foydalanuvchiga hech qanday xato xabarini ko'rsatmasligi aniqlangan. Shu holat uchun
page.routetesti va bug report — capstone'ga kuchli qo'shimcha.
API qismi uchun tayyor g'oyalar (2026-yil 9-oktabrda curl bilan tekshirilgan):
| So'rov | Natija | Nimani ko'rsatadi |
|---|---|---|
GET /users token'siz | 401 | Autentifikatsiya ishlaydi |
GET /users customer token bilan | 403 | Avtorizatsiya: oddiy foydalanuvchi admin ro'yxatini ko'rmaydi |
GET /users/me customer token bilan | 200 | O'z profiliga ruxsat bor |
GET /products?sort=hacker,up | 500 | Noto'g'ri parametr validatsiya qilinmagan — 400 kutilardi; bug report uchun material |
2.5. 3 haftalik reja
| Hafta | Kunlar | Nima qilasiz |
|---|---|---|
| 1 | 1–2 | Ilovani o'rganish (har bir sahifa, rollar, API Swagger), savollar ro'yxati |
| 1 | 3–4 | Test strategiya va risk matritsasi |
| 1 | 5–7 | Checklist, 30 ta test case, RTM |
| 2 | 8–9 | v5 build'da test case'larni bajarish, natijalarni yozish |
| 2 | 10–12 | Bug'li build'da bug hunting: 2 ta 60 daqiqalik exploratory sessiya, 10 ta bug report |
| 2 | 13–14 | API kolleksiya: login → token → mahsulotlar → savatcha; negative testlar; newman |
| 3 | 15–17 | Playwright: config, POM, fixtures, 10–15 ta UI test |
| 3 | 18–19 | API testlar (Zod), a11y va visual test |
| 3 | 20–21 | GitHub Actions, README, demo video, yakuniy tekshiruv |
2.6. Baholash rubrikasi
| Soha | A'lo | Qayta ishlash kerak |
|---|---|---|
| Strategiya va risk | Risklar asosli, test chuqurligi risk bilan bog'langan | Umumiy gaplar, risk va test o'rtasida bog'liqlik yo'q |
| Test case'lar | Texnikalar ko'rinadi (chegaralar, kombinatsiyalar), kutilgan natija aniq | "Ishlashi kerak" kabi kutilgan natijalar, faqat positive |
| Bug report'lar | Har biri qayta hosil qilinadi, bitta bug — bitta report, dalil bor | Bir report'da bir nechta bug, qadamlar yo'q |
| API | Chaining, assertion'lar, negative holatlar | Faqat "status 200" tekshiruvi |
| Avtomatlashtirish | POM, mustaqil testlar, barqaror locator'lar, sleep yo'q | waitForTimeout, testlar bir-biriga bog'liq |
| CI va hisobot | PR'da ishlaydi, report artifact, yashil | CI yo'q yoki doimiy qizil |
| README | 1 daqiqada tushuniladi, natijalar va cheklovlar halol yozilgan | Faqat "npm test" |
⚠️ Diqqat: Toolshop — ko'pchilik o'quvchilar foydalanadigan ommaviy sayt. Ro'yxatdan o'tishni testlasangiz, o'rtacha miqdorda va unikal emaillar bilan qiling; yuklama testi va xavfsizlik skanerlarini ishga tushirmang. Bug'li versiyada topilgan bug'larni portfolio'ingizda hujjatlashtiring.
3. Topshiriqlar xaritasi {#mashqlar}
| # | Topshiriq | Daraja | Darslar |
|---|---|---|---|
| 01 | SMS kod uchun Equivalence Partitioning | 🟢 | QA 5 |
| 02 | Savatcha soni uchun 2 va 3 qiymatli BVA | 🟢 | QA 5 |
| 03 | Bepul yetkazib berish chegarasi | 🟢 | QA 2, 5 |
| 04 | Chegirmalar decision table | 🟡 | QA 5 |
| 05 | Buyurtma holatlari: state transition | 🟡 | QA 6 |
| 06 | Pairwise: 54 kombinatsiyadan 9 ta test | 🟡 | QA 6 |
| 07 | Muddatli to'lov: EP + BVA kombinatsiyasi | 🔴 | QA 5 |
| 08 | Exploratory charter va sessiya hisoboti | 🟡 | QA 6 |
| 09 | OTP login uchun 5 ta test case | 🟢 | QA 7 |
| 10 | Yomon test case'ni tuzatish | 🟢 | QA 7 |
| 11 | Toolshop'dagi real bug uchun bug report | 🟡 | QA 8 |
| 12 | 8 ta bug: severity va priority | 🟡 | QA 8 |
| 13 | Mini RTM va qamrov | 🟡 | QA 7 |
| 14 | DevTools: bug kimniki? | 🟢 | QA 9 |
| 15 | curl bilan booking yaratish va o'qish | 🟢 | QA 9–10 |
| 16 | API negative va authZ testlari | 🟡 | QA 11, 24 |
| 17 | Postman: token chaining | 🟡 | QA 10 |
| 18 | SQL: buyurtmalar yaxlitligi | 🟡 | QA 12 |
| 19 | SQL: to'lovlar va eng ko'p daromad | 🔴 | QA 12 |
| 20 | Checkout uchun mobil interruption checklisti | 🟢 | QA 14 |
| 21 | Proxyman: har stsenariyga to'g'ri asbob | 🟡 | QA 15 |
| 22 | Proxyman Map Local: chegaraviy javoblar | 🟡 | QA 15 |
| 23 | Playwright: login testlari | 🟢 | QA 18 |
| 24 | Playwright: savatcha badge | 🟡 | QA 18 |
| 25 | Playwright POM: checkout summasi | 🔴 | QA 19 |
| 26 | Playwright API + Zod | 🔴 | QA 20 |
| 27 | GitHub Actions: PR'da smoke | 🟡 | QA 21 |
| 28 | k6: thresholds va natijani o'qish | 🟡 | QA 23 |
| 29 | Accessibility: axe bilan skanerlash | 🔴 | QA 25 |
| 30 | AI yozgan test case'larni audit qilish | 🔴 | QA 26 |
4. Test dizayn: 1–8 {#test-dizayn}
Topshiriq 01: SMS kod uchun Equivalence Partitioning (🟢) {#t01}
DemoBozor qoidasi: SMS kod — 6 raqam, 120 soniya amal qiladi, 3 marta noto'g'ri kiritilsa raqam 15 daqiqaga bloklanadi. Kod kiritish maydoni uchun ekvivalent bo'laklarni (valid va invalid) aniqlang va har biriga vakil qiymat hamda kutilgan natija yozing.
<details> <summary>💡 Yechimni ko'rish</summary>
| # | Bo'lak | Vakil qiymat | Kutilgan natija |
|---|---|---|---|
| V1 | 6 raqam, to'g'ri, 120 s ichida | SMS'dagi kod, masalan 482915 | Kirish muvaffaqiyatli |
| V2 | 6 raqam, 0 bilan boshlanadi | 012345 (agar SMS'da shu bo'lsa) | Qabul qilinadi — kod matn sifatida solishtiriladi |
| I1 | 6 raqam, noto'g'ri | 000000 | "Kod noto'g'ri", qolgan urinishlar soni kamayadi |
| I2 | 5 raqam | 48291 | Yuborib bo'lmaydi yoki format xatosi |
| I3 | 7 raqam | 4829150 | 7-raqam kiritilmaydi yoki format xatosi |
| I4 | Raqam bo'lmagan belgi | 48a915 | Harf qabul qilinmaydi |
| I5 | Bo'sh | Tugma faol emas yoki "kodni kiriting" | |
| I6 | To'g'ri kod, lekin muddati o'tgan | to'g'ri kod 121-soniyada | "Kod muddati tugagan", yangi kod so'rash taklifi |
| I7 | 3 marta noto'g'ri kiritilgandan keyin | to'g'ri kod 4-urinishda | Raqam bloklangan, to'g'ri kod ham qabul qilinmaydi |
E'tibor bering:
- V2 — klassik tuzoq: kod son sifatida saqlansa,
012345→12345bo'lib qoladi va to'g'ri kod rad etiladi; - I6 va I7 — vaqt va holatga bog'liq bo'laklar; ularning chegaralarini (119/120/121 soniya; 2- va 3-xato) keyingi texnikalar — BVA va state transition bilan to'liq tekshiramiz.
</details>
Topshiriq 02: Savatcha soni uchun 2 va 3 qiymatli BVA (🟢) {#t02}
DemoBozor: savatchada bitta mahsulot soni 1–99 (butun son). Ekvivalent bo'laklarni yozing, keyin 2 qiymatli va 3 qiymatli BVA bo'yicha test qiymatlarini va kutilgan natijalarni chiqaring.
<details> <summary>💡 Yechimni ko'rish</summary>
Bo'laklar: ≤ 0 (invalid) · 1–99 (valid) · ≥ 100 (invalid). Har bir chegarada ikkita chegaraviy qiymat bor — chap bo'lakning oxiri va o'ng bo'lakning boshi: 0 | 1 va 99 | 100.
- 2 qiymatli BVA (chegaraviy qiymat + qo'shni bo'lakdagi eng yaqin qiymat): 0, 1, 99, 100;
- 3 qiymatli BVA (har bir chegaraviy qiymat + ikkala qo'shnisi): 0 → {−1, 0, 1}, 1 → {0, 1, 2}, 99 → {98, 99, 100}, 100 → {99, 100, 101}. Birlashtirilganda: −1, 0, 1, 2, 98, 99, 100, 101.
| Qiymat | Kutilgan natija |
|---|---|
| −1 | Rad etiladi: UI'da manfiy son kiritib bo'lmaydi, API'da 400/422 |
| 0 | Rad etiladi (yoki talab bo'yicha mahsulot savatchadan o'chiriladi — PO bilan aniqlang) |
| 1 | Qabul qilinadi; "−" tugmasi faol emas yoki o'chirishni taklif qiladi |
| 2 | Qabul qilinadi |
| 98 | Qabul qilinadi |
| 99 | Qabul qilinadi; "+" tugmasi faol emas |
| 100 | Rad etiladi: UI'da kiritib bo'lmaydi, API'da 400/422 |
| 101 | Rad etiladi |
⚠️ Diqqat: Ko'p manbalarda 3 qiymatli BVA faqat valid bo'lakning chegaralari atrofida olinadi ({0, 1, 2, 98, 99, 100}). Bu ISTQB ta'rifining keng tarqalgan noto'g'ri talqini: invalid bo'laklarning chegaraviy qiymatlari (0 va 100) ham chegaraviy qiymat hisoblanadi. Batafsil: QA 5.
Qo'shimcha: −1 va 100 ni API orqali ham yuboring (POST /api/v1/cart/items — xayoliy endpoint) — UI cheklovi server cheklovi emas.
</details>
Topshiriq 03: Bepul yetkazib berish chegarasi (🟢) {#t03}
Qoida: mahsulotlar summasi ≥ 300 000 so'm bo'lsa yetkazib berish bepul, aks holda 20 000 so'm. Premium a'zolar uchun har doim bepul. Chegaraviy test qiymatlarini yozing. Qaysi qiymat QA 2dagi > vs >= defektini ushlaydi? Qanday savollarni PO'ga berasiz?
<details> <summary>💡 Yechimni ko'rish</summary>
Bo'laklar: < 300 000 (yetkazish pullik) va ≥ 300 000 (bepul); chegara 299 999 | 300 000.
| Mahsulotlar summasi | Premium | Kutilgan yetkazish narxi | Qaysi BVA |
|---|---|---|---|
| 299 998 | Yo'q | 20 000 | 3 qiymatli |
| 299 999 | Yo'q | 20 000 | 2 va 3 qiymatli |
| 300 000 | Yo'q | 0 | 2 va 3 qiymatli |
| 300 001 | Yo'q | 0 | 3 qiymatli |
| 299 999 | Ha | 0 | Premium istisnosi |
>vs>=defektini aynan 300 000 ushlaydi: noto'g'ri kodda 300 000 so'mlik buyurtmaga 20 000 qo'shiladi. Bu — QA 8dagideliveryFee()bug'i (DB-210).- Amaliy nuans: agar narxlar faqat mingga karrali bo'lsa, real qo'shnilar 299 000 va 301 000 bo'ladi. BVA'da qo'shni qiymat — ma'lumotning eng kichik qadami.
PO'ga savollar:
- Chegirma qo'llanib, summa 300 000 dan pastga tushsa — yetkazish pullikmi? (Qoida "mahsulotlar summasi" deydi — chegirmadan oldingi summa, lekin tasdiqlatish kerak.)
- Savatchadan mahsulot o'chirilib, summa chegaradan tushsa, narx darhol qayta hisoblanadimi?
- Viloyatlar uchun ham shu qoidami?
</details>
Topshiriq 04: Chegirmalar decision table (🟡) {#t04}
DemoBozor qoidalari: yangi mijoz (birinchi buyurtma) — 10%; yaroqli BAHOR15 promo-kodi — 15% (minimal summa 200 000 so'm); chegirmalar qo'shilmaydi — kattasi qo'llanadi; Premium a'zo — har doim bepul yetkazib berish. Mahsulotlar summasi 250 000 so'm deb oling (promo minimalidan yuqori, bepul yetkazish chegarasidan past). To'liq decision table tuzing (chegirma, yetkazish, jami), keyin uni qisqartiring.
<details> <summary>💡 Yechimni ko'rish</summary>
To'liq jadval (2³ = 8 qoida):
| Shart / natija | R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 |
|---|---|---|---|---|---|---|---|---|
| Yangi mijoz | Ha | Ha | Ha | Ha | Yo'q | Yo'q | Yo'q | Yo'q |
BAHOR15 yaroqli | Ha | Ha | Yo'q | Yo'q | Ha | Ha | Yo'q | Yo'q |
| Premium | Ha | Yo'q | Ha | Yo'q | Ha | Yo'q | Ha | Yo'q |
| Chegirma | 15% (37 500) | 15% (37 500) | 10% (25 000) | 10% (25 000) | 15% (37 500) | 15% (37 500) | 0 | 0 |
| Yetkazish | 0 | 20 000 | 0 | 20 000 | 0 | 20 000 | 0 | 20 000 |
| Jami | 212 500 | 232 500 | 225 000 | 245 000 | 212 500 | 232 500 | 250 000 | 270 000 |
Qisqartirilgan jadval: promo-kod yaroqli bo'lsa, "yangi mijoz" sharti natijaga ta'sir qilmaydi (15% > 10%), shuning uchun R1+R5 va R2+R6 birlashadi:
| Shart / natija | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| Yangi mijoz | – | – | Ha | Ha | Yo'q | Yo'q |
BAHOR15 yaroqli | Ha | Ha | Yo'q | Yo'q | Yo'q | Yo'q |
| Premium | Ha | Yo'q | Ha | Yo'q | Ha | Yo'q |
| Chegirma | 15% | 15% | 10% | 10% | 0 | 0 |
| Yetkazish | 0 | 20 000 | 0 | 20 000 | 0 | 20 000 |
8 o'rniga 6 ta test. Lekin ehtiyot bo'ling: qisqartirish haqiqiy foizlarga bog'liq. TEJA5 (5%) promo-kodi bilan yangi mijozning 10% i yutadi va R1/R5 natijalari farq qiladi — konfiguratsiyani tekshirib, kerak bo'lsa to'liq jadvalga qayting. Muddati o'tgan QISH10 yoki KUZ10 esa "promo-kod yaroqli = Yo'q" ustunlariga tushadi.
</details>
Topshiriq 05: Buyurtma holatlari — state transition (🟡) {#t05}
DemoBozor buyurtma holatlari: CREATED → PENDING_PAYMENT → PAID → PACKING → SHIPPED → DELIVERED; CANCELLED — CREATED, PENDING_PAYMENT, PAID (pul qaytariladi) va PACKING dan; RETURNED — DELIVERED dan 10 kun ichida; naqd to'lovda CREATED → PACKING.
- Barcha ruxsat etilgan o'tishlarni sanang.
- Barcha o'tishlarni qamraydigan minimal test yo'llarini (path) tuzing.
- Kamida 5 ta ruxsat etilmagan o'tishni yozing.
<details> <summary>💡 Yechimni ko'rish</summary>
1. Ruxsat etilgan o'tishlar — 11 ta (hodisa nomlari QA 6dagi state table bilan bir xil):
| # | Dan | Ga | Hodisa |
|---|---|---|---|
| 1 | CREATED | PENDING_PAYMENT | E1 to'lovni boshlash [karta] |
| 2 | PENDING_PAYMENT | PAID | E3 to'lov o'tdi |
| 3 | PAID | PACKING | E4 yig'ishni boshlash |
| 4 | PACKING | SHIPPED | E5 kuryerga topshirish |
| 5 | SHIPPED | DELIVERED | E6 yetkazildi |
| 6 | DELIVERED | RETURNED | E8 qaytarish [≤ 10 kun] |
| 7 | CREATED | CANCELLED | E7 bekor qilish |
| 8 | PENDING_PAYMENT | CANCELLED | E7 bekor qilish |
| 9 | PAID | CANCELLED | E7 bekor qilish (pul qaytariladi) |
| 10 | PACKING | CANCELLED | E7 bekor qilish |
| 11 | CREATED | PACKING | E2 tasdiqlash [naqd] |
8 holat × 8 hodisa = 64 katak; shundan faqat 11 tasi ruxsat etilgan o'tish, qolgan 53 tasi — "ruxsat etilmagan" kataklar, ularning eng xavflilarini alohida testlaymiz.
2. Barcha 11 o'tishni qamraydigan 5 ta yo'l:
| Yo'l | Ketma-ketlik | Qamralgan o'tishlar |
|---|---|---|
| P1 | CREATED → PENDING_PAYMENT → PAID → PACKING → SHIPPED → DELIVERED → RETURNED | 1, 2, 3, 4, 5, 6 |
| P2 | CREATED → CANCELLED | 7 |
| P3 | CREATED → PENDING_PAYMENT → CANCELLED | 8 |
| P4 | CREATED → PENDING_PAYMENT → PAID → CANCELLED (pul qaytgani tekshiriladi) | 9 |
| P5 | CREATED → PACKING (naqd) → CANCELLED | 11, 10 |
3. Ruxsat etilmagan o'tishlar (kutilgan natija: rad etiladi, holat o'zgarmaydi, tushunarli xabar):
SHIPPED→CANCELLEDDELIVERED→CANCELLEDCANCELLED→PAIDPENDING_PAYMENT→SHIPPED(bosqichdan sakrash)RETURNED→DELIVEREDDELIVERED→RETURNED11-kuni (guard sharti: chegarani BVA bilan — 10-kun ruxsat, 11-kun rad)
Ruxsat etilmagan o'tishlarni odatda API orqali testlash qulay — UI'da bunday tugma ko'rinmasligi mumkin, lekin server buni baribir tekshirishi shart.
</details>
Topshiriq 06: Pairwise — 54 kombinatsiyadan 9 ta test (🟡) {#t06}
Checkout'ni quyidagi parametrlar bilan testlash kerak:
- Brauzer: Chrome, Safari, Firefox
- Til: uz, ru, en
- To'lov: Uzcard, Humo, Naqd
- Qurilma: Desktop, Mobil
To'liq kombinatsiyalar soni nechta? Har bir juftlik kamida bir marta uchraydigan to'plam tuzing.
<details> <summary>💡 Yechimni ko'rish</summary>
To'liq: 3 × 3 × 3 × 2 = 54 kombinatsiya. Pairwise to'plam — 9 ta test (uchta 3-qiymatli parametr juftligi uchun kamida 3 × 3 = 9 qator kerak):
| # | Brauzer | Til | To'lov | Qurilma |
|---|---|---|---|---|
| 1 | Chrome | uz | Uzcard | Desktop |
| 2 | Chrome | ru | Humo | Mobil |
| 3 | Chrome | en | Naqd | Mobil |
| 4 | Safari | uz | Humo | Desktop |
| 5 | Safari | ru | Naqd | Desktop |
| 6 | Safari | en | Uzcard | Mobil |
| 7 | Firefox | uz | Naqd | Mobil |
| 8 | Firefox | ru | Uzcard | Mobil |
| 9 | Firefox | en | Humo | Desktop |
Bu to'plam L9 ortogonal massiviga asoslangan; barcha juftliklar qamralgani skript bilan tekshirildi (yetishmayotgan juftlik — 0). Amalda bunday jadvalni qo'lda emas, Microsoft PICT kabi vosita bilan yarating va cheklovlarni (masalan, "Safari faqat Apple qurilmalarida") model faylida yozing — QA 6.
</details>
Topshiriq 07: Muddatli to'lov — EP + BVA kombinatsiyasi (🔴) {#t07}
Qoida: muddatli (foizsiz) to'lov — yosh 18–65 (shu jumladan), buyurtma summasi 500 000 – 30 000 000 so'm, muddat 3, 6 yoki 12 oy. Minimal, lekin kuchli test to'plamini tuzing. Nega bitta testda bir nechta noto'g'ri qiymatni birlashtirmaslik kerak?
<details> <summary>💡 Yechimni ko'rish</summary>
| # | Yosh | Summa | Muddat | Kutilgan | Nimani tekshiradi |
|---|---|---|---|---|---|
| 1 | 18 | 500 000 | 3 | Ruxsat | Pastki chegaralar birga |
| 2 | 65 | 30 000 000 | 12 | Ruxsat | Yuqori chegaralar birga |
| 3 | 40 | 15 000 000 | 6 | Ruxsat | O'rta (tipik) qiymatlar |
| 4 | 17 | 1 000 000 | 6 | Rad: yosh | Yosh pastki chegaradan tashqari |
| 5 | 66 | 1 000 000 | 6 | Rad: yosh | Yosh yuqori chegaradan tashqari |
| 6 | 30 | 499 999 | 6 | Rad: summa | Summa pastki chegaradan tashqari |
| 7 | 30 | 30 000 001 | 6 | Rad: summa | Summa yuqori chegaradan tashqari |
| 8 | 30 | 1 000 000 | 9 | Rad: muddat | Ruxsat etilmagan muddat |
Bu yerda 2 qiymatli BVA ishlatildi (17/18, 65/66, 499 999/500 000, 30 000 000/30 000 001). 3 qiymatli BVA har chegaraga yana qo'shni qiymatlarni qo'shadi — masalan, yosh uchun 16, 19, 64 va 67 (QA 5).
"Bir vaqtda bitta noto'g'ri qiymat" qoidasi: agar testda yosh ham, summa ham noto'g'ri bo'lsa va tizim rad etsa — qaysi tekshiruv ishlaganini bilmaysiz; bittasi buzilgan bo'lsa ham test "o'tadi" (defect masking).
Qo'shimcha nozik joylar:
- Yosh tug'ilgan sanadan hisoblanadi: bugun 18 yoshga to'lgan va ertaga 66 ga to'ladigan (bugun hali 65) mijozlar — ikkalasi ham ruxsat;
- "Bugun" qaysi vaqt zonasida? Asia/Tashkent (UTC+5) — server UTC'da ishlasa, tunda chegara siljishi mumkin;
- Summa chegarasi chegirmadan oldingi yoki keyingi summaga qo'llanadimi — talabni aniqlashtiring.
</details>
Topshiriq 08: Exploratory charter va sessiya hisoboti (🟡) {#t08}
DemoBozor checkout'idagi promo-kod maydoni uchun 60 daqiqalik exploratory sessiya rejalang: charter yozing va kamida 10 ta g'oya ro'yxatini tuzing. Sessiya hisoboti qanday ko'rinishda bo'lishi kerak?
<details> <summary>💡 Yechimni ko'rish</summary>
Charter: Promo-kod maydonini checkout'da (Web, Chrome) turli formatdagi va holatdagi kodlar, ikki brauzer tab'i va sekin tarmoq bilan tekshirib, chegirma hisobidagi va qayta ishlatishdagi xatolarni topish.
G'oyalar:
- Kichik harflar:
bahor15(qoida: faqat katta harf — avtomatik o'zgartiriladimi yoki rad etiladimi?); - Boshida/oxirida probel:
" BAHOR15 "; - Uzunlik chegaralari: 5, 6, 12, 13 belgi;
- Kirill harflari lotinga o'xshash:
ВАНОR15(В, А, Н, О — kirill) — ko'zga bir xil, lekin boshqa kod; eng "makkor" holatlardan biri; - Muddati o'tgan kodlar (
QISH10,KUZ10) va kelajakda boshlanadigan kod; BAHOR15ning minimal summasi chegarasida (200 000) va undan 1 so'm kam (199 999);- Promo-kod + yangi mijoz chegirmasi birga:
TEJA5(5%) bilan yangi mijozning 10% i qo'llanishi kerak; - Kod qo'llangandan keyin mahsulot o'chirilib, summa minimaldan tushsa — chegirma olib tashlanadimi?;
- Ikki tab'da bir vaqtda bitta kodni ishlatish (race condition);
- Sekin tarmoqda "Qo'llash" tugmasini ikki marta bosish;
- Kod qo'llanib, sahifa yangilansa yoki "orqaga" qaytilsa;
- Bir marta ishlatilgan kodni boshqa buyurtmada qayta ishlatish.
Sessiya hisoboti tuzilmasi (session-based test management uslubida):
| Bo'lim | Mazmuni |
|---|---|
| Charter | Yuqoridagi matn |
| Tester, sana, vaqt | Ism, sana, 60 daqiqa (sozlashga ~10, testlashga ~45, hisobotga ~5) |
| Muhit | Staging, build raqami, brauzer |
| Test eslatmalari | Nima qilindi, nima kuzatildi |
| Bug'lar | Topilgan bug'lar ticket raqamlari bilan |
| Savollar / muammolar | Talabdagi noaniqliklar, bloklovchi muammolar |
| Qamrov | Yuqoridagi g'oyalardan qaysilari tekshirildi, qaysilari keyingi sessiyaga |
</details>
5. Hujjatlar va bug'lar: 9–13 {#hujjatlar}
Topshiriq 09: OTP login uchun 5 ta test case (🟢) {#t09}
DemoBozor mobil ilovasida telefon raqami va SMS kod bilan kirish uchun 5 ta test case yozing (ID, sarlavha, oldingi shartlar, qadamlar, test ma'lumotlari, kutilgan natija, ustuvorlik).
<details> <summary>💡 Yechimni ko'rish</summary>
| ID | Sarlavha | Oldingi shartlar | Qadamlar | Kutilgan natija | Ustuvorlik |
|---|---|---|---|---|---|
| TC-AUTH-001 | To'g'ri SMS kod bilan kirish | Test akkaunt +998 90 000 00 01, SMS keladi | 1) Raqamni kiriting 2) "Kod olish" 3) SMS'dagi 6 raqamni 120 s ichida kiriting | Bosh sahifa ochiladi, foydalanuvchi nomi ko'rinadi | P0 |
| TC-AUTH-002 | Noto'g'ri kod xato xabarini chiqaradi | TC-001 dagi kabi | 1–2) Kod oling 3) 000000 kiriting | "Kod noto'g'ri" xabari; qolgan urinishlar: 2; kirish yo'q | P0 |
| TC-AUTH-003 | Muddati o'tgan kod qabul qilinmaydi | Kod olingan | 1) 121 soniya kuting 2) To'g'ri kodni kiriting | "Kod muddati tugagan", "Qayta yuborish" taklifi; kirish yo'q | P1 |
| TC-AUTH-004 | 3 ta noto'g'ri urinishdan keyin raqam 15 daqiqaga bloklanadi | Kod olingan | 1) 3 marta noto'g'ri kod 2) To'g'ri kodni kiriting 3) 15 daqiqadan keyin qayta urining | 2-qadamda "15 daqiqaga bloklangan"; 3-qadamda yangi kod olish mumkin | P0 |
| TC-AUTH-005 | "Qayta yuborish" 60 soniyadan keyin faollashadi | Kod olingan | 1) Taymerni kuzating 2) 59-soniyada va 60-soniyadan keyin tugmani tekshiring | 59 s da tugma faol emas; 60 s dan keyin faol; yangi kod eskisini bekor qiladi | P1 |
Test ma'lumotlari va muhit (staging, test raqamlari) test case'ning o'zida yoki test suite darajasida ko'rsatiladi. TC-005'dagi "yangi kod eskisini bekor qiladi" — talabda yo'q bo'lsa, PO'dan tasdiqlatiladigan taxmin.
</details>
Topshiriq 10: Yomon test case'ni tuzatish (🟢) {#t10}
Quyidagi test case'ning kamchiliklarini toping va uni qayta yozing:
TC1: Login'ni tekshirish
Qadamlar: Ilovaga kiring va hamma narsani tekshiring.
Kutilgan natija: Hammasi ishlaydi.
<details> <summary>💡 Yechimni ko'rish</summary>
Kamchiliklar: sarlavha nimani tekshirishini aytmaydi; bitta case'da "hamma narsa" (atomar emas); oldingi shartlar va test ma'lumotlari yo'q; qadamlar takrorlanmaydi; kutilgan natija o'lchab bo'lmaydigan ("ishlaydi"); talabga bog'lanmagan; ustuvorlik yo'q.
Qayta yozilgani (bir nechta case'ga bo'linadi; bittasi namuna):
| Maydon | Qiymat |
|---|---|
| ID | TC-AUTH-006 |
| Sarlavha | 9 raqamdan kam telefon raqami bilan SMS kod so'rab bo'lmaydi |
| Talab | REQ-AUTH-01 (telefon: +998 + 9 raqam) |
| Oldingi shartlar | Ilova o'rnatilgan, foydalanuvchi tizimdan chiqqan |
| Test ma'lumoti | +998 90 123 45 6 (8 raqam) |
| Qadamlar | 1) Kirish ekranini oching 2) Raqamni kiriting 3) "Kod olish" tugmasini bosing |
| Kutilgan natija | Tugma faol emas yoki "Raqamni to'liq kiriting" xabari; SMS yuborilmaydi; API'ga so'rov ketmaydi |
| Ustuvorlik / tur | P1 / Negative, funksional |
</details>
Topshiriq 11: Toolshop'dagi real bug uchun bug report (🟡) {#t11}
https://with-bugs.practicesoftwaretesting.com ni oching. Saralash ro'yxatidan "Price (High - Low)" ni tanlang va natijani kuzating. Bu xatti-harakat uchun to'liq bug report yozing.
<details> <summary>💡 Yechimni ko'rish</summary>
Biz 2026-yil oktabrda kuzatgan natija: saralashdan keyin narxlar o'sish tartibida chiqdi ($4.92, $9.17, $11.14, $11.48, ...). Normal v5 build'da xuddi shu variant narxlarni kamayish tartibida ko'rsatadi ($89.55, $86.71, $80.19, ...).
ID: BUG-003
Sarlavha: [Katalog] "Price (High - Low)" saralash mahsulotlarni narx o'sishi bo'yicha ko'rsatadi
Muhit: https://with-bugs.practicesoftwaretesting.com (Toolshop v5.0 with bugs)
Chrome for Testing 156 (Playwright 1.64), macOS; mehmon foydalanuvchi
Oldingi shartlar: yo'q
Qayta hosil qilish qadamlari:
1. Bosh sahifani oching.
2. "Sort" ro'yxatidan "Price (High - Low)" ni tanlang.
3. Birinchi qatordagi mahsulot narxlarini kuzating.
Kutilgan natija: mahsulotlar narx kamayishi bo'yicha (eng qimmati birinchi).
Haqiqiy natija: mahsulotlar narx o'sishi bo'yicha ($4.92, $9.17, $11.14, $11.48, ...).
Takrorlanishi: 3/3
Severity: Major (funksiya teskari ishlaydi; workaround: "Low - High" ni tanlash)
Priority: P2
Komponent: Catalog / Sorting
Ilovalar: skrinshot (sort-high-low.png)
Qo'shimcha ma'lumot: DevTools'da "Price (High - Low)" option'ining qiymati "price,asc".
Label va qiymat almashib qolgan bo'lishi mumkin. Boshqa variantlar ("Name (A - Z)" — qiymati
"name,desc") alohida tekshirilib, alohida report qilinadi.
Nega bunday yozildi: sarlavha qayerda + nima formulasida (QA 8); bitta report — bitta bug; haqiqiy natijada aniq qiymatlar; ildiz sababi haqida taxmin "Qo'shimcha" bo'limida, faktlardan ajratilgan. Bu build'da boshqa bug'lar ham bor — ularni capstone uchun o'zingiz topasiz.
</details>
Topshiriq 12: 8 ta bug — severity va priority (🟡) {#t12}
Har bir DemoBozor bug'iga severity (Blocker/Critical/Major/Minor/Trivial) va priority (P0–P3) bering, qisqa asoslang:
- Android 14'da "To'lash" tugmasi bosilganda ilova yopilib qoladi (barcha foydalanuvchilar).
- Bosh sahifadagi logotip ostida "DemoBozr" deb yozilgan.
- Admin panelidagi oylik PDF hisobot eksporti crash bo'ladi (oyiga 2 marta ishlatiladi, CSV eksport ishlaydi).
- Aynan 300 000 so'mlik buyurtmaga yetkazish haqi olinadi.
- Sharh matni 1000 belgidan uzun bo'lsa server 500 qaytaradi (UI 1000 dan ortiq yozdirmaydi, faqat API orqali mumkin).
- Dark mode'da "Savatcha" tugmasi kontrasti juda past.
- Bitta promo-kodni ikki tab'da bir vaqtda ikki marta ishlatish mumkin.
- Rus tilida savatcha sahifasi sarlavhasi "Cart" bo'lib qolgan.
<details> <summary>💡 Yechimni ko'rish</summary>
| # | Severity | Priority | Asos |
|---|---|---|---|
| 1 | Blocker | P0 | Asosiy biznes oqimi barcha Android 14 foydalanuvchilari uchun to'xtagan |
| 2 | Trivial | P1 | Texnik ta'sir yo'q, lekin brend obro'si — har kim ko'radi |
| 3 | Major | P3 | Funksiya buziladi, lekin kam ishlatiladi va workaround (CSV) bor |
| 4 | Major | P1 | Pul bilan bog'liq, ko'p buyurtmaga ta'sir qiladi (QA 8dagi DB-210) |
| 5 | Minor | P2 | Server validatsiyasi yo'q (500 o'rniga 400/422 kerak); oddiy foydalanuvchiga ta'siri yo'q, lekin API sifati va xavfsizlik nuqtai nazaridan tuzatilishi kerak |
| 6 | Minor | P2 | A11y muammosi; ba'zi foydalanuvchilar uchun ishlatish qiyin (QA 25) |
| 7 | Critical | P0–P1 | To'g'ridan-to'g'ri pul yo'qotish va suiiste'mol imkoniyati |
| 8 | Minor | P2–P3 | Lokalizatsiya xatosi, funksiya ishlaydi |
±1 daraja farq normal — muhimi asoslash. Esda tuting: severity — texnik ta'sir, priority — biznes shoshilinchligi; ularni triage'da PO bilan birga yakunlaysiz.
</details>
Topshiriq 13: Mini RTM va qamrov (🟡) {#t13}
Talablar va test case'lar:
- REQ-01: SMS kod 6 raqam, 120 soniya amal qiladi → TC-AUTH-001, TC-AUTH-003
- REQ-02: 300 000 so'mdan yetkazish bepul → TC-DLV-001, TC-DLV-002
- REQ-03: Promo-kod har foydalanuvchiga bir marta → TC-PRM-004
- REQ-04: Savatchada soni 1–99 → TC-CRT-001 ... TC-CRT-006
- REQ-05: Sharhni faqat DELIVERED buyurtma egasi yozadi → (yo'q)
Oxirgi run: TC-DLV-002 — Failed (BUG-012), TC-PRM-004 — Blocked (staging'da promo-kodlar yo'q), qolganlari — Passed. RTM tuzing, talablar qamrovini hisoblang va xulosa yozing.
<details> <summary>💡 Yechimni ko'rish</summary>
| Talab | Test case'lar | Natija | Bug'lar | Holat |
|---|---|---|---|---|
| REQ-01 | TC-AUTH-001, TC-AUTH-003 | Passed, Passed | — | ✅ Qamralgan, o'tdi |
| REQ-02 | TC-DLV-001, TC-DLV-002 | Passed, Failed | BUG-012 | ❌ Qamralgan, bug bor |
| REQ-03 | TC-PRM-004 | Blocked | — | ⚠️ Qamralgan, bajarilmagan |
| REQ-04 | TC-CRT-001 ... 006 | Passed | — | ✅ Qamralgan, o'tdi |
| REQ-05 | — | — | — | ❌ Qamrov yo'q |
- Talablar qamrovi (kamida 1 testi bor): 4 / 5 = 80%;
- To'liq tasdiqlangan talablar: 2 / 5 (REQ-01, REQ-04).
Xulosa va harakatlar: REQ-05 uchun test case'lar yozish (DELIVERED egasi — ruxsat; boshqa holatdagi buyurtma egasi va begona foydalanuvchi — rad, API orqali ham); REQ-03 uchun staging'ga test promo-kodlari qo'shilishi kerak (bloklovchi muammoni DevOps/PO'ga ko'tarish); BUG-012 tuzatilgach TC-DLV-002 ni qayta testlash va regressiya.
</details>
6. Web, API va SQL: 14–19 {#web-api-sql}
Topshiriq 14: DevTools — bug kimniki? (🟢) {#t14}
Har bir holat uchun bug front-end'dami yoki back-end'dami aniqlang va bug report'ga nimani biriktirishni ayting:
- Katalog bo'sh ko'rinadi. Network:
GET /api/v1/products→200, javobda 24 ta mahsulot. Console'daTypeError: Cannot read properties of undefined (reading 'map'). - "Buyurtma berish" bosilganda xato oynasi. Network:
POST /api/v1/orders→500, javobda stack trace va SQL so'rovi ko'rinadi. - Narx API'da
250000, UI'da "25 000 so'm". - "Saqlash" tugmasi bosilganda hech narsa bo'lmaydi; Network'da so'rov yo'q; Console toza.
<details> <summary>💡 Yechimni ko'rish</summary>
| # | Kimniki | Asos | Biriktiriladi |
|---|---|---|---|
| 1 | Front-end | API to'g'ri ma'lumot qaytargan, JS xatosi render'ni buzgan | Console xatosi (stack bilan), javob JSON'i |
| 2 | Back-end (+ xavfsizlik) | Server xatosi; stack trace va SQL'ning javobga chiqishi — alohida xavfsizlik bug'i (QA 24) | So'rov body'si, javob, vaqt, request id |
| 3 | Front-end | Ma'lumot to'g'ri, formatlashda xato (bir nol yo'qolgan) | Javob qiymati va UI skrinshoti yonma-yon |
| 4 | Front-end (ehtimol) | So'rov umuman ketmagan: event handler ulanmagan yoki validatsiya jim to'xtatgan | Video, qadamlar, Network bo'sh ekani |
4-holatda jim ishlamaslik — UX bug'i ham: foydalanuvchi hech qanday xabar ko'rmaydi.
</details>
Topshiriq 15: curl bilan booking yaratish va o'qish (🟢) {#t15}
restful-booker'da curl bilan yangi booking yarating, uni ID bo'yicha o'qing va status kodlarini ko'rsating.
<details> <summary>💡 Yechimni ko'rish</summary>
# 1) Booking yaratish
curl -s -w "\nHTTP %{http_code}\n" -X POST https://restful-booker.herokuapp.com/booking \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"firstname":"Aziz","lastname":"Karimov","totalprice":250,"depositpaid":true,"bookingdates":{"checkin":"2026-11-01","checkout":"2026-11-05"},"additionalneeds":"Breakfast"}'
# 2) Javobdagi bookingid ni qo'yib o'qish (masalan, 2142)
curl -s -w "\nHTTP %{http_code}\n" https://restful-booker.herokuapp.com/booking/2142 \
-H "Accept: application/json"
2026-yil oktabrdagi haqiqiy javob (ID har safar boshqacha):
{
"bookingid": 2142,
"booking": {
"firstname": "Aziz",
"lastname": "Karimov",
"totalprice": 250,
"depositpaid": true,
"bookingdates": { "checkin": "2026-11-01", "checkout": "2026-11-05" },
"additionalneeds": "Breakfast"
}
}
E'tibor bering: yaratish **200 OK** qaytaradi. REST konvensiyasida yangi resurs uchun odatda 201 Created kutiladi — bu farqni ham kuzatuv sifatida qayd qiling. GET esa 200 va booking obyektini qaytaradi.
</details>
Topshiriq 16: API negative va authZ testlari (🟡) {#t16}
restful-booker uchun kamida 6 ta negative/avtorizatsiya testini rejalashtiring, har biri uchun REST nuqtai nazaridan kutilgan natijani yozing. Keyin ularni curl bilan bajarib, haqiqiy natijani solishtiring. DemoBozor'da IDOR (BOLA) testini qanday qilgan bo'lardingiz?
<details> <summary>💡 Yechimni ko'rish</summary>
2026-yil 9-oktabrda bajarilgan natijalar:
| # | So'rov | Kutilgan (REST) | Haqiqiy | Xulosa |
|---|---|---|---|---|
| 1 | PUT /booking/{id} token'siz | 401 yoki 403 | 403 | ✅ Himoyalangan |
| 2 | DELETE /booking/{id} noto'g'ri token (token=abc123) | 401 yoki 403 | 403 | ✅ Himoyalangan |
| 3 | POST /booking faqat firstname bilan | 400 + xato tavsifi | 500 Internal Server Error | 🐞 Validatsiya yo'q |
| 4 | POST /booking: totalprice=-5, checkout < checkin | 400 yoki 422 | 200, booking saqlandi | 🐞 Biznes validatsiya yo'q |
| 5 | POST /auth noto'g'ri parol bilan | 401 | 200 va {"reason":"Bad credentials"} | 🐞 Noto'g'ri status kod |
| 6 | DELETE /booking/{id} to'g'ri token bilan | 200 yoki 204 | 201 Created | 🐞 Noto'g'ri status (ma'lum "quirk") |
| 7 | O'chirilgan booking'ni GET | 404 | 404 | ✅ |
| 8 | O'chirilgan booking'ni yana DELETE (token bilan) | 404 | 405 Method Not Allowed | 🐞 Noto'g'ri status kod |
Negative so'rov namunasi (3-qator):
curl -s -w "\nHTTP %{http_code}\n" -X POST https://restful-booker.herokuapp.com/booking \
-H "Content-Type: application/json" -H "Accept: application/json" \
-d '{"firstname":"Aziz"}'
IDOR / BOLA — restful-booker'da bitta admin bor, shuning uchun "begona resurs" testini qilib bo'lmaydi. DemoBozor'da (xayoliy API) ikkita xaridor akkaunti kerak:
- A foydalanuvchi o'z buyurtmasini oladi:
GET /api/v1/orders/1001(A token) →200; - A foydalanuvchi B'ning buyurtmasini so'raydi:
GET /api/v1/orders/1002(A token) → **403yoki404** kutiladi;200va B'ning ma'lumoti — kritik xavfsizlik bug'i; - Xuddi shuni
POST /api/v1/orders/1002/canceluchun ham — o'qish himoyalangan, lekin o'zgartirish himoyalanmagan holatlar uchraydi.
Batafsil: QA 11, QA 24. Faqat o'z test muhitingizda!
</details>
Topshiriq 17: Postman — token chaining (🟡) {#t17}
Postman kolleksiyasi yarating: (1) POST /auth → token'ni o'zgaruvchiga saqlash; (2) POST /booking → bookingIdni saqlash; (3) token bilan DELETE; (4) o'chirilgan booking GET → 404. Har so'rovga Post-response testlari yozing va kolleksiyani Newman bilan ishga tushiring.
<details> <summary>💡 Yechimni ko'rish</summary>
Kolleksiya o'zgaruvchilari: baseUrl = https://restful-booker.herokuapp.com, token, bookingId.
1. Auth — Post-response (Tests) skripti:
pm.test("Status 200", () => pm.response.to.have.status(200));
const body = pm.response.json();
pm.test("Token bor va bo'sh emas", () => {
pm.expect(body.token).to.be.a("string").and.not.empty;
});
pm.collectionVariables.set("token", body.token);
2. Booking yaratish (POST {{baseUrl}}/booking, Accept: application/json):
pm.test("Status 200", () => pm.response.to.have.status(200));
const body = pm.response.json();
pm.test("bookingid son", () => pm.expect(body.bookingid).to.be.a("number"));
pm.test("Ism saqlangan", () =>
pm.expect(body.booking.firstname).to.eql("Aziz"),
);
pm.test("Javob 2 soniyadan tez", () =>
pm.expect(pm.response.responseTime).to.be.below(2000),
);
pm.collectionVariables.set("bookingId", body.bookingid);
3. O'chirish (DELETE {{baseUrl}}/booking/{{bookingId}}, header Cookie: token={{token}}):
pm.test("Status 201 (restful-booker quirk)", () =>
pm.response.to.have.status(201),
);
4. Tekshirish (GET {{baseUrl}}/booking/{{bookingId}}):
pm.test("Status 404", () => pm.response.to.have.status(404));
Ishga tushirish (kolleksiyani eksport qilib):
npx newman run booker.postman_collection.json
Biz Newman 6.2.3 bilan ishga tushirdik: 4 ta so'rov, 8 ta assertion, 0 ta xato. Eslatma: Postman'ning Free tarifi 2026-yil martidan bitta foydalanuvchiga cheklangan — jamoaviy ish uchun Bruno yoki Hoppscotch'da xuddi shu mantiqni qurish mumkin (QA 10).
</details>
Topshiriq 18: SQL — buyurtmalar yaxlitligi (🟡) {#t18}
Quyidagi DemoBozor ma'lumotlarini SQLite'ga yuklang (sqlite3 capstone.db < capstone_seed.sql) va to'rtta so'rov yozing:
- (a)
subtotalbuyurtma qatorlari yig'indisiga (quantity × unit_price) teng bo'lmagan buyurtmalar; - (b)
total ≠ subtotal − discount + delivery_feebo'lgan buyurtmalar; - (c) yetkazish qoidasi buzilgan buyurtmalar (≥ 300 000 bo'lsa ham haq olingan yoki < 300 000 bo'lsa ham premium bo'lmagan mijozdan olinmagan);
- (d) mavjud bo'lmagan buyurtmaga bog'langan "yetim"
order_items.
-- capstone_seed.sql
CREATE TABLE users (
id INTEGER PRIMARY KEY,
phone TEXT UNIQUE NOT NULL,
full_name TEXT NOT NULL,
role TEXT CHECK (role IN ('buyer','seller','admin')) DEFAULT 'buyer',
is_premium INTEGER DEFAULT 0,
created_at TEXT
);
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
category TEXT,
price INTEGER NOT NULL,
stock INTEGER NOT NULL,
seller_id INTEGER REFERENCES users(id)
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
status TEXT CHECK (status IN ('CREATED','PENDING_PAYMENT','PAID','PACKING','SHIPPED','DELIVERED','CANCELLED','RETURNED')),
payment_method TEXT CHECK (payment_method IN ('UZCARD','HUMO','VISA','MASTERCARD','CASH')),
promo_code TEXT,
subtotal INTEGER,
discount INTEGER,
delivery_fee INTEGER,
total INTEGER,
created_at TEXT
);
CREATE TABLE order_items (
id INTEGER PRIMARY KEY,
order_id INTEGER REFERENCES orders(id),
product_id INTEGER REFERENCES products(id),
quantity INTEGER CHECK (quantity BETWEEN 1 AND 99),
unit_price INTEGER
);
CREATE TABLE payments (
id INTEGER PRIMARY KEY,
order_id INTEGER REFERENCES orders(id),
amount INTEGER,
status TEXT CHECK (status IN ('SUCCESS','FAILED','REFUNDED')),
provider TEXT,
created_at TEXT
);
INSERT INTO users VALUES
(1, '+998900000001', 'Aziz Karimov', 'buyer', 0, '2026-08-01 10:00:00'),
(2, '+998900000002', 'Malika Rasulova', 'buyer', 1, '2026-08-03 12:30:00'),
(3, '+998900000003', 'Jasur Toshmatov', 'seller', 0, '2026-07-15 09:00:00'),
(4, '+998900000004', 'Dilnoza Yusupova', 'buyer', 0, '2026-08-20 18:45:00'),
(5, '+998900000005', 'Admin', 'admin', 0, '2026-07-01 08:00:00');
INSERT INTO products VALUES
(1, 'Elektr choynak', 'Maishiy texnika', 250000, 40, 3),
(2, 'Paxta ko''ylak', 'Kiyim', 120000, 100, 3),
(3, 'Simsiz quloqchin', 'Elektronika', 450000, 25, 3),
(4, 'Gilam (2x3 m)', 'Uy', 1800000, 5, 3),
(5, 'Telefon g''ilofi', 'Aksessuar', 45000, 200, 3);
INSERT INTO orders VALUES
(101, 1, 'DELIVERED', 'UZCARD', NULL, 295000, 29500, 20000, 285500, '2026-09-01 11:00:00'),
(102, 2, 'DELIVERED', 'VISA', NULL, 450000, 0, 0, 450000, '2026-09-02 15:20:00'),
(103, 4, 'PAID', 'HUMO', NULL, 240000, 0, 20000, 260000, '2026-09-05 09:10:00'),
(104, 1, 'SHIPPED', 'UZCARD', 'BAHOR15', 1890000, 283500, 0, 1606500, '2026-09-07 19:00:00'),
(105, 2, 'DELIVERED', 'MASTERCARD', NULL, 340000, 0, 0, 340000, '2026-09-08 13:40:00'),
(106, 4, 'CANCELLED', 'VISA', NULL, 250000, 0, 20000, 270000, '2026-09-10 10:05:00'),
(107, 1, 'CREATED', 'CASH', NULL, 450000, 0, 0, 405000, '2026-09-12 21:15:00'),
(108, 4, 'DELIVERED', 'UZCARD', NULL, 700000, 0, 20000, 720000, '2026-09-14 08:30:00'),
(109, 1, 'DELIVERED', 'HUMO', NULL, 90000, 0, 20000, 110000, '2026-09-15 17:50:00');
INSERT INTO order_items VALUES
(1, 101, 1, 1, 250000),
(2, 101, 5, 1, 45000),
(3, 102, 3, 1, 450000),
(4, 103, 2, 2, 120000),
(5, 104, 4, 1, 1800000),
(6, 104, 5, 2, 45000),