07 - カーソル AI によるデバッグ: 3 倍高速化
デバッグは、開発者の人生の中で最も時間のかかる作業の 1 つです。社内調査 Microsoft と Google の報告によると、上級開発者は 30 ~ 40% を費やしています。 バグの検索と修正に生産的な時間が費やされます。 AI ネイティブ IDE の出現により、これは 割合が崩れてきています。最適化されたワークフローで Cursor を使用しているユーザーは、削減までのレポートを作成します。 デバッグ時間の 65% がデバッグに費やされるのは、AI が確実だからではなく、 孤独でイライラすることの多いプロセスを、構造化された体系的なコラボレーションに変えます。
この記事では、「AI にバグの修正を依頼する」方法を紹介するだけではありません。探検してみましょう デバッグ専用の Cursor の特定の機能から、 デバッグモードの導入 カーソル2.2あり システムに バグボット PR の積極的なレビューのために、 TypeScript でのメモリ リーク、競合状態、不安定なテストに関する高度な戦略を通過する そしてアンギュラー。デバッグをアートから変える、反復可能なワークフローを構築する方法を学びます。 検証可能なエンジニアリングプロセスを曖昧にします。
この記事で学べること
- Cursor 2.2 のデバッグ モードの仕組みとランタイム ログに基づくエージェント ループ
- Bugbot: 自動自動修正によるプル リクエストのプロアクティブなバグ検出
- Cmd+K ワークフローとインライン チャットによるインスタント スタック トレース分析
- Cursor のソース マップを使用して TypeScript/Angular デバッガーを構成する
- メモリリーク、競合状態、不安定なテストに対する AI 戦略
- Chrome DevTools およびネイティブ VS Code デバッガーとの統合
- 完全なサイクル: 再現 - 分離 - 計測 - 修正 - 検証
- 実際のメトリクスを使用した従来のデバッグと AI 支援デバッグの比較
Cursor IDE および AI ネイティブ開発シリーズの記事
| # | アイテム | レベル |
|---|---|---|
| 1 | カーソル IDE: 開発者向け完全ガイド | 初心者 |
| 2 | カーソル ルール: プロジェクトの AI の構成 | 中級 |
| 3 | エージェント モード: コマンドを使用してコードベースを変更する | 中級 |
| 4 | プランモードとバックグラウンドエージェント | 高度な |
| 5 | カーソルフック: ワークフローを自動化する | 中級 |
| 6 | MCP とカーソル: IDE をデータベースと API に接続 | 高度な |
| 7 | 現在位置 - Cursor AI を使用したデバッグ: 3 倍高速化 | 中級 |
| 8 | 2026 年のカーソル vs ウィンドサーフィン vs 副操縦士 | 初心者 |
| 9 | プロフェッショナルなワークフロー: カーソルを使用した Angular | 高度な |
従来のデバッグの問題
問題が何であるかを調べるためにスタック トレースを 3 時間見つめた人
ある undefined null 許容フィールドについては、私たちが何を言っているのかを正確に理解しています。デバッグ
従来の方法では、膨大な認知コストがかかります。プログラムの状態を頭の中に入れておかなければなりません。
仮説を立て、ログを追加し、バグを再現し、結果を解釈し、反復します。
フローの各中断 - 追加する新しいログ、移動するブレークポイント -
集中力が途切れる。
デバッグに Cursor を使用する開発者は、このプロセスを排除するわけではありませんが、高速化します。 根本的に。重要なのは、AI がコンテキスト全体を同時に念頭に置くことができることです 高レベルのロジックに焦点を当てながら、コードベースの詳細を確認します。カーソル 2.2 が正式化 このアプローチを使用すると、 デバッグモード、まったく新しいエージェント ループが構築されました ランタイム情報と人間による検証を中心に。
従来のデバッグと AI 支援デバッグ: その数字
| 活動 | 伝統的 | カーソルAI搭載 | 貯蓄 |
|---|---|---|---|
| スタックトレース解析 | 15~30分 | 2~5分 | ~80% |
| 根本原因の特定 | 1~4時間 | 20~45分 | ~70% |
| 修正して確認してください | 30~90分 | 10~25分 | ~65% |
| メモリリーク調査 | 2~6時間 | 45~90分 | ~70% |
| 競合状態の検出 | 4~12時間 | 1~3時間 | ~75% |
| 不安定なテストの安定化 | 2~8時間 | 30~60分 | ~80% |
デバッグ モード: カーソル 2.2 エージェント ループ
2025 年 12 月 10 日に、Cursor はバージョン 2.2 をリリースしました。 デバッグモード、 これは、IDE の歴史の中で最も重要な機能の 1 つです。それは単純なことではありません VS Code デバッガーと AI の統合: および完全に再設計されたエージェント ループ ランタイム情報と人間のコラボレーションに関するものです。
デバッグ ループの仕組み
一般的な支援デバッグとの基本的な違いは、デバッグ モードではそれが検索されないことです。 すぐに修正を生成します。代わりに、次の 5 段階のプロセスに従います。
デバッグモードループ
- 仮説分析: カーソルがコードベースを読み取り、複数の仮説を生成します 原因がわかっているとは前提せずに、何が間違っているのかについて
- 計装: エージェントは対象のランタイム ログをポイントに追加します。 問題の考えられる原因として特定される
- ガイド付き再生: カーソルはユーザーにバグを再現するよう求めます 計測器を設置し、実行時データを収集します
- 対象となる修正: 実際のデータに基づいて、最小限の修正を提案します 投機的な書き換えではなく正確です
- チェックとクリーニング: 点検後は全ての装備を取り外します コミットの準備ができているクリーンな差分を残す
デバッグ モードをアクティブにするには、コンポーザー パネルを開き、ボタンの横にあるドロップダウンをクリックします。 入力して「デバッグモード」を選択します。その瞬間から、エージェントはこのループで動作します。 変更を直接続行する代わりに。
// 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!
インストルメンテーションのアプローチは、当て推量を排除するため、焦点が絞られており強力です。代わりに 仮説に基づいてコードを書き換え、Cursor はアクションを起こす前に具体的な証拠を収集します。 最終結果は常に最小限の差分です。リファクタリングは行わず、必要な修正だけを行います。 要求された機能、または合意されていない機能の追加。
デバッグ モードが最も効果的な場合
- 常に再現するとは限らない断続的なバグ (競合状態、タイミングの問題)
- 馴染みのないレガシーコードの問題
- 実際のデータを使用する運用環境でのみ発生するバグ
- 複数のライブラリにまたがる深いスタック トレースによるエラー
- 明示的なエラーを伴わない予期しない動作 (サイレントエラー)
デバッグ モードですが、明らかなコンパイル エラーや TypeScript エラーにはあまり役に立ちません。 Cmd+K インラインの方がはるかに高速です。
Bugbot: PR でのプロアクティブなバグ検出
デバッグ モードではバグが発生した後に修正しますが、 バグボット しようとしてください 本番環境に到達する前に阻止します。 2025 年 7 月にバージョン 1 でリリース 2026 年 1 月に Bugbot v11 で大幅に強化され、プロセスに統合されます。 各プルリクエストを自動的に分析することにより、コードレビューの効率を向上させます。
バグボットの仕組み
Bugbot は、それぞれに順序付けを備えた複数の並列パスを使用して PR diff を分析します。 モデル内のさまざまな推論を刺激するためのさまざまな変更。結果は来る 過半数投票と組み合わせて誤検知を減らします。このアプローチは、 人間のレビュー担当者の集団が、気づかれない本当のバグを発見することが証明されています 従来のコードレビューでは。
// 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: 自動修正
Bugbot v11 e の最も強力な機能 自動修正: Bugbot が識別したとき PR にバグがあると、修正を実装するために Cloud Agent が自動的に開かれることがあります。 エージェントは、PR へのコメントまたは追加のコミットとして変更を提案し、許可します。 レビュー担当者はワンクリックで修正を承認または拒否できます。
// 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;
});
}
}
バグボットは常に進化しています。カーソルはバージョンを実験中です 常時オン PR を待つ代わりにコードベースを継続的にスキャンし、次のメジャー リリースを実行します。 Bugbot がコードを実行して、最初に自身のバグレポートを検証できるようになります それらを報告するために。
Cmd+K とインライン チャットによるクイック デバッグ
日常的なバグのほとんどに対して、デバッグ モードとバグボットは強力なツールですが、 時には特大サイズ。 Cursor e の明らかなバグを修正する最速の方法 を通して Cmd+K (インライン編集) チャットパネル.
インスタントスタックトレース分析
コンソールまたはターミナルに例外が表示された場合、最も効率的なワークフローは次のとおりです。
- コンソールでスタック トレース全体を選択します
- プレス
Cmd+Shift+L選択内容をチャット コンテキストに追加するには - あなたは次のように書きます: 「このスタック トレースを分析し、根本原因を特定します。コードのどこに問題があるかを示し、最小限の修正を提案します。」
カーソルはエラーの最初の行を読み取るだけではありません。スタック上のファイル パスに従います。 プロジェクトから関連するコードを取得し、呼び出しチェーンを精神的に再構築します。 それが例外を引き起こしました。
// 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 によるコンテキスト インライン修正
すでに問題行を特定している場合は、 Cmd+K そしてさらに すぐに修正を適用できます。問題のあるコードを選択し、Cmd+K を押して説明します。 自然言語の問題。カーソルは選択したコードのみを変更します。 ファイルの残りの部分をタップします。
// 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'));
})
);
}
デバッグ中のチェックポイントとロールバック
システムのデバッグ時に見落とされがちな機能 チェックポイント カーソルの。複数の修正仮説を検討している場合、現在の状態を保存できます コードベースをチェックポイントとして削除し、試行によって状況が悪化した場合はロールバックします。
チェックポイントを使用したワークフロー
- 複雑なバグのデバッグを開始する前に、チェックポイントを保存してください
- Cursor を使用して最初の修正仮説を試してみる
- テストを実行します。テストが失敗した場合は、ワンクリックでチェックポイントをリセットします。
- クリーンな状態から開始して 2 番目の仮説をテストする
- テストに合格するまで続行します
これにより、典型的な「状況を悪化させてしまったので元に戻す方法がわからない」という問題が解消されます。 解決策を模索するリスクが大幅に軽減されます。
Cursor で TypeScript/Angular デバッガーを構成する
Cursor は VS Code と同じデバッグ エンジンを使用します。つまり、
launch.json 同じように機能することがわかります。違いはカーソルです。
プロセスの周囲に AI レイヤーを追加して、何が起こっているかを解釈できるようにします
問題をより早く解決します。
TypeScript のソース マップをセットアップする
TypeScript を効果的にデバッグするための重要な要件は、正しい構成です。 ソースマップの。これらがないと、デバッガーは代わりにコンパイルされた JavaScript ファイルを指します。 ソース TypeScript ファイルよりも大きいため、デバッグ中にコードを読み取ることができなくなります。
// 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"
}
]
}
設定が完了したら launch.json、次のようにしてデバッガを起動できます F5
VS Code のように。 Cursor との違いは、ブレークポイントまたは整数を選択できることです。
デバッグ パネルで機能を実行し、AI にその動作の説明を求めるか、
変数が予期しない値を持つ理由を示唆します。
トリック: カーソルのネイティブ TypeScript を無効にする
大規模なプロジェクト (モノリポジトリ、100 以上のモジュールを含むワークスペース) では、TypeScript 言語サーバー カーソルの使用は大量のメモリを消費する可能性があります。速度の低下やクラッシュに気付いた場合は、これを追加してください Cursor の内部の TypeScript の代わりにプロジェクトの TypeScript を使用するように設定します。
// .cursor/settings.json
{
"typescript.enableNativePreview": false,
"typescript.tsdk": "./node_modules/typescript/lib"
}
AI によるメモリ リーク、競合状態、不安定なテスト
これら 3 つのカテゴリのバグは、歴史的にデバッグが最も困難です。 それらは決定的ではありません。それらは断続的に発生し、多くの場合本番環境でのみ発生します。 または負荷がかかっている場合、それらを分離しようとすると、多くの場合、それらが除去されます。カーソルのAIがもたらすもの ここでの重要な利点は、コードを静的に分析できることです。 特定する パターン それが、顕在化する前であっても、これらのバグの原因となります。
Angular のメモリ リーク: 診断と修正
Angular で最も一般的なメモリ リークは、アンマネージド RxJS サブスクリプションです。しかし、それらは存在します Cursor が特定のプロジェクトで認識できるように学習する他の多くの問題のあるパターン。
// 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() { /* ... */ }
}
競合状態: 診断パターン
Angular の競合状態は、複数の非同期 HTTP リクエストが発生した場合によく発生します。 予測できない順序で完了するか、コンポーネントの状態が更新されたときに完了します。 コンポーネントが破壊された後。
// 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) {}
}
不安定なテスト: 安定化戦略
不安定なテスト (断続的に成功したり失敗したりするテスト) が問題の 1 つです 現代の開発で最もイライラするもの。カーソルは特に識別に効果的です。 テスト、テストされたコード、パターンを同時に分析できるため、原因を特定できます。 タイミングのこと。
// 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'
});
}));
AIを活用したパフォーマンスプロファイリング
パフォーマンスのデバッグは別の分野です。それはエラーを見つけることではなく、 何かが遅い理由を理解します。 Cursor は Chrome のような専用プロファイラーに代わるものではありません DevTools または Angular DevTools ですが、解釈プロセスが大幅に高速化されます。 データのプロファイリングと最適化の実装。
カーソルによるパフォーマンスプロファイルの分析
最も効果的なワークフローとネイティブ ツールでパフォーマンス データをキャプチャし、 分析と修正の実装のためにカーソル内の結果。
// 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)
};
}
}
Chrome DevTools との統合
高度なパフォーマンス デバッグのために、Chrome DevTools を組み合わせた最も強力なワークフロー カーソル付き。 Chrome でパフォーマンスまたはメモリのプロファイルをキャプチャし、データをエクスポートして、 コードベースのコンテキストでそれらを解釈するように Cursor に依頼します。
// 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."
デバッグのワークフロー: 再現、分離、修正、テスト
単一の強力な機能を備えているだけでは十分ではありません。本当の競争上の優位性は統合から生まれます これらのツールは、反復可能で体系的なワークフローで使用できます。開発者が行うワークフローは次のとおりです カーソルを標準化することで生産性が向上しました。
ステップ 1: 最大限のコンテキストで遊ぶ
コードに触れる前に、バグに関する入手可能な情報をすべて収集してください。カーソルを使用すると、 これは、AI に可能な限り豊富なコンテキストを提供することを意味します。
// 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à.
*/
フェーズ 2: 最小限のテストで隔離する
最も可能性の高い仮説を特定したら、Cursor にテストの作成を依頼します。 これによりバグが単独で再現されます。これには 2 つの利点があります: 仮説をテストする 自動回帰テストを提供します。
// 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);
});
});
フェーズ 3: 増分検証による修正
分離テストを実施したら、修正を適用してすぐに検証します。 逆 TDD アプローチ - 最初に回帰テスト、次に修正 - 例: 素早く反復できるため、Cursor を使用すると特に効果的です。
// 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);
}
フェーズ 4: 完全な回帰テスト
修正後、Cursor にバグをカバーする完全なテスト スイートを生成するよう依頼します。 問題が再発しないように、修正されたおよび関連するエッジ ケースを確認します。
// 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
AI 支援デバッグのベスト プラクティス
1. 常に正確なコンテキスト
AI 支援デバッグの効果は、提供されたコンテキストによって決まります。 曖昧なプロンプトと正確なプロンプトの違いは、 作業時間は10分と2時間。
効果的なデバッグ プロンプトの原則
- フルスタックトレース: 最初だけでなく、常に 5 ~ 10 行
- 予想される動作と観察された動作: 両方を説明します
- ファイルコンテキスト: アメリカ合衆国
@filename.ts関連ファイルを含める - 最終更新日: バグが最近のものである場合はコミットまたは機能を引用します
- 環境: dev/staging/prod は動作を頻繁に変更します
- 頻度: 常時/断続/負荷時のみ
2. Fix AI を盲目的に信頼しないでください
AI は症状に対処する修正を生成できますが、原因には対処できません。正しいワークフロー 常に: 提案された修正を理解し、テストで検証し、意識的に承認します。
アンチパターン: 修正を理解せずに受け入れる
「バイブ デバッグ」パターン - AI にバグの修正を依頼し、最初の要求を受け入れる 理解せずに提案し、本番に突入することが最も早く蓄積される方法です 技術的負債。各修正は次のようにする必要があります。
- それは論理レベルで起こります
- 少なくとも 1 つのテストで検証済み
- 意図しない副作用についてレビュー済み
3. デバッグにカーソル ルールを使用する
AI をトレーニングするデバッグ固有のカーソル ルールを設定できます。 プロジェクトのパターンに基づいて、規約に違反する修正を回避します。
// .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. ドキュメントとしてのデバッグセッション
高度なベスト プラクティスであり、デバッグ セッションを次の機会として扱います。 ドキュメント。複雑なバグを修正した後、Cursor に生成を依頼します。 見つかった問題とその理由を文書化したコード内の説明コメント 採用された解決策は正しいものです。
// 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 {
デバッグツールと統合
Datadog との統合
本番環境で Datadog を使用しているチームの場合、公式の Cursor 拡張機能を使用すると、 実稼働監視データを IDE に直接取り込みます。追加できます カーソルでログポイントを表示し、エージェントにサポートを依頼します。 実際のログとトレースに基づいて本番環境のバグをトラブルシューティングします。
Datadog + カーソルのセットアップ
- Cursor Extensions から Datadog 拡張機能をインストールします (VS Code 互換)
- 設定で Datadog 認証情報を構成する
- デバッグセッションでは、使用します
@datadog実際のログをコンテキストに取り込む - Cursor に本番環境のエラーをソース コードと関連付けるように依頼します
Angular DevTools とカーソル
ブラウザーの Angular DevTools と、Angular 固有の問題に対する優れたプロファイラー (変更検出、コンポーネントツリー、依存関係注入)。問題を見つけたとき プロファイラーで、コード分析のために情報を Cursor に取り込みます。
// 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
従来のデバッグと AI 支援デバッグ: いつ何を使用するか
AI はすべてのデバッグ手法を置き換えるわけではありません。デバッグするシナリオがあります。 従来のマニュアル、さらには優れた、または補完的なものもあります。
ガイド: どのアプローチを使用するか
| シナリオ | 推奨されるアプローチ | ツール |
|---|---|---|
| TypeScript / コンパイルエラー | Cmd+K インライン | カーソルインライン編集 |
| 実行時エラーのあるスタック トレース | ファイルコンテキストを使用したチャット | カーソルチャット + @file |
| 断続的なバグ/競合状態 | デバッグモード | カーソルデバッグモード (2.2) |
| 進行性のメモリリーク | プロファイラー+AI分析 | Chrome DevTools + カーソルチャット |
| パフォーマンスの回帰 | プロファイラー + AI の最適化 | Angular DevTools + カーソル |
| 不明なレガシーコードのバグ | デバッグモード + @codebase | カーソル デバッグ モード + コンテキスト |
| ハードウェア/低レベルのデバッグ | ネイティブデバッガー | gdb/lldb、手動ブレークポイント |
| セキュリティの脆弱性 | 手動でのコードレビュー | カーソル + 専門家による人間によるレビュー |
結論: AI 支援デバッグの文化の構築
Cursor AI を使用したデバッグは単なるツールの問題ではなく、変化です 精神性の。最も生産性の高い開発者は、「AI にバグの修正を依頼」しません。 AI との構造化された対話、正確なコンテキストの提供、テストによる仮説の検証、 あらゆる種類の問題に適切なツールを使用します。
Cursor 2.2 のデバッグ モードは質的な飛躍を表しています。 コードベースの専門家による効果的なデバッグ。仮説に基づいたアプローチ ランタイムインストルメンテーションにより、推測に費やす時間が大幅に削減されます。バグボットが動く コードレビュー時のバグ検出の負担の一部となり、数が削減されます。 本番環境に到達するバグの数。
Angular チームにとって、歴史的に重要な分野でのメリットは特に大きい さらに難しい: サブスクリプションのリーク、Observables の競合状態、不安定な非同期テスト 変化検出のパフォーマンス。カーソルはこれらのパターンを認識し、認識します 経験の浅い開発者にとっては何時間もかかる可能性があるところを、すぐに実現できます。
AI 支援デバッグを開始するためのチェックリスト
- 設定する
launch.jsonソースマップが有効な場合 - 能力
sourceMap: trueneltsconfig.json - プロジェクトのデバッグ標準に合わせてカーソル ルールを作成する
- デバッグ プロンプトで「BUG REPORT」テンプレートを練習します。
- コードベース内の実際のバグでデバッグ モードを試してください
- プル リクエストを使用する場合は Bugbot を構成する (GitHub/GitLab)
- ワークフローを統合: カーソルを使用して再現 - テスト - 修正 - 検証
カーソル IDE シリーズは継続します
デバッグに関する記事はこれで完了です。シリーズの他の記事に進みます。
- 次の記事: 2026 年のカーソル vs ウィンドサーフィン vs 副操縦士 - 現在の市場におけるAI FDIの完全な比較
- 完全なワークフローの場合: プロフェッショナルなワークフロー: カーソルを使用した Angular プロジェクト
- チェックを自動化するには: カーソルフック: ワークフローを自動化する
関連するクロスシリーズ: MCPとカーソル デバッグ用 データベースからの実際のデータとシリーズ モダンアンギュラー 特定の Angular のベスト プラクティスについては、







