Lewati ke konten

Debug pengujian yang gagal dengan agen

Panduan ini menunjukkan cara membuat agen memakai debugger pada kegagalan yang tidak dapat dijelaskan oleh pernyataan print.

Alat debug menjalankan sesi Debug Adapter Protocol yang sesungguhnya. Frame yang berhenti menjawab semua pertanyaan tentang momen itu sekaligus — setiap variabel lokal, setiap pemanggil, dan ekspresi yang dievaluasi dalam scope milik frame itu sendiri — sedangkan pernyataan print hanya menjawab pertanyaan yang sempat Anda pikirkan sebelum menjalankannya.

Alat ini tetap ada di permukaan agar agen dapat menanyakan mengapa tidak ada yang bisa dipakai, alih-alih menebak. Adapter baru benar-benar dapat dimulai jika kedua hal berikut terpenuhi:

  • ada penanda proyek di checkout, dan
  • biner adapter dapat di-resolve.

Minta agen memeriksanya:

debug(op: "adapters")

Alat itu menjawab dengan apa yang ditemukannya, atau menjelaskan bahwa sebuah adapter memerlukan kedua bagian tersebut.

Bahasa Adapter Penanda Instalasi
Dart / Flutter dart debug_adapter pubspec.yaml Sudah termasuk dalam SDK — tidak ada yang perlu dilakukan
Python python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt pip install debugpy
Rust / C / C++ lldb-dap Cargo.toml, CMakeLists.txt Sudah termasuk dalam LLVM
Go dlv dap go.mod go install github.com/go-delve/delve/cmd/dlv@latest

Urutannya penting dan alat ini menegakkannya: breakpoint dapat ditetapkan sebelum sesi ada, karena itulah urutan yang diwajibkan protokol.

Minta agen melakukan sesuatu seperti:

Fungsi compute di bin/main.dart mengembalikan nilai yang salah. Tetapkan breakpoint pada baris yang menetapkan product, jalankan di bawah debugger, dan beri tahu saya berapa nilai a dan b sebenarnya.

Agen akan menjalankan kira-kira:

debug(op: "breakpoints", file: "bin/main.dart", lines: [7])
debug(op: "launch", program: "bin/main.dart")

Peluncuran melaporkan di mana program berhenti:

Launched bin/main.dart on dart (session dart-1). Stopped: breakpoint. Use `stack` to see where.
debug(op: "stack")
→ #1 compute (bin/main.dart:7:3)
#2 main (bin/main.dart:2:18)

Lalu telusuri masuk ke dalamnya:

debug(op: "scopes", frame_id: 1)
→ Locals (reference 12)
debug(op: "variables", reference: 12)
→ a (int) = 6
b (int) = 7
product (int) = 42

Objek yang memiliki anak melaporkan [expand: reference N] — tetapi hanya jika memang benar-benar ada sesuatu di baliknya, sehingga ekspansi yang tidak dapat dipakai agen tidak pernah ditawarkan.

Untuk apa pun yang tidak terlihat sebagai variabel lokal:

debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)
Yang Anda inginkan Op
Jalankan sampai perhentian berikutnya continue
Baris berikutnya, frame yang sama step_over
Masuk ke dalam pemanggilan step_in
Keluar ke pemanggil step_out
Hentikan program yang sedang berjalan pause

Untuk proses yang macet, bukan proses yang Anda jalankan sendiri:

debug(op: "attach", port: 5858)
debug(op: "terminate")

Selalu akhiri sesi. Adapter debug memiliki proses yang berhenti yang memegang apa pun yang dipegang proses itu — port, lock, koneksi basis data.

Ekspansi variables pada graf objek yang dalam memang tidak terbatas secara alami — satu widget Flutter menjangkau seluruh pohon elemen. Anak per scope dibatasi 50, nilai dibatasi 400 karakter, dan stack frame dibatasi 30. Hasil alat yang memenuhi jendela konteks adalah alat yang mengakhiri run yang sedang dibantunya.