Agent chạy test bị ngập output: 9 cờ để runner chỉ in phần lỗi
Test runner vốn in kết quả cho người đọc. Khi coding agent đọc cùng output đó, hàng trăm dòng test đã qua làm loãng đúng phần lỗi cần sửa. Bài này hướng dẫn đo output trước, gắn 9 cờ gọn theo từng runner, rồi ghim lệnh vào file agent đọc khi mở phiên.
Agent chạy bộ test. Một test lỗi. Hàng trăm test đã qua. Runner kể cho agent nghe về tất cả: tiêu đề từng file, tiến trình từng test, tên từng test đã qua. Rồi mới tới bản tóm tắt, và đâu đó trong đó là dấu vết lỗi (stack trace) mà agent thật sự cần.
Test reporter (trình báo cáo kết quả chạy test) được viết cho người đọc trên terminal. Coding agent không cuộn màn hình. Nó đọc đúng những gì lệnh in ra.
Phần hữu ích có thể bị cắt mất. Lệnh test lỗi chỉ được Claude Code đọc tối đa khoảng 10.000 ký tự. Vượt quá mức đó, agent chỉ nhận một đoạn đầu và một đoạn cuối, mỗi đoạn cùng kích cỡ đó, mà không có đường dẫn tới phần còn lại. Lệnh test lỗi thoát với mã khác 0, nên nó được tính là thất bại. Đó lại chính là lần chạy mà phần giữa quan trọng nhất.
Phần nào lọt vào giới hạn cũng có thể ở lại. Claude Code gửi toàn bộ cuộc trò chuyện theo mỗi yêu cầu. Tên các test đã qua vì thế đi theo các lượt sau, cho tới khi cuộc trò chuyện được thu gọn hoặc xóa.
Bạn không đổi được cách agent đọc. Bạn đổi được những gì runner in ra. Bài này làm theo ba bước: đo trước, gắn cờ gọn, rồi ghim lệnh lại.
Đo trước: agent đọc bao nhiêu ký tự?
Chạy bộ test đúng cách agent chạy: không qua terminal tương tác, mà qua ống dẫn, gộp đầu ra lỗi vào đầu ra thường. Rồi đếm.
npx vitest run 2>&1 | wc -c
npx vitest run --reporter=minimal 2>&1 | wc -c
Lệnh wc -c đếm số byte. Với output chỉ gồm ký tự ASCII thông thường, số byte cũng là số ký tự, đúng đơn vị mà giới hạn của Claude Code dùng. Bài này không in con số mẫu, vì con số phụ thuộc hoàn toàn vào bộ test của bạn: bao nhiêu test, log nhiều hay ít, dấu vết lỗi sâu tới đâu. Hãy chạy trên dự án của bạn, trước và sau mỗi cờ dưới đây, và giữ lại cờ nào làm con số giảm.
Một vòng lặp nhỏ so sánh nhiều biến thể trong một lần chạy:
for cmd in "pytest" "pytest -q" "pytest -q --tb=short"; do
printf '%-24s' "$cmd"
sh -c "$cmd" 2>&1 | wc -c
done
Lưu ý quan trọng: đo ở ngoài phiên agent. Vitest tự chuyển sang reporter gọn khi phát hiện đang chạy trong agent lập trình, nên đo trong phiên agent sẽ giấu mất con số "trước khi gắn cờ".
Cờ 1 đến 4: JavaScript và Python
Vitest: --reporter=minimal
Vitest 4.1 thêm một reporter với mục đích ghi rõ là giảm lượng văn bản mà AI agent phải đọc. Tài liệu reporters hiện tại của Vitest gọi nó là minimal, với agent là tên thay thế. Nó chỉ in test lỗi và thông báo lỗi của chúng. Log từ test đã qua và phần tóm tắt đều bị lược bỏ. Khi không cấu hình reporter mà Vitest phát hiện AI agent, nó tự dùng reporter này.
Hãy gắn cờ rõ ràng khi cấu hình của bạn đã đặt reporters, hoặc khi cơ chế phát hiện không nhận ra agent của bạn:
npx vitest run --reporter=minimal
Muốn có tín hiệu tiến trình, --reporter=dot in một dấu chấm cho mỗi test hoàn thành, chỉ kèm chi tiết khi có lỗi và phần tóm tắt. Cờ --silent=passed-only của giao diện dòng lệnh giữ lại output console chỉ từ test lỗi.
Jest: --silent
Nếu code của bạn ghi log trong lúc test chạy, mỗi dòng log đó đều đi vào ngữ cảnh (context) của agent. Giao diện dòng lệnh của Jest có một cờ cho việc này: --silent ngăn test in thông báo qua console.
npx jest --silent
Jest có một mặc định dễ gây hại cho agent: verbose mặc định là false, nhưng lại là true khi chỉ chạy một file test. Lần chạy lại một file sau khi sửa, tức lần chạy agent làm thường xuyên nhất, lại chính là lần báo cáo từng test một.
pytest: -q
Cờ -q là chế độ lặng của pytest, tức ít chi tiết hơn. Cờ cần tìm trong script và trong addopts là cờ ngược lại: -v cho mỗi test một dòng riêng, và -vv ngừng rút gọn văn bản assertion (nội dung câu kiểm tra) hoàn toàn.
pytest: --tb=short
Mặc định của pytest, --tb=auto, in dấu vết lỗi dài cho mục đầu và mục cuối. Cờ --tb=short là định dạng dấu vết lỗi ngắn hơn. Cờ --tb=line chỉ in một dòng cho mỗi lỗi, thường là quá ít. Dạng ngắn giữ lại file, dòng và câu kiểm tra lỗi, tức đúng thứ agent cần để hành động.
pytest -q --tb=short
Thêm một chi tiết cùng trang tài liệu: nếu addopts bật --showlocals, mỗi dấu vết lỗi mang theo biến cục bộ. Cờ --no-showlocals ẩn chúng trong lần chạy đó.
Cờ 5 đến 8: Go, Rust, PHP và Ruby
Go: bỏ -v
Lệnh go test ./... vốn đã lặng: package nào qua chỉ in một dòng ok cuối cùng. Cờ -v ghi lại mọi test trong lúc chạy, và in cả văn bản từ Log và Logf ngay cả khi test qua. Nếu target trong Makefile hoặc agent thêm -v, mọi test đã qua và mọi dòng t.Log đều quay lại.
Muốn xem thân thiện hơn, gotestsum bọc go test -json. Định dạng mặc định pkgname in một dòng cho mỗi package, và dots in một ký tự cho mỗi test. Cờ của go test đặt sau --:
go test ./...
gotestsum --format dots -- ./...
pkgname tăng theo số package, dots tăng theo số test, nên hãy đo cả hai trên repo của bạn.
Cargo: -q, ở cả hai phía của --
cargo test -q -- --quiet
Cờ -q đầu tiên là của Cargo, ẩn thông báo log của chính nó. Mọi thứ sau -- đi vào bộ chạy test. Ở đó, --quiet của libtest hiển thị một ký tự cho mỗi test, và là tên thay thế của --format=terse. Mặc định pretty in một dòng cho mỗi test.
PHPUnit: --no-progress
Tài liệu TextUI của PHPUnit liệt kê --no-progress: tắt hiển thị tiến trình chạy test. Test lỗi và tóm tắt kết quả vẫn in ra.
vendor/bin/phpunit --no-progress
Hai cờ kề bên cần tránh trong vòng lặp agent: --testdox thay output mặc định bằng định dạng TestDox, tức báo cáo từng test theo tên. --no-output tắt toàn bộ output, tức lấy đi cả chi tiết lỗi.
RSpec: --format progress
RSpec mặc định dùng định dạng progress: dấu . cho test qua, F cho test lỗi, * cho test chờ. Định dạng documentation in ra văn bản của mọi describe và it. Hãy kiểm tra file .rspec của dự án: nếu nó có --format documentation, đổi thành --format progress hoặc xóa dòng đó.
Cờ 9: dừng ở lỗi đầu tiên
Mỗi runner trên đây đều có một phiên bản của cùng một công tắc. Khi agent đang sửa một thứ, các lỗi sau lỗi đầu tiên là output agent phải đọc trước khi sửa được bất kỳ lỗi nào.
| Runner | Dừng sớm | Tài liệu nói gì |
|---|---|---|
| Vitest | --bail=1 |
dừng sau N test lỗi |
| Jest | --bail |
N suite lỗi, mặc định là 1 |
| pytest | -x |
dừng sau lỗi đầu tiên |
| go test | -failfast |
không chạy test mới sau một lỗi |
| PHPUnit | --stop-on-failure |
dừng ở lỗi đầu tiên |
| RSpec | --fail-fast |
dừng ở test lỗi đầu tiên |
Cargo dừng sớm ở mức thô hơn: nó thoát sau chương trình test đầu tiên lỗi, nhưng libtest vẫn chạy mọi test trong chương trình đó. Cờ --fail-fast riêng của libtest tồn tại, nhưng cần -Z unstable-options.
Gộp lại, vòng lặp nhanh cho từng runner trông như sau:
npx vitest run --reporter=minimal --bail=1
npx jest --silent --bail
pytest -q --tb=short -x
go test -failfast ./...
cargo test -q -- --quiet
vendor/bin/phpunit --no-progress --stop-on-failure
bundle exec rspec --format progress --fail-fast
Dừng sớm chỉ dùng cho vòng lặp, không dùng cho bước chốt. Trước khi agent tuyên bố xong việc, nó nên chạy hết bộ test, ở chế độ gọn, và đọc mọi lỗi.
Ghim lệnh vào file agent đọc khi mở phiên
Cờ chỉ có tác dụng khi agent dùng chúng. Hãy đặt lệnh vào file agent đọc lúc bắt đầu phiên. Claude Code nạp CLAUDE.md vào ngữ cảnh khi phiên bắt đầu. AGENTS.md là định dạng mở mà Codex, Gemini CLI, Cursor, Aider và nhiều công cụ khác đọc.
## Tests
- Khi đang sửa: `pytest -q --tb=short -x tests/test_orders.py`
- Trước khi tuyên bố xong: `pytest -q --tb=short`
Hai lựa chọn nặng hơn cũng có trong tài liệu của Claude Code. Cơ chế PreToolUse viết lại lệnh test trước khi chạy, để chỉ lỗi quay lại. Lựa chọn còn lại là chạy test trong một agent con, để output dài ở lại ngữ cảnh của agent con và chỉ bản tóm tắt quay về. Cả hai đều tốn công dựng hơn một dòng cờ.
Một lưu ý cuối về thu gọn cuộc trò chuyện: lệnh thu gọn đọc chính cuộc trò chuyện mà nó tóm tắt, nên tự nó cũng là một yêu cầu tốn kém. Các cờ trên là cách rẻ hơn.
Checklist trước khi áp dụng
- Đo output bằng
wc -cở ngoài phiên agent, trước và sau mỗi cờ. - Gắn cờ gọn đúng runner của dự án, không gắn cờ của runner khác.
- Thêm cờ dừng sớm cho vòng lặp sửa, và bỏ nó ở bước chạy toàn bộ cuối cùng.
- Ghim đúng hai lệnh, lúc sửa và lúc chốt, vào
CLAUDE.mdhoặcAGENTS.md. - Chạy hết bộ test ở chế độ gọn trước khi tuyên bố xong việc.
Bài này cùng nhóm chủ đề với bài so sánh công cụ chạy coding agent trong CI: So sánh 6 công cụ chạy coding agent trong CI. Nếu bạn đang dựng quy trình agent, đọc thêm bài đó để chọn công cụ trước khi tối ưu output của nó.
Nguồn tham khảo
- Gabriel Anhaia, "Your Test Run Floods the Agent's Context. 9 Flags That Cut the Output It Reads", DEV Community, 2026-10-24. https://dev.to/gabrielanhaia/your-test-run-floods-the-agents-context-9-flags-that-cut-the-output-it-reads-1f59
- Vitest, "Reporters" (tài liệu chính thức, đã đối chiếu mục Minimal Reporter và Default Configuration). https://vitest.dev/guide/reporters
