Nhiều team khi mới đưa AI vào QA thường coi exploratory testing (kiểm thử tự do/khám phá) là "phần thêm" — làm khi rảnh, làm khi có thời gian dư sau regression. Đó là cách nghĩ sai lệch, và nó càng sai hơn trong một agentic loop, nơi mọi bước đều được thiết kế để tạo tín hiệu (signal) cho bước sau. Trong agentic QA workflow mà module này đang xây, exploratory testing không phải là "làm thêm cho vui" — nó là stage thứ 5 trong loop, đứng ngay sau scripted/automated testing, và nó tồn tại để trả lời một câu hỏi mà không script nào trả lời được: "Có gì đang xảy ra mà chúng ta chưa nghĩ tới hỏi?" Bài này đi sâu vào lý do vì sao thứ tự này không phải ngẫu nhiên, cách dùng code diff + test plan + kết quả CI để AI tự sinh ra charter (bản kế hoạch khám phá) theo đúng rủi ro thực tế, cách ghi note session theo định dạng có thể tái sử dụng ngay, và cách cân đối thời gian explore với sprint capacity mà không làm rối lịch trình.
Vì sao exploratory testing đến sau scripted testing trong agentic loop?
Đây là câu hỏi mà rất nhiều senior QA từng tự hỏi khi mới làm quen với agentic workflow: "Nếu exploratory testing giỏi tìm ra bug lạ, sao không làm trước để lỡ có gì nghiêm trọng thì phát hiện sớm?" Câu trả lời nằm ở bản chất khác nhau giữa hai loại kiểm thử: scripted testing xác nhận cái đã biết, exploratory testing đi tìm cái chưa biết. Và để tìm hiệu quả cái chưa biết, bạn cần biết trước cái đã biết là gì — nếu không, bạn sẽ lãng phí thời gian dò lại những thứ script đã xác nhận rồi.
Bài Toán Thiếu Thông Tin Khi Explore Trước
Nếu explore trước khi có kết quả scripted test, tester (hoặc AI agent đóng vai explorer) hoàn toàn không có tín hiệu về việc code thay đổi ảnh hưởng tới đâu. Explore trong tình trạng "mù" như vậy dẫn tới một pattern rất phổ biến: người test rơi vào vùng an toàn — click vào những màn hình họ thuộc, kiểm tra lại happy path mà chính automation cũng đã cover. Kết quả là exploratory session tốn 2-3 giờ nhưng tìm ra đúng những gì regression suite đã báo cáo từ trước, còn vùng rủi ro thật (thường nằm sâu trong logic vừa đổi) thì không ai chạm tới vì không ai biết nó tồn tại.
Vấn đề gốc là: bộ não con người (và cả AI agent) luôn có xu hướng explore theo thói quen hoặc theo cấu trúc UI dễ thấy, không theo rủi ro thực tế của thay đổi. Nếu không có tín hiệu định hướng, explore trước gần như luôn lệch khỏi nơi cần soi kỹ nhất.
Kết Quả Scripted Test Nói Gì Với Người Explore
Kết quả từ scripted/automated test — pass, fail, flaky, skip — không chỉ là báo cáo trạng thái, nó là bản đồ rủi ro (risk map) miễn phí. Một vài tín hiệu quan trọng mà scripted result cung cấp cho bước explore:
- Test fail hoặc flaky quanh một khu vực → khu vực đó có khả năng cao còn vấn đề chưa lộ hết; explorer nên đào sâu quanh biên (boundary) của case đã fail, không chỉ dừng ở đúng bug đã báo.
- Test pass nhưng coverage assertion mỏng (chỉ check status code, không check side-effect) → đây là vùng "pass giả" — automation nói OK nhưng chưa thực sự kiểm chứng hành vi, cần explorer soi kỹ hành vi thật trên UI/data.
- Test bị skip hoặc chưa viết được (thường do khó tự động hóa: animation, timing, đa thiết bị, thông báo real-time) → đây chính là vùng exploratory testing có giá trị cao nhất, vì automation chưa và có thể sẽ không bao giờ cover được.
Việc đọc kỹ 3 loại tín hiệu này trước khi vào phòng explore giúp bạn (hoặc AI agent) bắt đầu với một danh sách "nơi cần nhìn" thay vì một trang trắng.
Trình Tự Trong Loop
Đặt trong bức tranh tổng của agentic QA loop (đã nói ở bài 1 của module), thứ tự chuẩn là: code change → test plan cập nhật → scripted/automated test chạy trên CI → exploratory testing dựa trên kết quả CI → feedback vòng lại test plan và bug pipeline. Exploratory testing ở vị trí stage 5 này đóng vai trò "lưới an toàn thứ hai" (second safety net) — không lặp lại việc scripted test đã làm, mà lấp đúng khoảng trống mà scripted test không thể làm: hành vi cần trực giác con người, tương tác đa bước không tuyến tính, những thứ chỉ "cảm thấy sai" khi nhìn bằng mắt.
Về mặt agentic, điều này có nghĩa: agent sinh charter (charter-generation agent) phải được cấp quyền đọc kết quả CI run gần nhất trước khi sinh charter, không phải sinh charter song song hoặc trước khi CI chạy xong. Nếu pipeline của bạn hiện đang trigger charter generation ngay khi PR mở (song song với CI), đó là một lỗi kiến trúc loop cần sửa — charter sinh ra sẽ thiếu tín hiệu quan trọng nhất.
Khi Nào Nên Explore Trước (Trường Hợp Ngoại Lệ)
Có 3 tình huống mà explore trước scripted test lại hợp lý hơn:
- Feature hoàn toàn mới, chưa có automation nào cover — không có "kết quả CI" để tham chiếu, vì chưa có test nào chạy trên feature đó. Lúc này exploratory testing đóng vai trò khám phá để hiểu hành vi, làm nền cho việc viết test plan/script sau — đây chính là trường hợp exploratory testing phục vụ ngược cho scripted testing, không phải ngược lại như luồng thông thường.
- CI đang đỏ toàn diện do lỗi hạ tầng (môi trường test down, flaky ở tầng infrastructure) — chờ scripted result trong tình huống này vô nghĩa vì tín hiệu bị nhiễu hoàn toàn; explore trực tiếp trên môi trường staging để đánh giá nhanh mức độ nghiêm trọng trước khi CI được sửa.
- Hotfix khẩn cấp với thời gian cực ngắn — không có thời gian chờ full regression suite chạy xong; explore có định hướng thủ công (dựa trên vùng code thay đổi) chạy song song với một tập smoke test tối thiểu.
Ngoài 3 trường hợp này, quy tắc mặc định vẫn là: scripted trước, explore sau.
Mẹo: Nếu bạn thấy team đang explore "vì đến giờ explore" chứ không dựa vào bất kỳ kết quả CI nào, đó là dấu hiệu loop đang chạy sai thứ tự — hãy kiểm tra lại pipeline trigger, không phải trách người test lười tìm bug.
Làm thế nào để dùng code-change context tự sinh charter theo rủi ro?
Charter truyền thống thường được viết tay bởi một tester dựa trên trực giác và kinh nghiệm — "tôi nghĩ khu vực checkout dễ có vấn đề, hôm nay explore ở đó." Cách này vẫn có giá trị, nhưng không có hệ thống và phụ thuộc hoàn toàn vào việc tester đó có nhớ hết mọi thay đổi code gần đây hay không (thường là không, đặc biệt với hệ thống lớn nhiều người cùng commit). Trong agentic loop, ta thay bước "đoán bằng trực giác" bằng bước "tổng hợp bằng AI từ 3 nguồn tín hiệu cụ thể", rồi vẫn giữ trực giác con người ở vai trò review/điều chỉnh charter cuối.
Prompt Sinh Charter với Code-Change Context
Một charter tốt cần 4 input được đưa vào cùng một prompt, không phải yêu cầu AI "tự nghĩ ra charter" chung chung:
- CODE CHANGE — diff thực tế (hoặc tóm tắt file/hàm bị đổi), đóng vai trò tín hiệu rủi ro chính. Đây là input quan trọng nhất — không có nó, charter sinh ra sẽ generic và không khác gì charter viết tay không có dữ liệu.
- TEST PLAN — cho AI biết phần nào đã được lên kế hoạch kiểm bằng scripted test, để charter không lặp lại đúng scope đó.
- CI EXECUTION RESULTS — kết quả thực tế của lần chạy gần nhất (pass/fail/flaky/skip), theo 3 loại tín hiệu đã nói ở phần trước.
- CHARTER GENERATION INSTRUCTIONS — quy tắc định dạng và giới hạn phạm vi charter (độ dài, số charter tối đa, mức độ ưu tiên).
ROLE: You are a senior exploratory test lead who designs risk-based
test charters for an experienced QA engineer to execute.
INPUTS:
CODE CHANGE (diff summary):
"""
- src/checkout/AddressForm.tsx: added debounced real-time validation
on the "postal code" field; validation now fires on every keystroke
after 300ms idle instead of on blur.
- src/checkout/api/validateAddress.ts: new API call added, replacing
the previous client-side-only regex check.
- No changes to shipping cost calculation logic.
"""
TEST PLAN (scope already scripted):
"""
- Unit tests: postal code regex format validation (valid/invalid formats)
- E2E: happy path checkout with valid address, submit and confirm order
- API test: validateAddress endpoint contract (200, 400, 500 responses)
"""
CI EXECUTION RESULTS (latest run):
"""
- All scripted tests above: PASS
- Note: E2E test only asserts final submitted state, does not assert
intermediate UI state during typing
- No flaky tests reported in this area
"""
CHARTER GENERATION INSTRUCTIONS:
1. Only generate charters for risk NOT already covered by the test plan
or explained away by a passing, meaningful test.
2. Prioritize charters that exploit the specific nature of the code
change (e.g., timing-based logic, new async dependency) — do not
generate generic "test the form" charters.
3. Each charter must state: title, risk hypothesis, starting point,
and 2-3 guiding questions (not scripted steps).
4. Output max 3 charters, ranked by risk, for a 90-minute session.
Điểm mấu chốt trong prompt này là instruction số 1 và số 2: buộc AI phải loại trừ vùng đã được scripted test cover có ý nghĩa, và bám vào đặc thù kỹ thuật của thay đổi (ở ví dụ trên là debounce 300ms và việc chuyển từ validate client-side sang gọi API — đây chính là 2 nguồn rủi ro mới mà AI cần nhận diện được từ diff, không phải từ mô tả nghiệp vụ chung).
Ví Dụ Charter Được Sinh Ra
Với input trên, một charter output hợp lý sẽ có dạng:
CHARTER EC-001: Address validation state during rapid form editing
RISK HYPOTHESIS: The new debounced (300ms) real-time validation call
to validateAddress() may produce inconsistent UI state when the user
types faster than the debounce window, edits the field again before
the previous validation call resolves, or navigates away mid-request.
The E2E test only checks final submitted state, so this race-condition
class of bug is currently invisible to automation.
STARTING POINT: Checkout > Address step, postal code field.
GUIDING QUESTIONS:
1. What happens if the user types a postal code, the debounce timer
fires, then the user edits the field again before the API responds?
Does the UI show a stale validation result?
2. What happens if the user submits the form while a validation
request is still in flight?
3. What happens if the API call times out or fails silently — does
the field fall back to any client-side check, or fail open/closed?
TIME BOX: 30 minutes.
Chú ý charter này không hề nói "hãy test field bắt buộc nhập" — điều đó đã được unit test cover. Nó tập trung thẳng vào race condition sinh ra từ chính thay đổi code, thứ mà chỉ có thể tìm bằng thao tác tay tinh vi (gõ nhanh, sửa giữa lúc chờ API, submit giữa lúc đang validate) — chính xác là loại việc automation khó viết và duy trì.
Điều Chỉnh Charter Cho Từng Loại Kiểm Thử
Charter sinh từ code-change context cần được tùy biến theo discipline (bộ môn kiểm thử) đang áp dụng, vì "rủi ro" mang nghĩa khác nhau ở mỗi discipline:
- Frontend/UI: nhấn vào race condition, trạng thái trung gian, khả năng tiếp cận (accessibility) của validation mới (ví dụ: screen reader có đọc lỗi real-time hay chỉ đọc khi submit?).
- API/Backend: nhấn vào idempotency khi client gọi lại API validate nhiều lần liên tiếp, rate-limit, và hành vi khi upstream service (ở đây là service validate địa chỉ) chậm hoặc lỗi.
- Mobile: thêm biến số về mạng chập chờn (network vừa mất vừa có lại giữa lúc debounce đang chờ), và hành vi khi app bị đưa vào background giữa lúc có request đang chạy.
- Performance: nếu debounce đặt sai (quá ngắn), mỗi keystroke có thể tạo một API call — charter nên hỏi "tần suất gọi API thực tế khi người dùng gõ liên tục là bao nhiêu, và server có giới hạn nào không?"
Prompt sinh charter nên thêm một dòng chỉ rõ discipline: "Generate this charter from the perspective of a {frontend|backend|mobile|performance} tester" — cùng một code diff nhưng charter sinh ra sẽ rất khác nhau về guiding questions.
Ví dụ cụ thể: với cùng diff ở trên, nếu bạn là backend/API tester, đừng chỉ gõ một dòng chung chung — thêm hẳn một block instruction riêng vào cuối prompt gốc (giữ nguyên 4 input CODE CHANGE/TEST PLAN/CI EXECUTION RESULTS ở phần trước, chỉ đổi phần CHARTER GENERATION INSTRUCTIONS):
CHARTER GENERATION INSTRUCTIONS (BACKEND/API FOCUS):
Generate charters strictly from a backend/API tester's perspective.
Do not generate any UI-focused charter.
1. Idempotency: what happens if validateAddress() is called multiple
times in rapid succession for the same input (client retry, double
keystroke firing two debounced calls before the first resolves)?
2. Ordering: if two validation requests are in flight and the second
one resolves before the first, does the UI/state end up applying
the stale (first) response on top of the newer one?
3. Rate limiting: the old client-side-only check never hit the network;
the new one fires on every 300ms-idle keystroke. Estimate realistic
call volume per user session and ask whether the endpoint has (or
needs) rate limiting.
4. Upstream failure handling: what exact status code, response body,
and timeout does validateAddress() return when the address service
is slow or down — does the client fail open (allow submit) or fail
closed (block submit)?
Output the same charter format as before (title, risk hypothesis,
starting point, 2-3 guiding questions), scoped only to backend/API risk.
Charter sinh ra từ bản instruction này sẽ hỏi thẳng vào idempotency và thứ tự resolve của request — thứ mà charter frontend ở ví dụ trước (EC-001) hoàn toàn không đề cập tới, dù xuất phát từ cùng một diff. Đây đúng là giá trị của việc tách discipline: không phải đổi văn phong charter, mà đổi hẳn loại rủi ro được soi.
Mẹo: Nếu diff của PR chỉ sửa 1 file nhỏ nhưng AI sinh ra 5-6 charter dài dòng, đó là dấu hiệu charter đang bị "làm đầy" bằng case chung chung — siết lại instruction "max charters" và yêu cầu AI giải thích rõ charter đó bám vào dòng code cụ thể nào trong diff.
Làm thế nào để đưa kết quả exploratory testing ngược lại test plan và bug pipeline?
Một exploratory session dù tìm ra nhiều insight quý, nếu insight đó chỉ nằm trong đầu tester hoặc trong một file note rời rạc, thì coi như mất giá trị sau vài ngày. Điểm khác biệt giữa exploratory testing "làm cho có" và exploratory testing agentic thực sự là: mọi quan sát trong session phải được ghi theo định dạng có thể máy đọc được ngay từ lúc ghi, để AI agent có thể tự động chuyển nó thành bug report, cập nhật test plan, và cập nhật coverage record — không cần con người soạn lại từ đầu.
Định Dạng Ghi Note Theo Thời Gian Thực
Việc ghi note tự do (kiểu "thấy hơi lag khi bấm nút X") gần như vô dụng cho bước xử lý tự động sau đó, vì AI không biết đây là bug, là quan sát để tham khảo, hay chỉ là ghi chú riêng của tester. Giải pháp là ép mọi observation vào một định dạng có nhãn (tag) rõ ràng ngay lúc ghi, trong session, không để tới cuối buổi mới tổng hợp lại (lúc đó trí nhớ đã phai và chi tiết quan trọng — bước tái hiện chính xác — dễ bị mất).
EXPLORATORY SESSION NOTES
Charter: EC-001 — Address validation state during rapid form editing
Tester: [name/agent]
Start: 14:05 End: 14:35
OBSERVATIONS:
OBS-001 [BUG-CANDIDATE]
Time: 14:09
Steps: Typed "700" in postal code, waited 1s, typed "000" quickly
before debounce fired, waited for validation.
Actual: Field shows green checkmark (valid) even though "700000"
is not a real postal code for the selected country.
Expected: Should show validation error for invalid postal code.
Evidence: screenshot-14-09.png, network log shows validateAddress
call fired with stale value "700" not final "700000".
Severity guess: Medium — silent data corruption risk on submit.
OBS-002 [OBSERVATION - NOT BUG]
Time: 14:14
Steps: Typed valid postal code, waited for green checkmark.
Actual: Checkmark takes ~450ms to appear after typing stops, feels
slightly slow but within acceptable UX range.
Note: Not filing as bug, but flag for perf discussion if debounce
value changes in future.
OBS-003 [BUG-CANDIDATE]
Time: 14:22
Steps: Entered valid postal code, immediately clicked "Continue"
button before validation checkmark appeared.
Actual: Form submitted successfully, order proceeded to next step,
with an unvalidated address.
Expected: Continue button should be disabled or should wait for
in-flight validation before allowing submission.
Evidence: video-14-22.mp4
SUMMARY:
2 bug candidates found, both related to the race condition hypothesis
in the charter (confirms risk hypothesis was correct). 1 observation
noted for later perf discussion. Charter risk hypothesis: CONFIRMED.
Time used: 30/30 minutes (on time-box).
Cấu trúc OBS-XXX [TAG] với các trường cố định (Steps, Actual, Expected, Evidence) là phần quan trọng nhất của định dạng này — nó biến một buổi explore tự do thành dữ liệu có cấu trúc ngay tại nguồn, không cần bước "diễn giải lại" sau đó dễ sai lệch.
Chuyển Session Notes Thành Bug Report
Từ file note trên, AI agent thực hiện 3 task tách biệt, không trộn vào một prompt duy nhất (trộn dễ khiến agent bỏ sót một trong ba):
Task 1 — Generate Bug Reports (chỉ với các OBS được tag [BUG-CANDIDATE]):
TASK: Convert each OBS entry tagged [BUG-CANDIDATE] below into a
formal bug report using this exact format. Do not process entries
tagged [OBSERVATION - NOT BUG].
BUG REPORT FORMAT:
- Title: concise, includes affected component
- Severity: [Critical/High/Medium/Low] with 1-line justification
- Preconditions:
- Steps to Reproduce: (numbered, atomic steps)
- Actual Result:
- Expected Result:
- Evidence: (reference the file/log named in the note)
- Found via: Exploratory session, Charter [charter ID]
- Linked risk hypothesis: (quote the charter's risk hypothesis this
bug confirms)
SESSION NOTES:
[paste session notes above]
Task 2 — Test Plan Updates: yêu cầu riêng để AI đề xuất case mới cần bổ sung vào test plan (không phải bug report, mà là gap coverage cần vá lâu dài):
TASK: Based on the confirmed bug candidates above, propose new
scripted test cases that should be added to the test plan to prevent
regression of this exact issue class. For each proposal, specify
whether it belongs in unit, integration, or E2E test layer, and why
existing tests in that layer did not already catch it.
Task 3 — Coverage Record Update: cập nhật lại coverage record (bản ghi theo dõi charter nào đã explore, kết quả ra sao) để phản ánh charter đã chạy, kết quả, và mức độ rủi ro đã được xác nhận hay bác bỏ — dữ liệu này nuôi lại vòng lặp charter-generation ở sprint sau:
TASK: Update the coverage record with this entry:
- Charter ID, area covered, risk hypothesis status (CONFIRMED/
PARTIALLY CONFIRMED/REFUTED), bugs found (IDs), time spent vs
time-boxed, and a note on whether this area needs re-exploration
next sprint or can be considered "explored, low residual risk"
for now.
Tách 3 task này ra vì mỗi task phục vụ một hệ thống đích khác nhau (bug tracker, test plan doc, coverage dashboard) và có định dạng khác nhau — gộp chung dễ khiến AI trộn lẫn nội dung, ví dụ nhồi đề xuất test case mới vào giữa bug report.
Tích Hợp Với Bug Pipeline
Bug report sinh ra ở Task 1 chỉ có giá trị thực khi nó vào đúng chỗ team đang làm việc — thường là Jira. Cách tích hợp phổ biến nhất là dùng jira-cli hoặc một script tùy biến nhỏ, nhận input là bug report theo format chuẩn ở trên và tạo ticket tự động:
jira issue create \
--project QA \
--type Bug \
--summary "$(jq -r '.title' bug_report.json)" \
--priority "$(jq -r '.severity' bug_report.json)" \
--description "$(jq -r '.description' bug_report.json)" \
--custom-field "found_via=Exploratory Session (Charter EC-001)" \
--label "ai-exploratory-testing"
Một số nguyên tắc khi nối pipeline này để tránh rác trong tracker:
- Luôn gắn label riêng (ví dụ
ai-exploratory-testing) cho ticket sinh từ nguồn này, để team dễ lọc và đánh giá lại chất lượng của cả pipeline theo thời gian, không lẫn với bug do người dùng report. - Không auto-create ticket thẳng vào backlog chính — tạo vào một "staging" filter/board trước, để lead QA duyệt nhanh trong ngày (chỉ cần xác nhận severity và loại trùng lặp), rồi mới chuyển sang sprint board. Auto-create không qua duyệt dễ gây tình trạng backlog bị spam bởi bug trùng hoặc severity đánh sai.
- Script adapter (chuyển từ format bug report của AI sang field của Jira) nên được version-hoá cùng codebase, không phải viết tay một lần rồi bỏ quên — khi format bug report thay đổi (ví dụ thêm field
Linked risk hypothesis), script cần cập nhật theo.
Mẹo: Đừng để AI tự quyết severity cuối cùng khi tạo ticket — luôn để AI đề xuất severity kèm lý do, và bắt buộc một người review nhấn "confirm" trước khi ticket lên sprint board thật; severity sai lệch do AI đoán quá tay là nguyên nhân phổ biến khiến backlog mất uy tín rất nhanh.
Làm thế nào để cân đối thời gian explore với ràng buộc sprint bằng AI?
Exploratory testing có một rủi ro cố hữu: nó không có "điểm kết thúc tự nhiên" như một test case scripted (chạy xong, pass/fail, done). Một session có thể kéo dài vô hạn nếu không time-box (giới hạn thời gian cứng cho mỗi session/charter) nghiêm túc, và nếu để mặc, nó dễ nuốt hết thời gian còn lại của sprint mà không ai nhận ra cho tới ngày cuối. Đưa AI vào không phải để "quyết định thay" QA lead, mà để tính toán và cảnh báo capacity theo thời gian thực — thứ con người dễ bỏ lỡ vì bận tập trung vào chính việc explore.
Tính Toán Sprint Capacity
Trước khi phân bổ charter, cần một phép tính capacity đơn giản nhưng thường bị bỏ qua: tổng giờ QA khả dụng trong sprint, trừ đi giờ đã cam kết cho scripted testing/regression, phần còn lại mới là ngân sách thực cho exploratory. AI hỗ trợ tốt nhất ở việc tổng hợp số liệu này từ nhiều nguồn (velocity sprint trước, số PR dự kiến, độ phức tạp code change) thay vì đoán một con số tròn "2 giờ/ngày" theo quán tính.
TASK: Calculate exploratory testing capacity for this sprint.
INPUTS:
- Sprint length: 10 working days
- QA engineers available: 2 (1 full-time, 1 at 50% due to on-call rotation)
- Scripted test maintenance + execution monitoring estimate: 6 hours/day total
- Number of PRs expected this sprint (based on last 3 sprints avg): 14
- High-risk PRs (touching payment, auth, or data migration): 3
INSTRUCTIONS:
1. Compute total available QA hours for the sprint.
2. Subtract committed scripted-testing hours.
3. Allocate remaining hours across generated charters, weighting
high-risk PRs 2x over standard PRs.
4. Output a capacity table: total hours, hours per charter, max
number of charters this sprint can realistically absorb.
Con số output từ prompt này không phải để "chốt cứng" ngay từ đầu sprint, mà là baseline để đối chiếu — nếu số charter mà charter-generation agent (ở phần trước) đề xuất vượt quá capacity này, bạn biết ngay cần cắt charter nào trước khi bắt đầu, thay vì để giữa sprint mới phát hiện quá tải.
Tái Ưu Tiên Động Giữa Sprint
Capacity tính đầu sprint luôn là ước lượng, thực tế giữa sprint gần như luôn lệch — có PR mới phát sinh, có bug nghiêm trọng cần hotfix, có người nghỉ ốm. AI hữu ích nhất ở đây không phải "dự đoán tương lai" mà là tổng hợp nhanh trạng thái thực tế và đề xuất điều chỉnh có căn cứ, để QA lead ra quyết định nhanh mà không cần tự cộng trừ số liệu bằng tay giữa lúc bận.
MID-SPRINT UPDATE (Day 6 of 10)
CURRENT STATE:
- Charters completed: 4/7 planned
- Hours used on exploratory: 9 of 12 budgeted
- New PR merged mid-sprint: 1 high-risk (payment retry logic change),
not in original charter plan
- 1 charter (EC-003, low-risk UI area) found zero bug candidates,
hypothesis REFUTED
TASK: Recommend how to reallocate the remaining 3 hours of
exploratory budget. Consider dropping/shortening low-yield charters
in favor of the new high-risk PR. Justify the recommendation with
the risk signals above, not just "we have time left."
Kết quả đề xuất thường là dạng "cắt bớt 30 phút của charter còn lại có risk thấp, dồn vào charter mới cho PR payment retry, vì PR đó chưa có bất kỳ signal nào được kiểm chứng." Đây chính là giá trị cốt lõi của việc dùng AI để prioritize giữa sprint: nó dựa trên dữ liệu tín hiệu đã thu thập (charter nào refuted, charter nào confirmed, PR nào mới xuất hiện), không dựa vào cảm giác "hình như còn nhiều thời gian".
Dùng Tín Hiệu Time-Box Trong Lúc Chạy Session
Time-box chỉ có tác dụng nếu có cơ chế nhắc và ghi nhận rõ ràng, không phải chỉ ghi "30 phút" trên charter rồi để tester tự giác. Một cách thực dụng là yêu cầu mỗi session kết thúc bằng một bản ghi hoàn tất charter (charter completion record) — vừa đóng vai trò tổng kết, vừa là input cho vòng tái ưu tiên tiếp theo.
CHARTER COMPLETION RECORD
Charter: EC-001
Time-boxed: 30 minutes | Actual time used: 30 minutes
Outcome: Risk hypothesis CONFIRMED — 2 bug candidates found
Stop reason: Time-box reached (not: ran out of ideas / found nothing)
Follow-up needed: YES — race condition class of bug found here may
exist in similar debounced-validation fields elsewhere; recommend
a follow-up charter next sprint scoped to those fields.
Charter efficiency signal: HIGH (bugs found per minute spent) —
prioritize similar charters (timing/race-condition focus) in future
risk-based generation.
Trường Charter efficiency signal ở cuối là phần hay bị bỏ qua nhất nhưng lại nuôi ngược lại chất lượng của charter-generation agent theo thời gian: nếu bạn ghi nhận đều đặn charter nào "hiệu suất cao" (tìm được nhiều bug/quan sát giá trị trong thời gian ngắn) và charter nào "hiệu suất thấp" (hết giờ mà không tìm được gì, hoặc tìm được nhưng severity thấp), sau vài sprint AI sẽ có dữ liệu thật để ưu tiên đúng loại rủi ro cho team cụ thể của bạn — không còn dựa thuần vào suy luận từ code diff mà không có phản hồi thực tế.
Mẹo: Đừng coi một charter "hết giờ mà không tìm ra bug" là thất bại — hãy ghi rõ "Stop reason: Time-box reached, hypothesis REFUTED" và dùng chính dữ liệu đó để agent tương lai học được rằng loại rủi ro này ở khu vực này ít giá trị, tránh lặp lại đúng charter đó ở các sprint sau khi không có thay đổi code mới liên quan.
Một vài cạm bẫy thường gặp khi triển khai bước exploratory testing agentic này trong thực tế:
- Explore mà không có code-change context — charter sinh ra generic, tester lãng phí thời gian dò những vùng rủi ro thấp trong khi vùng vừa đổi code lại bị bỏ qua. Luôn kiểm tra charter có trích dẫn cụ thể dòng code/hàm nào trong diff hay không; nếu không, charter đó chưa đủ chất lượng để chạy.
- Note session không map được sang bug report — ghi note kiểu văn xuôi tự do, thiếu trường Steps/Actual/Expected rõ ràng, khiến bước chuyển sang bug report phải "đoán lại" từ đầu, dễ sai lệch thông tin tái hiện lỗi. Ép định dạng
OBS-XXX [TAG]ngay từ lúc ghi, không để tới cuối session mới chuẩn hóa. - Bỏ qua sprint capacity, làm lệch cả sprint — vì exploratory testing "cảm giác" quan trọng và thú vị hơn việc bảo trì script, dễ bị cuốn theo một charter thú vị và vượt time-box nhiều lần, kéo lệch cả kế hoạch sprint. Time-box phải được tôn trọng như một hợp đồng cứng, ghi nhận rõ "Stop reason: Time-box reached" thay vì tự gia hạn không kiểm soát.
- Tạo ticket Jira tự động không qua duyệt — dẫn tới backlog bị spam bug trùng lặp hoặc severity sai, làm giảm uy tín của cả pipeline agentic trong mắt team. Luôn có bước duyệt của người trước khi ticket lên sprint board chính thức.
Nắm vững 4 phần trên — thứ tự trong loop, sinh charter theo rủi ro, feedback loop về bug/test plan, và cân đối capacity — chính là thứ biến exploratory testing từ "việc làm khi rảnh" thành một stage có kỷ luật, có dữ liệu, và có thể đo lường hiệu quả theo thời gian trong agentic QA workflow.