1. Ümumiyyətlə ChatGPT App‑də nəyi test edirik (və nəyi etmirik)
Klassik veb tətbiqində hər şey aydındır: UI → backend → məlumat bazası. Funksiyalar üçün unit‑testlər yazırıq, API üçün inteqrasiya testləri, E2E — “istifadəçi axını keçib”.
ChatGPT App‑də mənzərə bir az daha mürəkkəbdir:
İstifadəçi ↔ ChatGPT UI ↔ Vidcet (Apps SDK, React)
↘
MCP serveri (tools/resources)
↘
ACP / backend / xarici API‑lər
ChatGPT daxilindəki model sizin suggest_gifts‑i nə vaxt çağıracağını, hansı arqumentlərlə, MCP‑dən gələn structuredContent‑i necə render edəcəyini və vidcetinizi nə vaxt göstərəcəyini özü qərar verir.
Test baxımından dünyanı iki layaya bölmək rahatdır:
- Infrastructure tests — bu mühazirədə məşğul olacağımız hissə. Biz aşağıdakıları yoxlayırıq:
- istifadəçi klik etdikdə vidcet kodu sınmır;
- MCP‑tools sxemlərdə vəd olunan formatda məlumat qəbul edir və qaytarır;
- ACP endpoint‑ləri və webhook‑lar işləkdir və tipik JSON‑da yıxılmır.
- AI behavior evals — bu, 20‑ci modulda olacaq. Orada artıq modelin nə cavab verdiyinə baxacağıq: adekvat izah edirmi, mənaca düzgün hədiyyə seçirmi, halyusinasiya etmir mi.
Bugünkü sadə düstur:
“LLM‑in ətrafındakı hər şeyi test edirik, amma LLM‑in özünü yox”.
Məhz buna görə kurs planında bu mövzu ayrıca vurğulanır: “Biz GPT cavabını sözbəsöz test etmirik, biz onun ətrafındakı infrastrukturu və məlumat kontraktlarını test edirik”.
Çətinlikdə boğulmamaq üçün GiftGenius üçün sadə bir “piramida”dan istifadə edirik.
graph TD A["Unit testlər<br/>utils, tools biznes məntiqi"] --> B[Contract testlər<br/>Zod/JSON Schema, webhook‑lar] B --> C[E2E / UI testlər<br/>ChatGPT olmadan vidcet + MCP] C --> D["CI‑də smoke<br/>“ümumiyyətlə işləyir?”"] style A fill:#e0f7fa,stroke:#00838f,stroke-width:1px style B fill:#e8f5e9,stroke:#2e7d32,stroke-width:1px style C fill:#fff3e0,stroke:#ef6c00,stroke-width:1px style D fill:#ffebee,stroke:#c62828,stroke-width:1px
İndi hər səviyyədən keçəcəyik və eyni zamanda tədris GiftGenius‑umuza testlər əlavə edəcəyik. Sonda isə ChatGPT App testləşdirməsində ən çox rast gəlinən tipik səhvlər üçün yoxlama siyahısı toplayacağıq.
2. Unit‑testlər: GiftGenius‑u kiçik hissələrə bölmək
ChatGPT App‑də unit nə sayılır
Bizim stekdə unit‑test — kiçik və izolyasiya olunmuş məntiq hissəsinin yoxlanmasıdır. Real şəbəkə olmadan, baza olmadan və imkan düşdükcə MCP framework‑ünü çağırmadan.
GiftGenius üçün bu, belə şeylər ola bilər:
- “hədiyyənin uyğunluğunu” hesablayan funksiya;
- qiyməti olmayan və ya uyğun valyutası olmayan məhsulları çıxaran filtr;
- valyuta çeviricisi;
- “xam” məhsul obyektindən UI üçün GiftCardProps‑a map edən funksiya.
Ümumiyyətlə, MCP‑tools daxilindəki məntiqi də parçalamağa dəyər: MCP marşrut handler‑i — təmiz biznes məntiqi funksiyasını çağıran nazik bir “örtükdür”. Unit‑testlərdə məhz həmin təmiz funksiyanı test edirik.
Nümunə: hədiyyələrin reytinq funksiyası
Tutaq ki, bizdə qiymət diapazonu və populyarlığa əsasən “bal” verən scoreGift adlı util var:
// src/lib/scoreGift.ts
export type Gift = {
id: string;
price: number;
popularity: number; // 0..1
};
export function scoreGift(gift: Gift, maxPrice: number): number {
if (gift.price > maxPrice) return 0;
const priceScore = 1 - gift.price / maxPrice;
return Math.round((priceScore * 0.6 + gift.popularity * 0.4) * 100);
}
Jest üçün unit‑test yazırıq (Vitest demək olar eyni olacaq):
// src/lib/scoreGift.test.ts
import { scoreGift } from './scoreGift';
test('scoreGift bahalı hədiyyələrin balını aşağı salır', () => {
const cheap = { id: 'c', price: 50, popularity: 0.5 };
const expensive = { id: 'e', price: 100, popularity: 0.5 };
const max = 100;
const cheapScore = scoreGift(cheap, max);
const expensiveScore = scoreGift(expensive, max);
expect(cheapScore).toBeGreaterThan(expensiveScore);
});
Burada əsas “Arrange–Act–Assert” görünür (məlumatı hazırladıq, funksiyanı çağırdıq, nəticəni yoxladıq) — daha mürəkkəb testlərdə də məhz bu strukturlaşdırmanı istifadə etməyi tövsiyə edirlər.
Biznes məntiqini MCP handler‑indən çıxarmaq
Hazırda yəqin ki, təxminən belə bir şeyiniz var:
// app/mcp/route.ts — xeyli sadələşdirilmiş
import { createMcpServer } from '@modelcontextprotocol/sdk';
import { scoreGift } from '@/lib/scoreGift';
server.tool('suggest_gifts', {
// ...
handler: async ({ input }) => {
const gifts = await fetchFromCatalog(input);
const scored = gifts
.map(g => ({ ...g, score: scoreGift(g, input.maxPrice) }))
.sort((a, b) => b.score - a.score);
return { gifts: scored.slice(0, 10) };
},
});
scoreGift üçün unit‑testi artıq yazmışıq, amma bütöv funksiyanı da test etmək istəyirik: “hədiyyələr siyahısını götürüb sıralanmış top‑10 qaytaran funksiya”. Onu ayrıca modulə çıxaraq:
// src/lib/rankGifts.ts
import { scoreGift, Gift } from './scoreGift';
export function rankGifts(gifts: Gift[], maxPrice: number) {
return gifts
.map(g => ({ ...g, score: scoreGift(g, maxPrice) }))
.sort((a, b) => b.score - a.score)
.slice(0, 10);
}
Və test:
// src/lib/rankGifts.test.ts
import { rankGifts } from './rankGifts';
test('rankGifts maksimum 10 hədiyyəni score‑a görə azalan qaydada qaytarır', () => {
const gifts = Array.from({ length: 20 }, (_, i) => ({
id: `g${i}`,
price: 10 + i,
popularity: 0.5,
}));
const result = rankGifts(gifts, 100);
expect(result).toHaveLength(10);
expect(result[0].score).toBeGreaterThanOrEqual(result[9].score);
});
Belə unit‑testlər sürətlidir, ucuzdur və operativ rəy verir — məhz buna görə MCP xidmətləri üçün “test piramidasının geniş bazası” kimi tövsiyə olunurlar.
MCP alətləri üçün unit‑testlər: xarici API‑ləri mock etmək
Tez‑tez edilən səhv — MCP tool handler‑ini kataloqa, Stripe‑a və s. real HTTP sorğuları ilə birlikdə “unit‑test” etməyə çalışmaqdır. Nəticədə test yavaşıyır və kövrək olur.
Ən yaxşı variant: handler‑də yalnız “skleyka” (wiring) qalsın, bütün mürəkkəb məntiq isə artıq ayrıca test etdiyimiz funksiyalara daşınsın. Əgər mütləq handler‑in özünü test etmək istəyirsinizsə, asılılıqları mock edin. Məhz bunu MCP testləşdirməsinin ətraflı icmallarında da tövsiyə edirlər: tool‑handler‑lərdə xarici API‑ləri mock etmək.
3. Contract‑testlər: Zod/JSON Schema model və ACP ilə “müqavilə” kimi
Bizim kontekstdə contract‑test nədir
Unit məntiqini nizama saldıq: kiçik təmiz funksiyalar nəzarətimizdədir. Növbəti qat — servislerin hələ də JSON kontraktlarına görə bir‑birini başa düşdüyünə əmin olmaqdır. Bu, məhz contract‑testlərdir.
Kontrakt testləşdirməsi o deməkdir ki, məlumat mübadiləsi aparan iki tərəf hələ də bir‑birini anlayır. Fokus daxili alqoritmlərdə deyil, JSON‑un forması və mənasındadır: sahələr, tiplər, məcburilik.
ChatGPT App‑də belə kontraktlar çoxdur:
- ChatGPT ↔ MCP: MCP‑tools üçün inputSchema və outputSchema.
- MCP ↔ commerce‑API (ACP): create_checkout_session sorğularının formatı, cavabların strukturu.
- ACP ↔ backend‑imiz webhook‑lar üzrə: order.created, payment_failed və s.
Sxemi dəyişirsiniz, amma kodu yeniləməyi unudursunuz (və ya əksinə — kodu dəyişirsiniz, sxemi köhnə saxlayırsınız) — səssiz uyğunsuzluq yaranır. Model köhnə JSON göndərməyə davam edir, sizin kod isə artıq yeni sahə gözləyir — və run‑time‑da yıxılır. Məhz belə situasiyaları contract‑testlər proddan əvvəl tutmalıdır.
Zod — yeganə həqiqət mənbəyi kimi
JavaScript/TypeScript ekosistemində bunun üçün Zod əladır; siz artıq MCP ilə istifadə etmisiniz: SDK alətləri elan etmək üçün Zod sxemlərini JSON Schema‑ya çevirməyi bacarır.
Məsələn, hədiyyə və tövsiyə nəticəsinin sxemini təsvir edək:
// src/schemas/gift.ts
import { z } from 'zod';
export const GiftSchema = z.object({
id: z.string(),
title: z.string(),
price: z.number().nonnegative(),
currency: z.string().length(3),
url: z.string().url(),
});
export const SuggestGiftsResultSchema = z.object({
gifts: z.array(GiftSchema).min(1),
});
Kod üçün tipləri z.infer ilə alırıq:
export type Gift = z.infer<typeof GiftSchema>;
export type SuggestGiftsResult = z.infer<typeof SuggestGiftsResultSchema>;
Bu, artıq bir növ compile‑time contract testdir: əgər haradasa currency: 123 verməyə çalışsanız, TypeScript xəbərdarlıq edəcək və bunun string olmalı olduğunu xatırladacaq.
Sxemlər üçün runtime contract‑testlər
Bizi daha da çox qoruyan — real (və ya reala yaxın) məlumat nümunələrini sxemlərdən keçirən runtime‑testlərdir.
// src/schemas/gift.test.ts
import { GiftSchema, SuggestGiftsResultSchema } from './gift';
test('GiftSchema düzgün məhsulu qəbul edir', () => {
const sample = {
id: '123',
title: 'Pişikli fincan',
price: 19.99,
currency: 'USD',
url: 'https://example.com/gift/123',
};
expect(() => GiftSchema.parse(sample)).not.toThrow();
});
test('SuggestGiftsResultSchema boş hədiyyə siyahısını rədd edir', () => {
const badResult = { gifts: [] };
expect(() => SuggestGiftsResultSchema.parse(badResult)).toThrow();
});
Niyə vacibdir:
- əgər promplarda/dokumentasiyada model üçün JSON nümunələri göstərirsinizsə, onları birbaşa bu testlərə qoyub “nümunə yalan danışmır” zəmanəti ala bilərsiniz;
- əgər sxemi dəyişirsinizsə (məsələn, url sahəsini məcburi edirsiniz), testlər dərhal bütün köhnə nümunələri və fiqsturaları işıqlandıracaq.
Apps SDK üzrə rəsmi tövsiyələr də vurğulayır: structured content elan olunmuş outputSchema‑ya uyğun olmalıdır, əks halda model onu anlaya bilməz. Sxem testləri — uyğunsuzluqların qarşısını alan ilk müdafiə xəttidir.
Webhook və ACP kontraktları
Eyni prinsip webhook‑lar və ACP endpoint‑lərinə də tətbiq olunur. Tutaq ki, bizdə OrderCreated var:
// src/schemas/acp.ts
import { z } from 'zod';
export const OrderCreatedSchema = z.object({
id: z.string(),
userId: z.string(),
totalAmount: z.number(),
currency: z.string().length(3),
status: z.literal('created'),
});
Test:
// src/schemas/acp.test.ts
import { OrderCreatedSchema } from './acp';
test('OrderCreatedSchema webhook nümunəsini doğrulayır', () => {
const sample = {
id: 'ord_1',
userId: 'user_42',
totalAmount: 59.99,
currency: 'USD',
status: 'created',
};
expect(() => OrderCreatedSchema.parse(sample)).not.toThrow();
});
Sonra webhook handler‑ində ilk işiniz OrderCreatedSchema.parse(body) etməkdir — beləliklə, davamda artıq etibarlı obyektlə işlədiyinizə əmin olursunuz.
OpenAI App‑lar üçün regresiya yoxlama siyahısında tətbiq inkişaf etdikcə sxemləri aktual saxlamağı da tövsiyə edir — contract‑testlər bunun unudulmamasını təmin edir.
4. Vidcetin və “demək olar ki, E2E”‑nin testləşdirilməsi: chatgpt.com olmadan necə
Unit‑testlər məntiqi, contract‑testlər isə servislərarası məlumat formasını qaydada saxlayır. Amma piramida bununla bitmir: istifadəçinin vidcet və MCP üzərindən tam yolu həqiqətən bütöv sistem kimi işləyirmi — bunu da yoxlamalıyıq. ChatGPT App üçün bu xüsusi, “demək olar ki, E2E” format olacaq.
Niyə sadəcə Playwright‑ı ChatGPT‑yə buraxmaq olmaz
İntuisiya belə deyir: “Gəlin https://chatgpt.com açaq, vidceti işə salaq, Playwright ilə bütün ssenarini ‘hədiyyə seç → sifarişi rəsmiləşdir’ keçək — və bizdə əsl E2E olsun”.
Təəssüf ki, yox.
Problemlər:
- chatgpt.com üzərindən avtomatlaşdırılmış qaçış ToS‑u pozur;
- CI‑dan gələn botları sevməyən qoruma (Cloudflare, 2FA və s.) var;
- modelin davranışı dəyişkəndir: bu gün suggest_gifts çağırır, sabah sırf mətn cavabı ilə kifayətlənir.
Buna görə də ChatGPT App üçün E2E‑test daha geniş şərh olunur: öz tətbiqiniz daxilində tam yolu — vidcet + MCP + ACP — test edirik, amma real ChatGPT UI və real modeli istifadə etmirik.
Ətraflı bələdçilər də məhz bu strategiyanı təklif edir: MCP serverini ayrıca headless‑klientlə test etmək, vidceti isə lazımi metodlarla mock olunmuş window.openai ilə “test host” daxilində sınamaq.
Vidceti React komponenti kimi test etmək
Baza variant — React Testing Library. Bizə gərəkdir:
- GiftGeniusWidget komponentini render etmək.
- Ona lazımi metodlarla (callTool, openExternal və s.) saxta window.openai vermək.
- İstifadəçi kimi davranmaq: düymələri klikləmək, mətn daxil etmək.
- callTool‑un düzgün arqumentlərlə çağırıldığını və UI‑nin gözlənilən nəticəni göstərdiyini yoxlamaq.
Tutaq ki, bizdə sadələşdirilmiş vidcet var:
// src/app/GiftGeniusWidget.tsx
'use client';
import React from 'react';
export function GiftGeniusWidget() {
const [loading, setLoading] = React.useState(false);
async function handleClick() {
setLoading(true);
await (window as any).openai.callTool('suggest_gifts', {
occasion: 'birthday',
});
setLoading(false);
}
return (
<div>
<button onClick={handleClick}>Hədiyyə seç</button>
{loading && <p>Bir saniyə, ideyalar toplayıram...</p>}
</div>
);
}
Test:
// src/app/GiftGeniusWidget.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { GiftGeniusWidget } from './GiftGeniusWidget';
test('düymə window.openai.callTool vasitəsilə suggest_gifts çağırır', async () => {
const callToolMock = vi.fn().mockResolvedValue({});
(window as any).openai = { callTool: callToolMock };
render(<GiftGeniusWidget />);
const button = screen.getByText('Hədiyyə seç');
await fireEvent.click(button);
expect(callToolMock).toHaveBeenCalledWith('suggest_gifts', {
occasion: 'birthday',
});
});
Burada mühit tam bizim nəzarətimizdədir:
- heç bir real ChatGPT yoxdur;
- şəbəkə yoxdur;
- təmiz, sürətli test — “UI → window.openai” əlaqəsini yoxlayır.
Apps SDK sənədlərində də məhz bunu tövsiyə edirlər: vidceti test edərkən window.openai‑ni mock edin ki, real mühitdən asılı olmayasınız.
E2E‑light Playwright ilə: Next.js + MCP
Növbəti səviyyə — Next.js tətbiqini lokalda (Dev Mode kimi) qaldırırıq, amma ona ChatGPT üzərindən yox, test brauzerindən birbaşa daxil oluruq.
Mənalı ssenari kimi bunları yoxlamaq olar:
- /widget səhifəsini açmaq (və ya layihənizdə necədirsə, /).
- Minimum addımları imitasiya etmək: hədiyyə tipini seçmək, “İdeyaları göstər” düyməsinə basmaq.
- Vidzecin hədiyyə kartlarını göstərdiyini yoxlamaq.
- (Opsional) kartı klikləmək, “Ödənişə keç” düyməsinə basmaq və ACP mock‑unun uğur qaytardığını təsdiqləmək.
Kiçik Playwright test nümunəsi:
// tests/e2e/gift-flow.spec.ts
import { test, expect } from '@playwright/test';
test('istifadəçi hədiyyə seçə və nəticələri görə bilir', async ({ page }) => {
await page.goto('http://localhost:3000/widget');
await page.click('text=Ad günü üçün hədiyyə');
await page.click('text=Seç');
await page.waitForSelector('[data-testid="gift-card"]');
const cards = await page.locator('[data-testid="gift-card"]').all();
expect(cards.length).toBeGreaterThan(0);
});
Real layihədə bunlar da əlavə olunacaq:
- beforeAll daxilində npm run dev və ya ayrıca test‑serverin qaldırılması;
- prod servislərə toxunmamaq üçün MCP/ACP üçün mock‑lar.
Amma hətta belə sadə ssenari belə vidcetlə MCP arasında tipik “qırılmaları” tutur: səhv URL, CORS xətaları, yalnış structuredContent və s.
5. CI‑də smoke‑testlər: “ümumiyyətlə başlayırmı”nı yoxlayırıq
Piramidanın yuxarı, ən yüngül qatı — smoke‑testlər qaldı. Onlar E2E‑light kimi bütün ssenarini yoxlamır, sadəcə cavab verir: tətbiq ümumiyyətlə canlıdırmı və dep- loydan əvvəl qalxırmı?
Smoke və tam E2E
“Əl ilə” smoke‑test haqqında artıq ikinci modulda eşitmişdiniz: o zaman ən ilk “Hello GiftGenius”‑u işə salmışdıq, vidcetin render olunduğunu, ChatGPT‑nin onu gördüyünü və düymənin linki açdığını yoxlamışdıq. Məqsəd: Dev Mode + tunel + Apps SDK konfiqinin ümumilikdə doğru olduğuna əmin olmaq idi.
İndi tapşırıq oxşardır, amma avtomatlaşdırılmış və CI‑də:
- istifadəçinin bütün ssenarilərini imitasiya etmirik;
- real ChatGPT ilə danışmırıq;
- sadəcə bunları yoxlayırıq:
- Next.js tətbiqi start götürür;
- MCP server ən azı baza tools/list / tools/call‑a cavab verir;
- ACP endpoint canlıdır və test JSON‑una 200 qaytarır.
Bu, xüsusilə production‑a deploydan və ya Store‑a yeni versiya göndərməzdən əvvəl vacibdir: “qalxmadı” kimi problemləri CI‑də tutmaq, istifadəçilərdən eşitməkdən asandır.
MCP alətləri üçün smoke‑test nümunəsi
Tutaq ki, testdə MCP serverini qaldıran və ya SDK‑dakı MCP‑klienti istifadə edən köməkçi modulunuz var. Konseptual test belə görünür:
// tests/smoke/mcp-tools.smoke.test.ts
import { createTestMcpClient } from './testClient';
test('MCP tools.list və tools.call(suggest_gifts) sorğularına cavab verir', async () => {
const client = await createTestMcpClient(); // serveri qaldırır və ya ona qoşulur
const tools = await client.listTools();
expect(tools.some(t => t.name === 'suggest_gifts')).toBe(true);
const result = await client.callTool('suggest_gifts', {
occasion: 'birthday',
budget: { currency: 'USD', max: 50 },
});
expect(result.gifts.length).toBeGreaterThan(0);
});
MCP testləşdirməsinin dərin izahlarında da məhz bu yanaşma tövsiyə olunur: JSON‑RPC‑nin tam dövrəsini yoxlamaq üçün testlərdə MCP‑klientdən istifadə etmək — list → call → cavab.
createTestMcpClient reallaşdırmasını util‑lərdə gizlətmək olar: eyni prosesdə serveri start verir və ya artıq işləyən nümunəyə qoşulur.
ACP/checkout üçün smoke‑test
Oxşar şəkildə commerce qatına ən sadə test yazmaq olar, real ödənişi imitasiya etmədən:
// tests/smoke/acp.smoke.test.ts
import fetch from 'node-fetch';
test('ACP test-intent 200 qaytarır', async () => {
const res = await fetch('http://localhost:3000/api/acp/test-intent', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
amount: 10,
currency: 'USD',
}),
});
expect(res.ok).toBe(true);
});
Burada test-intent‑in nə etdiyinin fərqi yoxdur — o, sadəcə DB‑yə çıxışı yoxlayıb {"status":"ok"} qaytara bilər. Əsas odur ki, CI aşağıdakıları tutsun:
- unudulmuş env açarı;
- sınmış marşrut;
- səhv JSON parsinqi.
Minimal CI pipeline‑ı
CI/CD‑ni ətraflı deployment modullarında danışacağıq, amma baza pipeline belə görünə bilər (GitHub Actions nümunəsində):
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main ]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm test # unit + contract
- run: npm run test:e2e # e2e/ui
- run: npm run test:smoke # smoke mcp/acp
npm run test:e2e və npm run test:smoke komandaları daxilində artıq dev‑serveri qaldırmaq, hazır olmasını gözləmək və Playwright / Node skriptlərini işə salmaq mümkündür.
6. GiftGenius üçün mini test xəritəsi
Azmamaq üçün hər səviyyədə nəyi test etdiyimizi və bunun hansı sualı cavabladığını bir cədvəldə toplayaq.
| Səviyyə | GiftGenius üçün nümunələr | Alətlər | Hansı suala cavab verir |
|---|---|---|---|
| Unit | scoreGift, rankGifts, büdcə validatorları | Jest / Vitest | Məntiq düzgün hesablayır? |
| Contract (schemas) | Zod sxemləri Gift, SuggestGiftsResult, OrderCreated | Zod, AJV | Hələ də GPT/ACP ilə eyni JSON “dilində” danışırıq? |
| UI/Component | Klik zamanı vidcetin davranışı, window.openai.callTool çağırışı | React Testing Library | UI düzgün hərəkətləri çağırır? |
| E2E‑light | İstifadəçi hədiyyə seçmə axınından keçdi və kartları gördü | Playwright/Cypress | GiftGenius‑un bütün hissələri işlək axına yığılır? |
| Smoke CI‑də | MCP tools.list/call‑a cavab verir, ACP test-intent 200 | Node skriptləri, MCP client | Tətbiq ümumiyyətlə işləkdir və əlaqələr qurulub? |
Bu dəst — modul planında deyilən ChatGPT App üçün “minimal işlək test dəsti”dir: Enterprise QA komandası olmadan, amma produn hər xırda dəyişiklikdən yıxılmamasına baza zəmanəti ilə.
7. ChatGPT App testləşdirməsində tipik səhvlər
Səhv №1: modelin cavablarını deterministik şəkildə test etməyə çalışmaq.
Bəzən tərtibatçılar “GPT aşağıdakı sətirlə cavab versin: Budur 5 hədiyyə ideyası” tipində testlər yazmağa çalışırlar. Belə testlər mahiyyətcə kövrəkdir: model eyni ifadəni sözbəsöz təkrarlamağa borclu deyil, üstəlik modelin özü yenilənə bilər. Bu modulda biz ümumiyyətlə mətnin məzmununa toxunmuruq — yalnız alət çağırışlarını, sxemlərin validliyini və axının yıxılmadığını yoxlayırıq. Mətn keyfiyyətinin qiymətləndirilməsi — ayrıca bir fənddir (M20, LLM‑evals).
Səhv №2: MCP sxemləri üçün contract‑testlərin olmaması.
Zod sxemini bir dəfə yazıb onu unutmaq çox cazibədardır. Sonra alət nəticəsinə discount sahəsi əlavə edirsiniz, kodu yeniləyirsiniz, amma sxemi yox. Model köhnə formatı göndərməyə davam edir, sizin kod isə yeni sahə gözləyir — prod‑da qəribə yıxılmalar başlayır. Zod/JSON Schema üzrə kontrakt testləri məhz belə “səssiz” pozuntuların qarşısını alır, ona görə onlardan imtina etmək — məşhur və çox ağrılı bir səhvdir.
Səhv №3: CI‑dən chatgpt.com üzərinə E2E qaçırmağa cəhd etmək.
Bunu yenə də edən olur: real ChatGPT‑yə qarşı Playwright işə salır, login olur, UI‑də klikləyir — nəticədə Cloudflare‑dan ban, qeyri‑stabil testlər və istifadə şərtlərinin mümkün pozulması. Düzgün yol — Apps SDK və MCP bələdçilərinin tövsiyə etdiyi kimi, öz Next.js hostunuzu + MCP‑ni izolyasiyada test etmək, window.openai və xarici API‑ləri mock etməkdir.
Səhv №4: yalnız E2E yazmaq və unit səviyyəsini unutmaq.
Bəzən layihədə yarım tətbiqi klikləyən “nəhəng” bir E2E testi, amma sıfır unit‑test görürsən. Bu yanaşma yalancı təhlükəsizlik hissi yaradır: test ya yaşıl, ya qırmızıdır, amma səbəbi lokallaşdırmaq demək olar ki, mümkün olmur və hər qaçış dəqiqələr çəkir. Çox daha effektiv olan — təmiz funksiyalar üçün onlarla sürətli unit‑testə və kritik yollar üzrə bir neçə səliqəli E2E‑light ssenarisinə sahib olmaqdır.
Səhv №5: adi testlərdə real xarici API‑lərdən istifadə etmək.
Stripe, xarici kataloqlar, CRM — bunlar idarə olunan mühitdə inteqrasiya testləri üçün əladır, amma sıravi npm test üçün yox. Əgər testləriniz şəbəkədən, özgə rate‑limit‑lərdən və kiminsə prod serverindən asılıdırsa, kodunuzla əlaqəsi olmayan səbəblərdən yıxılacaqlar. Ən yaxşı yanaşma — xarici API‑ləri (nock, msw və s.) mock etmək və ayrıca xüsusi mühitdə bir neçə “canlı” yoxlama saxlamaqdır.
Səhv №6: deploydan əvvəl smoke‑testləri unutmaq.
Fīçanı birləşdirdiniz, MCP‑schema‑nı yenilədiniz, UI‑ni düzəltdiniz, “Deploy”a basdınız — və Next.js start götürmür, çünki kimsə next.config‑i sındırıb və ya .env silinib. Avtomatlaşdırılmış smoke‑testlər olmadan CI belə aşkar səhvləri prod‑a buraxır. “Server qalxdı”, “MCP baza çağırışına cavab verir” və “ACP test endpoint‑i 200 verir” kimi bir sadə smoke‑suite döyüşdə saatlarla debugu və əsəbi xilas edir.
Səhv №7: ilkin mərhələdə test konturunu həddindən artıq mürəkkəbləşdirmək.
Bəzən iri şirkətlərin best‑practice‑lərindən ilhamlanıb dərhal onlarla mühit, məlumat generasiyalı mürəkkəb kontrakt testləri, yükləmə ssenariləri və s. qurmaq istəyirsən. Nəticədə komanda həftələrlə infrastrukturla məşğul olur və fīçə buraxmır. ChatGPT App ilə start üçün bizim dediyimiz “Sanity Suite” kifayətdir: unit + contract + bir neçə E2E‑light + CI‑də smoke. Sonra trafik və tələblər artdıqca tədricən təkamül etmək olar.
GO TO FULL VERSION