Với những team mà dev và QA làm việc gần nhau trong cùng một IDE, Cursor là lựa chọn tự nhiên để tích hợp TestRail MCP: agent mode của Cursor có thể vừa đọc code test tự động trong repo, vừa gọi tool TestRail để đối chiếu, đề xuất case còn thiếu, và phát hiện case nào chưa có automation coverage — tất cả không cần rời khỏi cửa sổ code. Bài này hướng dẫn cách kết nối TestRail MCP với Cursor Agent Mode, cách gắn case ID vào code test tự động, cách phát hiện case chưa được automation hoá, và những giới hạn/cách khắc phục khi dùng Cursor cho việc này.
Kết Nối TestRail MCP Với Cursor Agent Mode
Cursor lưu cấu hình MCP server trong file .cursor/mcp.json (theo project) hoặc trong Settings global. Khai báo TestRail MCP server:
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "mcp-server-testrail"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.io",
"TESTRAIL_EMAIL": "qa-bot@yourcompany.com",
"TESTRAIL_API_KEY": "your-api-key-here",
"TESTRAIL_PROJECT_ID": "12"
}
}
}
}
Vào Cursor Settings → MCP để xác nhận server hiện trạng thái xanh (connected) và xem danh sách tool đã được expose. Điểm khác biệt của Cursor so với các IDE/CLI khác: bạn phải chuyển sang Agent Mode (không phải Chat/Ask thông thường) để model được phép gọi tool MCP — ở mode Ask thông thường, Cursor chỉ trả lời dựa trên context code, không thực thi tool call.
Trong Agent Mode, khi model đề xuất gọi một tool ghi dữ liệu (ví dụ testrail_add_case), Cursor sẽ hiện một khối xác nhận ngay trong panel chat, hiển thị rõ tên tool và tham số trước khi bạn bấm "Run" — tương tự cách Cursor xác nhận trước khi apply một diff code. Đây là điểm UX (trải nghiệm người dùng) khá tốt: bạn nhìn thấy tool call giống như nhìn thấy một diff code, dễ review trước khi cho phép chạy.
Mẹo: Bật chế độ hiển thị chi tiết tham số tool call đầy đủ (thường có toggle "show full parameters" trong panel xác nhận) thay vì chỉ xem tóm tắt. Với tool ghi dữ liệu như
testrail_add_case, tham sốcustom_stepshoặccustom_expectedcó thể bị cắt ngắn trong view tóm tắt, khiến bạn duyệt mà không thấy hết nội dung thật sẽ được ghi.
Gắn Code Test Tự Động Với Case ID Trong TestRail
Một trong những việc giá trị nhất mà Cursor Agent Mode làm tốt là tận dụng việc nó đang "ở ngay trong" codebase để tự động gắn kết case TestRail với test code tương ứng — việc mà nếu làm thủ công sẽ rất tốn thời gian với codebase lớn.
Ví dụ prompt thực tế sau khi viết xong một file test mới:
Đọc file tests/e2e/checkout.spec.ts vừa viết. Với mỗi test("...") trong file này,
tìm case tương ứng trong suite "Checkout" của TestRail (dùng testrail_get_cases,
so khớp theo mô tả hành vi, không chỉ so khớp tên chuỗi).
Nếu tìm thấy case khớp, thêm comment ngay trên dòng test() dạng:
// TestRail: C<case_id>
Nếu không tìm thấy case khớp, đề xuất tạo case mới, in ra bảng đề xuất
trước khi tạo thật.
Cursor sẽ đọc từng test() block, hiểu ngữ cảnh hành vi (không chỉ dựa vào tên hàm), rồi tra cứu case tương ứng. Với các test đã có annotation cũ nhưng case ID sai (ví dụ do case đã bị đổi ID sau khi merge suite), agent có thể phát hiện case đó không còn tồn tại (testrail_get_cases không trả về ID đó nữa) và báo cho bạn để sửa annotation.
Sau khi có annotation nhất quán, việc đồng bộ kết quả CI về TestRail ở các bước sau (dù chạy qua Claude Code, script riêng, hay pipeline CI) đều dựa trên đúng annotation này — đây là lý do annotation case ID nên được coi là một phần "hạ tầng" của repo, không phải chi tiết vụn vặt.
Mẹo: Chuẩn hoá format annotation thành đúng một dạng duy nhất trong toàn repo (ví dụ luôn là
// TestRail: C1024, không lúc viết#TestRail:1024lúc viết// tr-case-1024). Thêm rule này vào file.cursor/rulesđể Cursor luôn tự áp dụng đúng format này mỗi khi tạo annotation mới, tránh tình trạng annotation không đồng nhất gây khó cho các script/agent đọc lại sau này.
Phát Hiện Case Chưa Có Automation Coverage Từ Cursor
Câu hỏi mà QA lead và dev lead thường xuyên cần trả lời trước mỗi retro hoặc mỗi lần lập kế hoạch tự động hoá: "còn case nào đang phải test tay mà chưa được automation hoá?" Với Cursor đang mở cả codebase và có quyền truy cập TestRail, câu hỏi này trở thành một truy vấn có thể tự động hoá gần như hoàn toàn:
So sánh 2 nguồn dữ liệu:
1. Toàn bộ case trong suite "Checkout" (testrail_get_cases).
2. Toàn bộ annotation "// TestRail: C<số>" xuất hiện trong thư mục tests/.
Liệt kê case nào KHÔNG có annotation tương ứng nào trong tests/ (nghĩa là chưa
có automation coverage), sắp xếp theo priority giảm dần. Với mỗi case, ước lượng
độ khó tự động hoá (Easy/Medium/Hard) dựa trên mô tả Steps của case đó
(ví dụ case liên quan thanh toán qua bên thứ ba thường Hard, case validate
form đơn giản thường Easy).
Kết quả của truy vấn này là một danh sách ưu tiên hoá (prioritized backlog) rất thực tế cho việc lập kế hoạch automation sprint tới — không chỉ biết "còn thiếu gì" mà còn biết "cái gì nên làm trước" dựa trên tỷ lệ giá trị/độ khó.
Một biến thể hữu ích khác: phát hiện automation "orphan" — test code tồn tại nhưng case TestRail tương ứng đã bị archive hoặc xoá:
Quét toàn bộ annotation "// TestRail: C<số>" trong tests/, với mỗi case_id,
gọi testrail_get_cases để xác nhận case đó còn tồn tại và đang active trong TestRail.
Liệt kê case_id nào không còn tồn tại (test code đang "mồ côi", không map đến case nào).
Mẹo: Chạy 2 truy vấn "coverage gap" và "orphan automation" này định kỳ mỗi 2 sprint, không phải chỉ một lần. Codebase và TestRail đều thay đổi liên tục — case mới được thêm, test code được refactor hoặc xoá — nên một bức ảnh chụp (snapshot) một lần sẽ nhanh chóng lỗi thời.
Giới Hạn Và Cách Khắc Phục Khi Dùng TestRail MCP Trong Cursor
Vài giới hạn thực tế cần biết trước khi phụ thuộc hoàn toàn vào Cursor cho workflow TestRail:
- Giới hạn về số lượng tool call trong một phiên Agent Mode. Với các truy vấn cần lặp qua nhiều case (ví dụ so khớp annotation cho hàng trăm test), Cursor có thể dừng giữa chừng do đạt giới hạn số bước (step limit) của agent loop. Cách khắc phục: chia truy vấn theo từng suite hoặc từng thư mục con (ví dụ xử lý
tests/e2e/checkout/trước, rồitests/e2e/payment/sau), thay vì yêu cầu xử lý toàn bộtests/trong một lần. - So khớp ngữ nghĩa giữa test code và case đôi khi không chính xác 100%. Nếu tên test và mô tả case dùng từ ngữ hoàn toàn khác nhau (ví dụ test code viết tiếng Anh kỹ thuật, case TestRail viết tiếng Việt theo văn phong nghiệp vụ), độ chính xác so khớp giảm. Cách khắc phục: khi viết test code mới, thêm docstring/comment mô tả hành vi bằng đúng ngôn ngữ và văn phong dùng trong case TestRail, giúp agent so khớp chính xác hơn ở các lần chạy sau.
- Không có cách "khoá" (lock) một case trong khi agent đang cập nhật, nên nếu 2 người cùng chạy Cursor Agent Mode để sửa case cùng lúc trên cùng project, có rủi ro ghi đè (race condition) — dù nhỏ, nhưng có thể xảy ra ở team lớn nhiều người dùng đồng thời.
- Custom field đặc thù của từng công ty (ví dụ field "Regulatory Impact" trong ngành fintech) cần được liệt kê rõ tên và option hợp lệ trong prompt hoặc trong file rule, vì agent không tự "học" được toàn bộ business context đằng sau field custom đó chỉ từ schema API.
Mẹo: Với các thay đổi quan trọng trên case đang có nhiều người theo dõi (case liên quan tính năng đang trong giai đoạn regression trước release), quy định rõ trong quy trình team: chỉ một người được chạy Cursor Agent Mode để cập nhật case trong khung thời gian đó, tránh race condition dù xác suất xảy ra không cao.
Mẹo
Vài điểm cần chuẩn bị để Cursor + TestRail MCP hoạt động hiệu quả và an toàn trong lâu dài:
- Đặt các rule về annotation, naming case, và giới hạn quyền ghi vào
.cursor/rules(không chỉ nói miệng trong prompt), để mọi thành viên team dùng Cursor đều tuân theo cùng chuẩn. - Với case liên quan đến compliance hoặc dữ liệu tài chính nhạy cảm, luôn giữ nguyên tắc "AI đề xuất, người duyệt" — không tự động hoá hoàn toàn bước tạo/sửa case cho các case thuộc nhóm rủi ro cao này.
- Theo dõi log các lần Cursor Agent Mode gọi tool ghi dữ liệu TestRail qua panel history của Cursor, định kỳ review nhanh để phát hiện sớm nếu agent có xu hướng lệch khỏi convention của team.
Mẹo: Nếu team vừa dùng Cursor vừa dùng công cụ khác (Claude Code, OpenCode) cho TestRail, đảm bảo rule về annotation và naming convention được viết chung trong một file (ví dụ đồng bộ nội dung giữa
CLAUDE.mdvà.cursor/rules), tránh tình trạng mỗi công cụ áp dụng một chuẩn khác nhau chỉ vì rule được viết riêng lẻ ở từng nơi.