07 - Ladění pomocí kurzoru AI: 3x rychlejší
Ladění je jednou z časově nejnáročnějších činností v životě vývojáře. Interní studium společnosti Microsoft a Google uvádějí, že vedoucí vývojáři utrácejí 30 až 40 procent jejich produktivní čas při hledání a opravě chyb. S příchodem nativních IDE AI, toto procento se hroutí. Ti, kteří používají Cursor s optimalizovaným workflow, hlásí až snížení 65 procent času stráveného laděním ne proto, že je umělá inteligence neomylná, ale proto, že přeměňuje osamělý a často frustrující proces ve strukturovanou a systematickou spolupráci.
Tento článek vám nejen ukazuje, jak „požádat AI o opravu chyby“. Pojďme prozkoumat specifické funkce Cursoru věnované ladění, od Zaveden režim ladění s kurzorem 2.2 do systému Bugboti pro aktivní kontrolu PR, projít pokročilými strategiemi pro úniky paměti, závodní podmínky a nespolehlivé testy v TypeScriptu a Angular. Naučíte se vytvořit opakovatelný pracovní postup, který transformuje ladění z umění zakrývá ověřitelný inženýrský proces.
Co se dozvíte v tomto článku
- Jak funguje režim ladění Cursor 2.2 a jeho smyčka agenta založená na protokolech běhu
- Bugbot: Proaktivní detekce chyb na žádostech o stažení s automatickou autofixací
- Pracovní postup Cmd+K a inline chat pro okamžitou analýzu trasování zásobníku
- Nakonfigurujte ladicí program TypeScript/Angular se zdrojovými mapami v Cursoru
- AI strategie pro úniky paměti, závodní podmínky a nespolehlivé testy
- Integrace s Chrome DevTools a nativním debuggerem VS Code
- Kompletní cyklus: reprodukovat - izolovat - přístroj - opravit - ověřit
- Porovnání mezi tradičním a AI podporovaným laděním se skutečnými metrikami
Články z Cursor IDE a AI-Native Development Series
| # | Položka | Úroveň |
|---|---|---|
| 1 | Cursor IDE: Kompletní průvodce pro vývojáře | Začátečník |
| 2 | Pravidla kurzoru: Konfigurace AI pro váš projekt | Střední |
| 3 | Režim agenta: Upravte kódovou základnu pomocí příkazu | Střední |
| 4 | Režim plánu a agenti na pozadí | Moderní |
| 5 | Háčky kurzoru: Automatizujte pracovní postup | Střední |
| 6 | MCP a kurzor: Připojte IDE k databázi a API | Moderní |
| 7 | Jste zde – Ladění pomocí kurzorové umělé inteligence: 3x rychlejší | Střední |
| 8 | Cursor vs Windsurf vs Copilot v roce 2026 | Začátečník |
| 9 | Profesionální pracovní postup: Úhlový s kurzorem | Moderní |
Problém s tradičním laděním
Každý, kdo strávil tři hodiny zíráním na stopu zásobníku, aby zjistil, v čem je problém
a undefined na pole s možností null přesně ví, o čem mluvíme. Ladění
tradiční metoda má obrovské kognitivní náklady: musíte si udržet stav programu v hlavě,
vytvářet hypotézy, přidávat protokoly, reprodukovat chybu, interpretovat výsledky a opakovat.
Každé přerušení toku – nový protokol k přidání, bod přerušení k přesunutí –
narušuje koncentraci.
Vývojáři, kteří používají Cursor pro ladění, tento proces neodstraňují, ale urychlují radikálně. Klíčem je, že umělá inteligence může mít na paměti celý kontext současně kódové základny, zatímco se soustředíte na logiku vysoké úrovně. Kurzor 2.2 formalizován tento přístup s Režim ladění, postavená zcela nová smyčka agentů kolem informací za běhu a ověření člověkem.
Tradiční vs AI-Assisted Debugging: The Numbers
| Aktivita | Tradiční | S kurzorem AI | Úspory |
|---|---|---|---|
| Analýza trasování zásobníku | 15-30 min | 2-5 min | ~80 % |
| Identifikace hlavní příčiny | 1-4 hodiny | 20-45 min | ~70 % |
| Opravte a zkontrolujte | 30-90 min | 10-25 min | ~65 % |
| Vyšetřování úniku paměti | 2-6 hodin | 45-90 min | ~70 % |
| Detekce podmínek závodu | 4-12 hodin | 1-3 hodiny | ~75 % |
| Slabá testovací stabilizace | 2-8 hodin | 30-60 min | ~80 % |
Režim ladění: Cursor 2.2 Agent Loop
10. prosince 2025 vydal Cursor verzi 2.2, která představuje Režim ladění, jedna z nejvýznamnějších funkcí v historii IDE. Není to jednoduché Integrace debuggeru VS Code s AI: a zcela přepracovaná smyčka agentů kolem runtime informací a lidské spolupráce.
Jak funguje ladicí smyčka
Zásadní rozdíl oproti generickému asistovanému ladění je v tom, že Debug Mode jej nevyhledává okamžitě vygenerovat opravu. Místo toho postupuje v pěti krocích:
Smyčka režimu ladění
- Hypotetická analýza: Kurzor čte kódovou základnu a generuje několik hypotéz o tom, co by mohlo být špatně, aniž bychom předpokládali, že známe příčinu
- Instrumentace: Agent přidává cílené protokoly běhu v bodech identifikované jako pravděpodobné zdroje problému
- Přehrávání s průvodcem: Kurzor požádá uživatele, aby chybu reprodukoval s přístroji na místě a shromažďuje data za běhu
- Cílená oprava: Na základě reálných dat navrhuje minimální opravu a přesné místo spekulativního přepisování
- Kontrola a čištění: Po kontrole odstraňte veškeré vybavení ponechání čistého rozdílu připraveného k odevzdání
Chcete-li aktivovat režim ladění, otevřete panel Skladatel a klikněte na rozevírací seznam vedle tlačítka zadejte a vyberte „Režim ladění“. Od tohoto okamžiku bude agent pracovat v této smyčce místo toho, abyste pokračovali přímo se změnami.
// Esempio di come Cursor strumenta il codice durante Debug Mode
// File: src/app/services/payment.service.ts
// PRIMA della strumentazione
async processPayment(order: Order): Promise<PaymentResult> {
const cart = await this.cartService.getCart(order.userId);
const total = this.calculateTotal(cart);
return this.paymentGateway.charge(order.paymentMethod, total);
}
// DOPO la strumentazione aggiunta da Cursor Debug Mode
async processPayment(order: Order): Promise<PaymentResult> {
console.log('[DEBUG:cursor] processPayment called', {
orderId: order.id,
userId: order.userId,
paymentMethod: order.paymentMethod
});
const cart = await this.cartService.getCart(order.userId);
console.log('[DEBUG:cursor] cart retrieved', {
cartId: cart?.id,
itemCount: cart?.items?.length,
cartIsNull: cart === null
});
const total = this.calculateTotal(cart);
console.log('[DEBUG:cursor] total calculated', { total, cartTotal: cart?.total });
const result = await this.paymentGateway.charge(order.paymentMethod, total);
console.log('[DEBUG:cursor] payment result', { success: result.success, error: result.error });
return result;
}
// Dopo la riproduzione, Cursor vede nei log:
// [DEBUG:cursor] cart retrieved { cartId: undefined, itemCount: undefined, cartIsNull: false }
// Questo rivela che cart esiste ma items e undefined - bug trovato!
Přístrojový přístup je cílený a výkonný, protože eliminuje dohady. Místo toho přepište kód na základě hypotéz, Cursor shromáždí konkrétní důkazy, než podnikne akci. Konečným výsledkem je vždy minimální rozdíl: pouze nezbytná oprava, bez refaktoringu požadované nebo doplňky funkcí, které nebyly dohodnuty.
Když je režim ladění nejúčinnější
- Občasné chyby, které se ne vždy reprodukují (závodní podmínky, problémy s načasováním)
- Problémy se starším kódem, které neznáte
- Chyby, které se objevují až ve výrobě se skutečnými daty
- Chyby s hlubokým trasováním zásobníku zahrnujícím více knihoven
- Neočekávané chování bez explicitních chyb (tichá selhání)
Režim ladění a méně užitečný pro zjevné chyby kompilace nebo chyby TypeScript, kde Cmd+K inline je mnohem rychlejší.
Bugbot: Proaktivní zjišťování chyb na PR
Zatímco režim ladění opravuje chyby poté, co se objeví, Bugboti pokusit se zachytit je dříve, než se vůbec dostanou do výroby. Vydáno ve verzi 1 v červenci 2025 a výrazně vylepšený Bugbotem v11 v lednu 2026, integruje do procesu kontroly kódu automatickou analýzou každého požadavku na stažení.
Jak Bugbot funguje
Bugbot analyzuje PR rozdíl pomocí několika paralelních průchodů, z nichž každý má pořadí různé změny, které stimulují různé uvažování v modelu. Výsledky přicházejí v kombinaci s většinovým hlasováním ke snížení falešných poplachů. Tento přístup, podobný a ansámbl lidských recenzentů, bylo prokázáno, že zachytí skutečné chyby, které zůstávají bez povšimnutí v tradičních recenzích kódu.
// Esempio di configurazione Bugbot rules in .cursor/bugbot.rules
// Queste regole personalizzano cosa Bugbot considera un bug nel tuo progetto
# Regole per progetto Angular/TypeScript
## Patterns Pericolosi
- Flag qualsiasi uso di 'any' in funzioni pubbliche dei servizi
- Segnala operatori non-null assertion '!' su proprietà di input Angular
- Evidenzia subscribe() senza corrispondente unsubscribe() o takeUntilDestroyed()
- Avvisa quando una migration SQL non ha rollback corrispondente
## Invarianti del Progetto
- I componenti non devono accedere direttamente all'HttpClient, solo ai servizi
- Tutti i form devono avere validazione lato client E lato server
- Non usare localStorage direttamente, usa StorageService
## Falsi Positivi da Ignorare
- I file *.spec.ts possono usare 'any' per i mock
- I file di configurazione possono avere assert non-null
Bugbot Autofix: Automatická oprava
Nejvýkonnější funkce Bugbot v11 e Automatická oprava: když Bugbot identifikuje Chyba v PR může automaticky otevřít Cloud Agenta k implementaci opravy. Zmocněnec navrhuje změny jako komentář k PR nebo jako dodatečný závazek, pokud to dovolí recenzent přijmout nebo odmítnout opravu jediným kliknutím.
// Bug trovato da Bugbot su PR #142:
// File: src/app/components/user-profile/user-profile.component.ts
// PROBLEMA: Memory leak - Observable non viene unsubscribed
@Component({
selector: 'app-user-profile',
template: `<div>{{ user?.name }}</div>`
})
export class UserProfileComponent implements OnInit {
user: User | null = null;
constructor(private userService: UserService) {}
ngOnInit() {
// BUGBOT: Observable subscription senza unsubscribe
// Causa memory leak quando il componente viene distrutto
this.userService.getCurrentUser().subscribe(user => {
this.user = user;
});
}
}
// FIX PROPOSTO DA BUGBOT AUTOFIX:
@Component({
selector: 'app-user-profile',
template: `<div>{{ user?.name }}</div>`
})
export class UserProfileComponent {
private destroyRef = inject(DestroyRef);
user: User | null = null;
constructor(private userService: UserService) {
this.userService.getCurrentUser()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(user => {
this.user = user;
});
}
}
Bugbot se neustále vyvíjí. Cursor experimentuje s verzí stále zapnutý který nepřetržitě skenuje kódovou základnu místo čekání na PR a další hlavní vydání umožní Bugbotu nejprve spustit kód k ověření jeho vlastních chybových hlášení nahlásit je.
Rychlé ladění pomocí Cmd+K a Inline Chat
Pro většinu každodenních chyb jsou režimy ladění a Bugbot výkonnými nástroji někdy předimenzované. Nejrychlejší způsob, jak opravit zjevné chyby v Cursor e skrz Cmd+K (inline edit) a Panel chatu.
Okamžitá analýza trasování zásobníku
Když se v konzole nebo terminálu objeví výjimka, nejúčinnější pracovní postup je:
- Vyberte celé trasování zásobníku v konzole
- Stiskněte
Cmd+Shift+Lpro přidání výběru do kontextu chatu - píšeš: "Analyzujte toto trasování zásobníku a identifikujte hlavní příčinu. Ukažte, kde v kódu leží problém, a navrhněte minimální opravu."
Kurzor nečte pouze první řádek chyby. Sleduje cesty souborů v zásobníku, načtěte příslušný kód ze svého projektu a mentálně zrekonstruujte řetězec volání což způsobilo výjimku.
// Stack trace reale di un'app Angular con NgRx
ERROR TypeError: Cannot read properties of undefined (reading 'items')
at CartComponent.getItemCount (cart.component.ts:47:35)
at CartComponent_Template (cart.component.html:12:18)
at executeTemplate (core.mjs:11223)
at refreshView (core.mjs:11094)
at refreshComponent (core.mjs:12147)
at refreshChildComponents (core.mjs:11060)
// Cosa chiedi a Cursor:
// "Questo stack trace viene da un'app Angular con NgRx.
// CartComponent.getItemCount accede a items su una proprietà
// che risulta undefined. Analizza cart.component.ts e lo store
// corrispondente per trovare dove il dato non viene inizializzato."
// Cursor risponde analizzando:
// 1. cart.component.ts - come viene acceduto lo store
// 2. cart.reducer.ts - lo stato iniziale del reducer
// 3. cart.selectors.ts - i selettori usati nel componente
// E identifica:
// PROBLEMA in cart.reducer.ts:
const initialState: CartState = {
// 'items' manca! Lo stato iniziale non ha la proprietà
loading: false,
error: null
// items: [] <-- questa riga manca
};
// FIX:
const initialState: CartState = {
items: [], // aggiunto
loading: false,
error: null
};
Cmd+K pro kontextové vložené opravy
Když jste již identifikovali problémovou linii, Cmd+K a mnohem víc rychle aplikovat opravu. Vyberte problematický kód, stiskněte Cmd+K a popište problém v přirozeném jazyce. Kurzor pouze upravuje vybraný kód, bez klepněte na zbytek souboru.
// Selezioni questo codice in un service Angular e premi Cmd+K:
getUserData(id: string) {
return this.http.get(`/api/users/${id}`);
}
// Scrivi: "aggiungi gestione errori, tipizzazione forte con User interface,
// e timeout di 5 secondi"
// Cursor genera:
getUserData(id: string): Observable<User> {
return this.http.get<User>(`/api/users/${id}`).pipe(
timeout(5000),
catchError((error: HttpErrorResponse) => {
if (error.status === 404) {
return throwError(() => new Error(`User ${id} not found`));
}
if (error.name === 'TimeoutError') {
return throwError(() => new Error('Request timed out'));
}
return throwError(() => new Error('Failed to load user data'));
})
);
}
Kontrolní body a vrácení během ladění
Často opomíjená funkce při ladění a systému Kontrolní body kurzoru. Když zkoumáte několik hypotéz oprav, můžete uložit aktuální stav kódové základny jako kontrolní bod a vrátit se zpět, pokud pokus situaci zhorší.
Pracovní postup s kontrolním bodem
- Než začnete ladit složitou chybu, uložte kontrolní bod
- Vyzkoušejte první hypotézu opravy pomocí kurzoru
- Spusťte testy: pokud selžou, resetujte kontrolní bod jedním kliknutím
- Otestujte druhou hypotézu počínaje čistým stavem
- Pokračujte, dokud testy neprojdou
Odpadá tak klasický problém „zhoršil jsem věci a nevím, jak se vrátit“. takže zkoumání řešení je mnohem méně riskantní.
Nakonfigurujte TypeScript/Angular Debugger v Cursoru
Cursor používá stejný ladicí engine jako VS Code, což znamená, že všechny
launch.json že znáte práci identicky. Rozdíl je v tom kurzoru
přidává do procesu vrstvu AI, která vám pomůže interpretovat, co se děje
a rychleji řešit problémy.
Nastavte zdrojové mapy pro TypeScript
Klíčovým požadavkem pro efektivní ladění TypeScript je správná konfigurace zdrojových map. Bez nich debugger místo toho ukazuje na kompilované soubory JavaScriptu než do zdrojových souborů TypeScript, což znemožňuje čtení kódu při ladění.
// tsconfig.json - configurazione base per debugging
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"sourceMap": true, // OBBLIGATORIO per debugging TS
"inlineSources": true, // Include sorgente nelle source maps
"inlineSourceMap": false, // Usa file .map separati
"outDir": "./dist",
"strict": true,
"moduleResolution": "node"
}
}
// .vscode/launch.json - configurazione per Angular con Chrome
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Angular App",
"type": "chrome",
"request": "launch",
"url": "http://localhost:4200",
"webRoot": "${workspaceFolder}/src",
"sourceMapPathOverrides": {
"webpack:///./src/*": "${webRoot}/*"
},
"skipFiles": [
"node_modules/**",
"**/*.spec.ts"
]
},
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": [
"--runInBand",
"--no-coverage",
"${file}"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"env": {
"NODE_ENV": "test"
}
},
{
"name": "Debug Node.js Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/server/index.ts",
"runtimeArgs": ["--require", "ts-node/register"],
"sourceMaps": true,
"envFile": "${workspaceFolder}/.env.local"
}
]
}
Po nakonfigurování launch.json, můžete spustit ladicí program pomocí F5
jako ve VS Code. Rozdíl oproti kurzoru je v tom, že můžete vybrat bod přerušení nebo celé číslo
funkce na panelu ladění a požádejte AI, aby vysvětlila své chování nebo aby
navrhnout, proč má proměnná neočekávanou hodnotu.
Trik: Vypněte nativní TypeScript kurzoru
Ve velkých projektech (monorepos, pracovní prostory s více než 100 moduly), TypeScript Language Server Cursor může spotřebovat hodně paměti. Pokud zaznamenáte pomalost nebo pády, přidejte toto konfigurace pro použití TypeScript vašeho projektu místo interního kurzoru:
// .cursor/settings.json
{
"typescript.enableNativePreview": false,
"typescript.tsdk": "./node_modules/typescript/lib"
}
Úniky paměti, závodní podmínky a nespolehlivé testy s AI
Tyto tři kategorie chyb se historicky nejobtížněji ladí, protože nejsou deterministické. Vyskytují se přerušovaně, často pouze ve výrobě nebo pod zátěží a pokusy o jejich izolaci je často eliminují. Umělá inteligence kurzoru přináší významná výhoda právě zde: může analyzovat kód staticky identifikovat vzory které vedou k těmto chybám, ještě dříve, než se projeví.
Úniky paměti v Angular: Diagnostika a oprava
Nejčastějším únikem paměti v Angularu je nespravované předplatné RxJS. Ale existují mnoho dalších problematických vzorců, které se kurzor naučí rozpoznávat ve vašem konkrétním projektu.
// Prompt efficace per ricerca memory leak:
// "Analizza questo componente e identifica tutti i possibili
// memory leaks. Includi: subscriptions non gestite, event listeners
// non rimossi, interval/timeout non cancellati, e reference circolari."
// Componente con multipli leak:
@Component({
selector: 'app-dashboard',
template: `...`
})
export class DashboardComponent implements OnInit {
data: any[] = [];
private subscription: Subscription;
constructor(
private dataService: DataService,
private router: Router,
private renderer: Renderer2,
private elementRef: ElementRef
) {}
ngOnInit() {
// LEAK 1: Subscription senza unsubscribe
this.subscription = this.dataService.getStream()
.subscribe(data => this.data = data);
// LEAK 2: Event listener sul document non rimosso
document.addEventListener('keydown', this.handleKeyPress.bind(this));
// LEAK 3: Interval non cancellato
setInterval(() => this.refreshData(), 5000);
// LEAK 4: Router events subscription
this.router.events.subscribe(event => {
console.log(event);
});
}
handleKeyPress(event: KeyboardEvent) { /* ... */ }
refreshData() { /* ... */ }
}
// VERSIONE CORRETTA (generata da Cursor):
@Component({
selector: 'app-dashboard',
template: `...`
})
export class DashboardComponent implements OnInit, OnDestroy {
data: any[] = [];
private destroyRef = inject(DestroyRef);
private intervalId: ReturnType<typeof setInterval> | null = null;
private boundHandleKeyPress: (event: KeyboardEvent) => void;
constructor(
private dataService: DataService,
private router: Router
) {}
ngOnInit() {
// FIX 1: takeUntilDestroyed per tutte le subscriptions
this.dataService.getStream()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(data => this.data = data);
// FIX 2: Listener con cleanup esplicito
this.boundHandleKeyPress = this.handleKeyPress.bind(this);
document.addEventListener('keydown', this.boundHandleKeyPress);
// FIX 3: Interval con riferimento per cleanup
this.intervalId = setInterval(() => this.refreshData(), 5000);
// FIX 4: Router events con takeUntilDestroyed
this.router.events
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(event => console.log(event));
}
ngOnDestroy() {
document.removeEventListener('keydown', this.boundHandleKeyPress);
if (this.intervalId) {
clearInterval(this.intervalId);
}
}
handleKeyPress(event: KeyboardEvent) { /* ... */ }
refreshData() { /* ... */ }
}
Rasové podmínky: Diagnóza
Závodní podmínky v Angularu často vznikají při více asynchronních HTTP požadavcích dokončují se v nepředvídatelném pořadí nebo když je aktualizován stav komponenty po zničení součásti.
// Race condition classica in Angular: richieste HTTP concorrenti
// L'utente digita velocemente nel search box - ogni keystroke
// lancia una nuova richiesta, ma non necessariamente arrivano in ordine
// PROBLEMA:
@Component({
selector: 'app-search',
template: `
<input (input)="onSearch($event)">
<div *ngFor="let result of results">{{ result.title }}</div>
`
})
export class SearchComponent {
results: SearchResult[] = [];
constructor(private searchService: SearchService) {}
onSearch(event: Event) {
const query = (event.target as HTMLInputElement).value;
// RACE CONDITION: se digiti "an" poi "ang", la risposta per "an"
// potrebbe arrivare DOPO quella per "ang", mostrando risultati sbagliati
this.searchService.search(query).subscribe(results => {
this.results = results;
});
}
}
// SOLUZIONE con switchMap (generata da Cursor):
@Component({
selector: 'app-search',
template: `
<input [formControl]="searchControl">
<div *ngFor="let result of results$ | async">{{ result.title }}</div>
`
})
export class SearchComponent {
searchControl = new FormControl('');
private destroyRef = inject(DestroyRef);
results$ = this.searchControl.valueChanges.pipe(
debounceTime(300), // Attendi 300ms dopo l'ultimo keystroke
distinctUntilChanged(), // Ignora se il valore non cambia
filter(query => (query?.length ?? 0) >= 2), // Min 2 caratteri
switchMap(query => // Cancella la richiesta precedente
this.searchService.search(query ?? '').pipe(
catchError(() => of([])) // Gestisce errori senza rompere lo stream
)
),
takeUntilDestroyed(this.destroyRef)
);
constructor(private searchService: SearchService) {}
}
Šupinové testy: Stabilizační strategie
Jedním z problémů jsou slabé testy (testy, které občas projdou a selžou). nejvíce frustrující moderního vývoje. Kurzor je zvláště účinný při identifikaci příčiny, protože může současně analyzovat test, testovaný kód a vzory načasování.
// Flaky test in Angular: problema con async/await e timing
// Questo test fallisce circa il 30% delle volte
// FLAKY TEST:
it('should update user when form is submitted', fakeAsync(() => {
const fixture = TestBed.createComponent(UserFormComponent);
const component = fixture.componentInstance;
fixture.detectChanges();
component.nameControl.setValue('John Doe');
component.onSubmit();
// Problema: il test non aspetta il completamento dell'Observable
expect(component.successMessage).toBe('User updated successfully');
}));
// Cosa chiedi a Cursor:
// "Questo test e flaky - fallisce intermittentemente. Analizza il
// componente UserFormComponent e identifica perchè il test non e
// deterministico. Proponi una versione stabile del test."
// RISPOSTA DI CURSOR - analisi del problema:
// Il componente usa un Observable con delay, il test non lo aspetta correttamente
// TEST STABILE (generato da Cursor):
it('should update user when form is submitted', fakeAsync(() => {
const userServiceSpy = jasmine.createSpyObj('UserService', ['updateUser']);
userServiceSpy.updateUser.and.returnValue(of({ success: true }).pipe(delay(100)));
TestBed.configureTestingModule({
declarations: [UserFormComponent],
providers: [
{ provide: UserService, useValue: userServiceSpy }
]
});
const fixture = TestBed.createComponent(UserFormComponent);
const component = fixture.componentInstance;
fixture.detectChanges();
component.nameControl.setValue('John Doe');
component.onSubmit();
// Avanza il tempo virtuale di 100ms per completare il delay
tick(100);
fixture.detectChanges();
expect(component.successMessage).toBe('User updated successfully');
expect(userServiceSpy.updateUser).toHaveBeenCalledOnceWith({
name: 'John Doe'
});
}));
Profilování výkonu s pomocí AI
Ladění výkonu je samostatná disciplína: nejde o hledání chyb, ale o pochopit, proč je něco pomalé. Cursor nenahrazuje vyhrazené profilery jako Chrome DevTools nebo Angular DevTools, ale značně urychlují proces interpretace profilování dat a implementace optimalizací.
Analýza výkonnostních profilů pomocí kurzoru
Nejúčinnější pracovní postup a sběr dat o výkonu pomocí nativních nástrojů, pak přineste výsledky v Cursor pro analýzu a implementaci oprav.
// Esempio di workflow: ottimizzare un componente Angular lento
// Hai identificato con Angular DevTools che questo componente
// causa 850ms di change detection su ogni input
// Componente problematico (dati dal profiler):
@Component({
selector: 'app-large-table',
template: `
<table>
<tr *ngFor="let item of processedItems">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ formatDate(item.createdAt) }}</td>
<td>{{ calculateTotal(item) }}</td>
</tr>
</table>
`
})
export class LargeTableComponent {
@Input() items: RawItem[] = [];
// PROBLEMA 1: getter ricalcolato ad ogni change detection
get processedItems() {
return this.items.map(item => this.processItem(item));
}
// PROBLEMA 2: funzione chiamata nel template - ricreata ogni volta
formatDate(date: Date): string {
return new Intl.DateTimeFormat('it-IT').format(date);
}
// PROBLEMA 3: calcolo costoso nel template
calculateTotal(item: RawItem): number {
return item.prices.reduce((acc, price) => acc + price.amount, 0);
}
private processItem(item: RawItem): ProcessedItem { /* ... */ }
}
// VERSIONE OTTIMIZZATA (generata da Cursor con spiegazione):
@Component({
selector: 'app-large-table',
template: `
<table>
<tr *ngFor="let item of processedItems; trackBy: trackById">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.formattedDate }}</td>
<td>{{ item.total }}</td>
</tr>
</table>
`,
changeDetection: ChangeDetectionStrategy.OnPush // FIX 3: OnPush CD
})
export class LargeTableComponent {
private _items: RawItem[] = [];
processedItems: ProcessedItem[] = [];
@Input() set items(value: RawItem[]) {
this._items = value;
// FIX 1: calcola solo quando input cambia, non ad ogni CD
this.processedItems = value.map(item => this.processItem(item));
}
// FIX 2: trackBy per evitare ricreazione DOM inutile
trackById(index: number, item: ProcessedItem): string {
return item.id;
}
private dateFormatter = new Intl.DateTimeFormat('it-IT');
private processItem(item: RawItem): ProcessedItem {
return {
...item,
// Pre-calcola tutto durante la trasformazione
formattedDate: this.dateFormatter.format(item.createdAt),
total: item.prices.reduce((acc, price) => acc + price.amount, 0)
};
}
}
Integrace s Chrome DevTools
Pro pokročilé ladění výkonu kombinuje nejvýkonnější pracovní postup Chrome DevTools s kurzorem. Zachyťte profil výkonu nebo paměti v prohlížeči Chrome, exportujte data a požádejte kurzor, aby je interpretoval v kontextu vaší kódové základny.
// Workflow con Chrome DevTools + Cursor
// 1. In Chrome DevTools > Performance, cattura un profilo
// Identifica i frame lenti (rossi) e le funzioni costose
// 2. Copia il nome delle funzioni costose nel profile:
// "component_factory.ts:847 - ComponentFactory.create - 234ms"
// 3. Porta in Cursor:
// "Ho profilato la mia app Angular e component_factory.create
// richiede 234ms nei frame lenti. Il profiler mostra che viene
// chiamata quando l'utente cambia route. Analizza il sistema
// di routing e lazy loading e identifica dove i componenti
// vengono ricreati invece di essere riutilizzati."
// 4. Per heap snapshots (memory leaks):
// - In Chrome DevTools > Memory, prendi due heap snapshots:
// uno prima e uno dopo un'operazione sospetta
// - Confronta: Objects allocated between snapshots
// - Copia i tipi di oggetti con crescita anomala in Cursor:
// "Il heap snapshot mostra un aumento di 15MB in
// 'EventEmitter' instances dopo navigazione back/forward.
// Analizza i componenti che usano EventEmitter e identifica
// dove non vengono destroyati correttamente."
Pracovní postup ladění: Reprodukujte, izolujte, opravujte, testujte
Mít jednotlivé výkonné funkce nestačí. Skutečná konkurenční výhoda pochází z integrace tyto nástroje v opakovatelném a systematickém pracovním postupu. Zde je pracovní postup vývojářů produktivnější s Cursor mají standardizované.
Krok 1: Hrajte s maximálním kontextem
Než se dotknete kódu, shromážděte všechny dostupné informace o chybě. S kurzorem, to znamená poskytnout AI co nejbohatší kontext.
// Template per il primo messaggio di debugging in Cursor Chat:
/*
BUG REPORT:
- Comportamento atteso: [descrizione]
- Comportamento osservato: [descrizione]
- Frequenza: [sempre / intermittente al X%]
- Ambiente: [dev / staging / prod]
- Ultima modifica correlata: [commit hash o feature]
ERROR OUTPUT:
[incolla lo stack trace completo]
PASSI PER RIPRODURRE:
1. [passo 1]
2. [passo 2]
FILES PROBABILMENTE COINVOLTI:
- src/app/services/order.service.ts
- src/app/components/checkout/checkout.component.ts
@codebase analizza i file rilevanti e proponi le prime 3 ipotesi
sulla root cause, ordinate per probabilità.
*/
Fáze 2: Izolujte s minimálním testem
Jakmile určíte nejpravděpodobnější hypotézu, požádejte kurzor, aby vytvořil test který reprodukuje chybu v izolaci. To má dvě výhody: Testování hypotézy a poskytuje automatické regresní testování.
// Prompt per creare un test di isolamento:
// "Sulla base dell'analisi, il bug sembra essere in OrderService.calculateDiscount()
// quando items ha elementi con quantity: 0. Crea un unit test Jest che riproduce
// esattamente questo scenario e verifica il comportamento corretto."
// Cursor genera:
describe('OrderService.calculateDiscount', () => {
let service: OrderService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(OrderService);
});
// Test che riproduce il bug
it('should handle items with zero quantity without throwing', () => {
const orderWithZeroQty = {
items: [
{ id: '1', price: 100, quantity: 2 },
{ id: '2', price: 50, quantity: 0 }, // caso problematico
{ id: '3', price: 75, quantity: 1 }
],
discountCode: 'SAVE10'
};
// BUG: questo throw invece di restituire 0
expect(() => service.calculateDiscount(orderWithZeroQty)).not.toThrow();
expect(service.calculateDiscount(orderWithZeroQty)).toBe(17.5);
});
});
Fáze 3: Oprava pomocí přírůstkového ověření
Po provedení izolačního testu aplikujte opravu a okamžitě ji ověřte. Reverzní přístup TDD - nejprve regresní test, poté fix - např zvláště efektivní s kurzorem, protože můžete rychle opakovat.
// Prompt per la fix:
// "Il test di isolamento conferma il bug. Il problema e in calculateDiscount
// quando quantity e 0 causa una divisione per zero nel calcolo del prezzo
// unitario medio. Fixa calculateDiscount gestendo il caso quantity === 0
// e assicurati che tutti i test esistenti continuino a passare."
// Cursor analizza e genera la fix:
calculateDiscount(order: Order): number {
const validItems = order.items.filter(item => item.quantity > 0); // FIX
if (validItems.length === 0) {
return 0;
}
const subtotal = validItems.reduce(
(sum, item) => sum + (item.price * item.quantity),
0
);
const discount = this.discountService.getDiscount(order.discountCode);
return subtotal * (discount / 100);
}
Fáze 4: Kompletní regresní test
Po opravě požádejte Cursor, aby vygeneroval kompletní sadu testů, které chybu pokrývají pevné a související okrajové případy, aby se zajistilo, že se problém nebude opakovat.
// Prompt finale:
// "La fix e applicata e il test di isolamento passa. Ora genera una suite
// completa di test per calculateDiscount che copre: items normali,
// items con quantity 0, lista vuota, discount code invalido,
// e ordini con tutti gli items a quantity 0."
// Cursor genera 8 test cases che coprono tutti gli edge cases
// e aggiunge JSDoc al metodo spiegando il comportamento atteso
Osvědčené postupy pro ladění za pomoci umělé inteligence
1. Vždy přesný kontext
Ladění s pomocí AI je jen tak dobré, jak dobrý je kontext, který poskytnete. Rozdíl mezi vágní a přesnou výzvou může být rozdíl mezi 10 minut a 2 hodiny práce.
Principy pro efektivní ladění výzev
- Trasování celého zásobníku: vždy 5-10 řádků, nejen první
- Očekávané vs. pozorované chování: vysvětluje obojí
- Kontext souboru: USA
@filename.tszahrnout příslušné soubory - Naposledy upraveno: citujte odevzdání nebo funkci, pokud je chyba nedávná
- Prostředí: dev/staging/prod často mění chování
- Frekvence: vždy/přerušovaně/pouze při zátěži
2. Nedůvěřujte slepě Fix AI
Umělá inteligence může generovat opravy, které řeší symptom, ale ne příčinu. Správný pracovní postup e vždy: pochopte navrhovanou opravu, ověřte ji testy a vědomě ji schvalte.
Anti-Pattern: Přijímání oprav bez jejich pochopení
Vzor "ladění vibrací" - požádejte AI, aby opravila chybu, přijměte první návrh bez jeho pochopení, tlačení do výroby – je nejrychlejší způsob akumulace technický dluh. Každá oprava musí být:
- Děje se to na logické úrovni
- Ověřeno alespoň jedním testem
- Zkontrolováno pro nezamýšlené vedlejší účinky
3. Pro ladění použijte pravidla kurzoru
Můžete nastavit pravidla kurzoru specifická pro ladění, která trénují AI na vzorech vašeho projektu a vyhýbejte se opravám, které porušují vaše konvence.
// .cursor/rules/debugging.mdc
---
name: Debugging Standards
globs: ["src/**/*.ts", "src/**/*.spec.ts"]
---
# Standard di Debugging per Questo Progetto
## Quando proponi un fix per un bug:
1. Spiega la root cause in massimo 3 frasi
2. Mostra PRIMA il codice problematico con commento // PROBLEMA:
3. Mostra POI la versione corretta con commento // FIX:
4. Aggiungi un test di regressione per il caso problematico
## Pattern da evitare nei fix:
- Non usare 'any' come fix temporanea per errori TypeScript
- Non aggiungere try/catch senza gestione specifica dell'errore
- Non usare '!' (non-null assertion) per silenziare errori nullable
- Non modificare i test per farli passare invece di fixare il codice
## Pattern preferiti:
- Usa Optional Chaining (?.) per accessi nullable
- Usa Nullish Coalescing (??) per default values
- Usa type guards per narrowing
- Usa catchError con specifici tipi di errore in RxJS
4. Ladění relací jako dokumentace
Pokročilý osvědčený postup a považujte relace ladění za příležitosti dokumentaci. Po opravě složité chyby požádejte kurzor o vygenerování vysvětlující komentář v kódu, který dokumentuje nalezený problém a proč zvolené řešení je správné.
// Prompt post-fix:
// "Il bug e risolto. Aggiungi un commento JSDoc a calculateDiscount
// che documenta: il bug che abbiamo trovato (divisione per zero
// con quantity 0), la soluzione adottata (filter prima del calcolo),
// e un link al test di regressione."
// Cursor genera:
/**
* Calcola lo sconto totale per un ordine basato su un codice sconto.
*
* Nota: gli items con quantity === 0 vengono esclusi dal calcolo
* per evitare errori di divisione per zero nel calcolo del prezzo
* unitario medio. Questo comportamento e testato in:
* order.service.spec.ts > 'should handle items with zero quantity'
*
* @param order - L'ordine con items e codice sconto
* @returns Il valore dello sconto in euro (0 se nessun item valido)
*/
calculateDiscount(order: Order): number {
Nástroje pro ladění a integrace
Integrace s Datadogem
Pro týmy používající Datadog v produkci vám to umožňuje oficiální rozšíření Cursor přenést data sledování výroby přímo do IDE. Můžete přidat logpoints jejich zobrazením v kurzoru a požádejte agenta, aby vám pomohl odstraňovat chyby v produkci na základě skutečných protokolů a stop.
Nastavení Datadog + kurzor
- Nainstalujte rozšíření Datadog z Cursor Extensions (kompatibilní s VS Code)
- Nakonfigurujte přihlašovací údaje Datadog v nastavení
- V relacích ladění použijte
@datadoguvést skutečné logy do kontextu - Požádejte kurzor, aby porovnal produkční chyby se zdrojovým kódem
Angular DevTools a Cursor
Angular DevTools v prohlížeči a vynikající profiler pro problémy specifické pro Angular (detekce změn, strom komponent, vkládání závislostí). Když najdete problém v profileru přeneste informace do kurzoru pro analýzu kódu.
// Workflow Angular DevTools + Cursor
// 1. Apri Angular DevTools (F12 > Angular tab)
// 2. Profila la change detection: ogni barra rossa = frame lento
// 3. Clicca sul componente lento - vedi le proprietà e il tempo CD
// 4. In Cursor, porta il contesto:
// "Angular DevTools mostra che ProductListComponent impega 450ms
// per la change detection. Il profiler indica che il re-render
// avviene 47 volte in 1 secondo durante lo scroll.
// @product-list.component.ts analizza e ottimizza la change
// detection strategy e l'uso degli input."
// Cursor risponderà con:
// - Analisi del componente
// - Identificazione dei problemi (mancanza di OnPush, trackBy, ecc.)
// - Implementazione ottimizzata
Tradiční vs ladění za pomoci umělé inteligence: Kdy co použít
AI nenahrazuje všechny přístupy ladění. Existují scénáře ladění tradiční manuál a dokonce lepší nebo doplňkový.
Průvodce: Jaký přístup použít
| Scénář | Doporučený přístup | Nástroje |
|---|---|---|
| TypeScript / chyba kompilace | Cmd+K v řádku | Vložená úprava kurzoru |
| Trasování zásobníku s chybou běhu | Chat s kontextem souboru | Kurzorový chat + @soubor |
| Občasná chyba / závodní stav | Režim ladění | Režim ladění kurzoru (2.2) |
| Progresivní únik paměti | Profiler + analýza AI | Chrome DevTools + Cursor Chat |
| Regrese výkonu | Profiler + optimalizace AI | Angular DevTools + kurzor |
| Chyba v neznámém starším kódu | Režim ladění + @codebase | Režim ladění kurzoru + kontext |
| Hardware / nízkoúrovňové ladění | Nativní debugger | gdb/lldb, ruční zarážky |
| Chyby zabezpečení | Manuální kontrola kódu | Kurzor + expertní lidská kontrola |
Závěry: Budování kultury ladění za pomoci umělé inteligence
Ladění pomocí Cursor AI není jen otázkou nástrojů, je to změna mentality. Nejproduktivnější vývojáři „nežádají AI, aby opravovala chyby“ – staví strukturovaný dialog s umělou inteligencí, poskytující přesný kontext, ověřování hypotéz pomocí testů, a používání správných nástrojů pro každý typ problému.
Režim ladění kurzoru 2.2 představuje kvalitativní skok: již není třeba odborníci na kódovou základnu pro efektivní ladění. Přístup řízený hypotézou s Provozní instrumentace dramaticky snižuje čas strávený dohady. Bugbot se pohybuje součástí zátěže odhalování chyb v době kontroly kódu, což snižuje počet chyb, které se dostanou do výroby.
Pro týmy Angular je zisk obzvláště významný v historicky významných oblastech složitější: úniky předplatného, závodní podmínky v Observables, nespolehlivé asynchronní testy a výkon detekce změn. Kurzor tyto vzory zná a rozpoznává je rychle, kde méně zkušenému vývojáři mohou zabrat hodiny.
Kontrolní seznam pro začátek s laděním za pomoci umělé inteligence
- Konfigurovat
launch.jsons povolenými zdrojovými mapami - Schopnost
sourceMap: trueneltsconfig.json - Vytvořte pravidla kurzoru pro standardy ladění vašeho projektu
- Procvičte si šablonu "BUG REPORT" ve výzvách k ladění
- Experimentujte s režimem ladění na skutečné chybě ve vaší kódové základně
- Nakonfigurujte Bugbot, pokud používáte žádosti o stažení (GitHub/GitLab)
- Integrujte pracovní postup: reprodukujte - otestujte - opravte - ověřte pomocí kurzoru
Řada Cursor IDE pokračuje
Dokončili jste článek o ladění. Pokračujte dalšími články ze série:
- Další článek: Cursor vs Windsurf vs Copilot v roce 2026 - kompletní srovnání AI FDI na současném trhu
- Pro kompletní pracovní postupy: Profesionální pracovní postup: Úhlový projekt s kurzorem
- Chcete-li automatizovat kontroly: Háčky kurzoru: Automatizujte pracovní postup
Související křížové série: MCP a kurzor pro ladění s reálnými daty z databáze a série Moderní hranatý pro konkrétní osvědčené postupy Angular.







