Đọc xong bốn bài trước, bạn đã hiểu AI agent là gì, agentic workflow khác gì automation truyền thống, và bộ công cụ nào đang có trên thị trường. Bài này chuyển sang phần thực chiến: cài đặt, cấu hình và kiểm chứng một môi trường QA có AI hỗ trợ thực sự chạy được — không phải demo, mà là thứ bạn dùng hàng ngày để phân tích coverage, sinh test case, và review code trong CI/CD pipeline (chuỗi tích hợp và triển khai liên tục).
Tôi sẽ dùng hai công cụ CLI (command-line interface — dòng lệnh) phổ biến nhất hiện nay là Claude Code và Gemini CLI làm ví dụ xuyên suốt, vì cả hai đều free-tier đủ dùng để một QA engineer tự trải nghiệm trước khi đề xuất mua license cho cả team.
Cách Cài Đặt và Cấu Hình Claude Code và Gemini cho Quy Trình QA
Trước khi đụng vào repo test thật, bạn cần một máy dev sạch, có Node.js đúng version, và đã đăng nhập đúng tài khoản. Phần này đi từng bước, từ zero đến có thể gõ prompt đầu tiên.
Điều Kiện Tiên Quyết
Cả Claude Code và Gemini CLI đều là ứng dụng Node.js, nên bạn cần:
- Node.js >= 18 (khuyến nghị 20 LTS trở lên). Dùng
nvm(Node Version Manager) để quản lý version, tránh xung đột với version Node mà project frontend/backend của công ty đang dùng:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm install 20
nvm use 20
node -v # should print v20.x.x
- Git đã cấu hình sẵn quyền truy cập vào repo test của team (SSH key hoặc HTTPS token).
- Terminal quen tay — iTerm2/Terminal trên macOS, hoặc Windows Terminal + WSL2 trên Windows. Cả hai CLI này chạy tốt nhất trên môi trường Unix-like, WSL2 gần như là bắt buộc nếu bạn dùng Windows.
- Một tài khoản có quyền dùng Claude (qua Claude.ai Pro/Max hoặc Anthropic Console API key) và/hoặc Google (Gemini, qua Google AI Studio API key hoặc Google Workspace).
Cài Đặt Claude Code
Claude Code cài qua npm (Node Package Manager) toàn cục:
npm install -g @anthropic-ai/claude-code
Kiểm tra cài đặt thành công:
claude --version
Đăng nhập lần đầu — chạy claude trong bất kỳ thư mục nào, CLI sẽ mở trình duyệt để bạn login bằng tài khoản Claude.ai (nếu bạn có subscription Pro/Max) hoặc dán API key (nếu dùng theo usage-based billing qua Anthropic Console):
claude
Sau khi login, thử một prompt smoke-test (kiểm tra khói — kiểm tra nhanh xem hệ thống có hoạt động cơ bản không) ngay trong repo test của bạn để chắc chắn CLI đọc được code:
Analyze the test files in this repo and tell me what testing framework is being used, how many test files exist, and what the general test file naming convention is.
Nếu Claude Code trả lời đúng framework (ví dụ "Đây là repo dùng Playwright với TypeScript, 42 file test, đặt tên theo pattern *.spec.ts"), coi như bước cài đặt đã xong.
Cài Đặt Gemini CLI
Tương tự, Gemini CLI của Google cũng cài qua npm:
npm install -g @google/gemini-cli
Kiểm tra:
gemini --version
Chạy lần đầu để đăng nhập — Gemini CLI hỗ trợ login bằng tài khoản Google cá nhân (free tier có giới hạn request/phút) hoặc API key từ Google AI Studio:
gemini
Nếu muốn dùng API key thay vì login tương tác (hữu ích khi bạn test trên máy không có GUI, hoặc chuẩn bị sẵn cho bước CI ở phần sau), set biến môi trường (environment variable):
export GEMINI_API_KEY="your-api-key-here"
Prompt smoke-test tương đương cho Gemini:
List all test suites in this repository grouped by feature area, and flag any test file that has not been modified in the last 6 months.
Cấu Hình Model Mặc Định
Cả hai CLI cho phép set model mặc định để không phải gõ flag --model mỗi lần. Với Claude Code, dùng lệnh /model trong session hoặc set qua file config:
/model claude-opus-4-6
Hoặc cấu hình vĩnh viễn trong ~/.claude/settings.json:
{
"model": "claude-sonnet-5",
"permissions": {
"allow": ["Bash(npm test:*)", "Bash(npm run test:*)"]
}
}
Lời khuyên thực tế: dùng model mạnh nhất (Opus-tier) cho task phân tích coverage gap hoặc thiết kế test strategy — vì đây là task cần suy luận sâu; dùng model nhanh/rẻ hơn (Sonnet/Haiku-tier hoặc Gemini Flash) cho task lặp lại như sinh boilerplate test case hoặc format lại bug report.
Với Gemini CLI, model mặc định set trong ~/.gemini/settings.json:
{
"model": "gemini-2.5-pro"
}
Mẹo: Đừng cài CLI bằng sudo npm install -g nếu tránh được — nó gây lỗi quyền truy cập (permission) khó chịu khi CLI tự update sau này. Thay vào đó dùng nvm để Node và các package toàn cục nằm trong home directory của bạn, không cần sudo cho bất kỳ lệnh npm nào.
Cách Kết Nối Công Cụ AI với Test Repository và CI/CD Pipeline
Cài xong trên máy cá nhân chỉ là bước một. Giá trị thật của agentic QA nằm ở việc AI chạy được ngay trong pipeline — review pull request tự động, chặn merge khi coverage gap quá lớn, sinh báo cáo bug ngay khi test fail trên CI.
Kết Nối Với Test Repository
Trước khi đưa vào CI, hãy chạy CLI ngay tại root của test repo trên máy local để AI "nhìn thấy" toàn bộ cấu trúc project. Claude Code và Gemini CLI đều tự động đọc file trong working directory hiện tại — không cần "connect" theo nghĩa API riêng, miễn là bạn cd vào đúng thư mục:
cd ~/projects/ecommerce-test-suite
claude
Với monorepo có nhiều package test (ví dụ apps/web-e2e, apps/api-tests, apps/mobile-e2e), nên chạy CLI từ subfolder cụ thể để tránh AI phải quét toàn bộ monorepo (tốn context window — vùng nhớ ngữ cảnh mà model dùng để "nhớ" nội dung bạn đưa vào — và chậm hơn):
cd ~/projects/monorepo/apps/api-tests
claude
Thêm Vào GitHub Actions
Đây là bước biến AI QA assistant thành một phần của quy trình review chính thức. Ví dụ workflow chạy Claude Code để review coverage của mỗi pull request:
name: AI QA Coverage Review
on:
pull_request:
branches: [main, develop]
jobs:
ai-coverage-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run coverage gap analysis
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "Compare the diff of this PR against main branch. \
List every changed function that has no corresponding test case. \
Output as a markdown table with columns: File, Function, Risk Level." \
--output-format text > coverage-report.md
- name: Post report as PR comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('coverage-report.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## AI Coverage Gap Report\n\n${report}`
});
Thêm Vào GitLab CI
Nếu team dùng GitLab, logic tương tự viết trong .gitlab-ci.yml:
stages:
- ai-qa-review
ai-coverage-review:
stage: ai-qa-review
image: node:20-alpine
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- npm install -g @anthropic-ai/claude-code
- >
claude -p "Review the merge request diff. Identify changed API endpoints
that lack integration test coverage. Output a risk-ordered list."
--output-format text > coverage-report.txt
- cat coverage-report.txt
artifacts:
paths:
- coverage-report.txt
expire_in: 7 days
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
Muốn kết quả tự động post lên merge request thay vì chỉ nằm trong artifact, dùng thêm GitLab API (curl với PRIVATE-TOKEN) trong một step riêng, hoặc dùng job template có sẵn nếu team đã có bot account cho việc này.
Quản Lý API Key Trong CI
Đây là phần dễ làm sai nhất khi mới setup. Nguyên tắc cứng:
- Không bao giờ hardcode API key vào file YAML hoặc commit vào repo.
- Lưu key trong CI/CD secrets — với GitHub là
Settings → Secrets and variables → Actions, với GitLab làSettings → CI/CD → Variables(nhớ tick "Masked" và "Protected"). - Dùng API key riêng cho CI, khác với key bạn dùng trên máy cá nhân — để khi cần revoke (do leak hoặc do rate limit bất thường) không ảnh hưởng đến việc dùng hàng ngày.
- Set budget/spend limit trên Anthropic Console hoặc Google AI Studio cho key dùng trong CI, tránh trường hợp một vòng lặp lỗi (ví dụ retry vô hạn) đốt hết quota trong một đêm.
gh secret set ANTHROPIC_API_KEY --body "sk-ant-xxxxxxxxxxxx"
Mẹo: Tạo hẳn một API key riêng tên ci-qa-review-readonly với budget alert ở mức thấp (ví dụ $20/tháng) để nhận cảnh báo sớm nếu một job nào đó chạy loop bất thường và gọi API liên tục — kinh nghiệm thực tế là lỗi cấu hình on: pull_request chạy lại vô hạn do trigger nhầm push tag đã khiến không ít team "cháy" quota chỉ trong một buổi sáng.
Cách Thiết Lập Prompt Files, Context Files và Workspace Configuration
Nếu bỏ qua bước này, AI của bạn sẽ "đoán" convention của project mỗi lần — kết quả không nhất quán, lúc thì sinh test bằng Jest, lúc lại đề xuất Mocha dù project không hề dùng. File context (ngữ cảnh) chính là cách bạn "dạy" AI hiểu project của mình một lần, dùng lại mãi.
File CLAUDE.md
CLAUDE.md là file markdown đặt tại root repo (hoặc root từng package trong monorepo), được Claude Code tự động đọc vào context mỗi khi khởi động trong thư mục đó. Gemini CLI có cơ chế tương đương gọi là GEMINI.md. Đây là ví dụ thực tế cho một test repo e-commerce:
## Test Stack
- Framework: Playwright v1.48 with TypeScript
- API testing: Supertest + Jest for backend contract tests
- Test runner: `npx playwright test` for E2E, `npm run test:api` for API suite
- Reporting: Allure report, published to `reports/allure/`
- CI: GitHub Actions, workflow file at `.github/workflows/e2e.yml`
## Test File Locations
- E2E specs: `tests/e2e/**/*.spec.ts`, one file per user flow (e.g. `checkout.spec.ts`)
- API specs: `tests/api/**/*.test.ts`, grouped by resource (e.g. `orders.test.ts`)
- Page Objects: `tests/e2e/pages/*.page.ts`
- Test data fixtures: `tests/fixtures/*.json` — never hardcode test data inline in spec files
- Shared test utils: `tests/utils/`
## Test Conventions
- Test titles follow `should <expected behavior> when <condition>` pattern
- Use `test.step()` to break long E2E flows into readable sub-steps
- Every new API endpoint test must cover: happy path, validation error (400), auth error (401/403), not-found (404)
- Selectors: prefer `data-testid` attributes, never rely on CSS class names or XPath
- No `sleep()` / hardcoded `waitForTimeout()` — use Playwright's built-in auto-waiting or explicit `waitFor` conditions
## Domain Context
- This is an e-commerce platform. Key entities: Order, Cart, Product, Customer, Payment.
- Checkout flow has 3 steps: cart review → shipping/payment → confirmation.
- Payment integration uses Stripe in test mode; test card numbers are in `tests/fixtures/stripe-test-cards.json`.
- Orders below $50 don't require address verification; orders above do (business rule as of 2026-Q1).
## What NOT to Generate
- Do not generate tests that call the production payment gateway — always use the Stripe test/sandbox keys.
- Do not suggest visual regression tests — the team uses a separate tool (Percy) for that, out of scope here.
- Do not modify files under `tests/fixtures/` without flagging the change explicitly — fixtures are shared across 40+ tests.
- Do not remove existing `test.skip()` blocks without asking — some are intentionally skipped pending a backend fix (tracked in JIRA).
Giữ file này ngắn và cập nhật quan trọng hơn viết dài. Một CLAUDE.md 500 dòng, nửa năm không update, còn tệ hơn không có — vì AI sẽ áp dụng convention đã lỗi thời.
Slash Commands Cho Các Tác Vụ QA Lặp Lại
Slash command (lệnh bắt đầu bằng /) là prompt template được lưu sẵn thành file, gọi lại bằng một dòng lệnh ngắn thay vì gõ lại toàn bộ hướng dẫn mỗi lần. Với Claude Code, đặt file .md trong .claude/commands/.
Ví dụ command sinh coverage report, lưu tại .claude/commands/coverage-report.md:
---
description: Generate a risk-ordered coverage gap report for a given diff or PR
---
Analyze the current git diff (or the PR number passed as $ARGUMENTS) and produce a report with these sections:
## Changed Files
List every file modified in this diff, grouped by module.
## Existing Test Coverage
For each changed file, state whether a corresponding test file exists and was also modified.
## Coverage Gaps (Risk-Ordered)
List changed logic with NO test coverage, ordered from highest to lowest risk.
Risk = likelihood of breaking production behavior x blast radius (how many features depend on it).
## Draft Test Cases for Top Gaps
For the top 3 highest-risk gaps, draft a concrete test case in Gherkin-style
(Given/When/Then), specific enough that a QA engineer could implement it directly
using the project's existing test stack (see CLAUDE.md).
Gọi command này bằng:
/coverage-report PR-482
Ví dụ thứ hai — template chuẩn hóa bug report, lưu tại .claude/commands/bug-report.md:
---
description: Turn a raw failure log or manual observation into a standardized bug report
---
Given the failure information provided in $ARGUMENTS (log output, stack trace, or manual description),
produce a bug report with exactly these sections:
## Summary
One sentence describing the bug.
## Environment
Browser/OS/API version/environment (staging, production, etc.) — infer from logs if possible,
otherwise mark as "NEEDS CONFIRMATION".
## Steps to Reproduce
Numbered, minimal steps required to trigger the bug.
## Expected Behavior
What should have happened, based on the acceptance criteria or documented business rule.
## Actual Behavior
What actually happened, quoting the exact error message or observed output.
## Evidence
Reference the specific log lines, screenshot filename, or stack trace snippet provided.
## Root Cause Hypothesis
Your best technical guess at the root cause, based on the stack trace and codebase context.
Mark confidence as High / Medium / Low.
## Suggested Fix Direction
A concrete suggestion for where to start investigating (file, function, or recent commit),
NOT a full fix — this report is for triage, not for auto-fixing.
Gọi bằng cách paste log lỗi trực tiếp:
/bug-report "TypeError: Cannot read properties of undefined (reading 'total') at CartSummary.tsx:42, occurred during checkout_flow.spec.ts run on staging"
Context Files Cho Các Tác Vụ Cụ Thể
Ngoài CLAUDE.md áp dụng toàn repo, bạn có thể tạo context file cho một khu vực nghiệp vụ cụ thể — hữu ích khi domain phức tạp, nhiều rule nghiệp vụ mà không phải AI session nào cũng cần đọc hết. Ví dụ tests/payment/PAYMENT_CONTEXT.md:
- Supported payment methods: Credit Card (Stripe), PayPal, Momo (Vietnam-only), bank transfer.
- Momo integration only active for orders with `shipping_country = "VN"`.
- Refund SLA: full refund must complete within 5-7 business days; partial refund tests
must assert against the `refund_status = "pending"` intermediate state, not just final state.
- Known flaky area: PayPal sandbox redirect sometimes times out in CI — retry logic is in
`tests/utils/retry-paypal-redirect.ts`, don't remove it even if it looks unnecessary.
Trong Claude Code, nạp file này vào context của session hiện tại bằng:
Read tests/payment/PAYMENT_CONTEXT.md and tests/payment/checkout-payment.spec.ts,
then suggest test cases for the new "save card for later" feature described in JIRA-2291.
Mẹo: Đừng nhồi tất cả context vào một file CLAUDE.md khổng lồ. Tách theo domain (payment, auth, inventory...) và chỉ nạp file liên quan vào từng session — vừa tiết kiệm context window, vừa giảm rủi ro AI trộn lẫn rule của module này sang module khác khi trả lời.
Cách Kiểm Tra Môi Trường AI QA Với Một Tác Vụ Thực Tế Đầu Tiên
Cài xong, cấu hình xong, nhưng đừng vội báo cáo "đã setup xong" cho team lead. Chạy ba tác vụ kiểm chứng (validation task) sau để chắc chắn môi trường hoạt động đúng trên dữ liệu thật của project bạn, không chỉ trên ví dụ mẫu.
Tác Vụ Kiểm Tra 1: Phân Tích Coverage Gap
Chọn một pull request đã merge gần đây (biết trước phần nào có test, phần nào thiếu, để tự đối chiếu kết quả). Chạy:
Look at the last 5 merged pull requests in this repo (use git log to find them).
For each PR, identify whether the changed source files have corresponding
test file changes. List any PR where source code changed but no test file
was touched, and explain what risk that introduces.
Kết quả mong đợi: AI liệt kê đúng các PR bạn đã biết là thiếu test, giải thích risk hợp lý (ví dụ "PR #475 sửa logic tính discount nhưng không có test mới — rủi ro tính sai giá khi áp nhiều voucher cùng lúc"). Nếu AI bỏ sót PR rõ ràng thiếu test, hoặc bịa ra file không tồn tại, đó là dấu hiệu context chưa đủ hoặc repo quá lớn cần chia nhỏ working directory.
Tác Vụ Kiểm Tra 2: Sinh Test Case Từ User Story Thực Tế
Lấy một user story/JIRA ticket thật, càng cụ thể càng tốt về business rule:
Here is a user story:
"As a customer, I want to apply a discount code at checkout so that I pay less,
but only one discount code can be active per order, and codes cannot be combined
with the 'first order' promotion."
Generate test cases covering positive, negative, and edge cases for this story.
Format each test case as: Title / Preconditions / Steps / Expected Result.
Use the existing test conventions defined in CLAUDE.md.
Kết quả mong đợi: test case bao gồm cả case "áp 2 code cùng lúc bị chặn", "áp code khi đã có promotion first-order", không chỉ happy path — và format đúng convention bạn đã định nghĩa trong CLAUDE.md. Nếu AI chỉ sinh 3 happy-path case chung chung, thử viết lại prompt yêu cầu rõ "cover edge cases and business rule conflicts explicitly".
Tác Vụ Kiểm Tra 3: Kiểm Tra Tích Hợp CI
Tạo một pull request test (nhánh nhỏ, thay đổi vô hại, ví dụ sửa 1 dòng comment trong file source) để trigger workflow AI QA review vừa thêm ở phần trước:
git checkout -b test/verify-ai-ci-setup
echo "// trigger AI review workflow" >> src/checkout/discount.ts
git add src/checkout/discount.ts
git commit -m "test: verify AI QA CI integration"
git push origin test/verify-ai-ci-setup
Mở pull request, quan sát tab "Actions" (GitHub) hoặc "CI/CD → Pipelines" (GitLab). Kết quả mong đợi: job ai-coverage-review chạy xanh (pass), và comment được bot post lên PR trong vòng 1-3 phút. Nếu job đỏ (fail), xem log chi tiết ở phần troubleshooting ngay dưới đây.
Xử Lý Các Vấn Đề Thường Gặp Khi Setup
| Vấn đề | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
Error: authentication failed khi chạy claude local |
Session login hết hạn, hoặc máy không mở được browser (SSH vào server headless) | Chạy lại claude để re-login qua browser; với máy headless, dùng API key thay vì login tương tác: export ANTHROPIC_API_KEY=... |
CI job fail với ANTHROPIC_API_KEY is not set |
Secret chưa add vào repo, hoặc add nhầm ở level Organization mà job không có quyền truy cập, hoặc tên biến sai chính tả | Kiểm tra lại tên biến chính xác (case-sensitive), xác nhận secret được add đúng scope (repo/environment), và job có env: trỏ đúng tên |
429 Too Many Requests / rate limit khi chạy nhiều job CI song song |
Nhiều PR trigger cùng lúc, hoặc free-tier API key có giới hạn request/phút thấp | Thêm concurrency group trong GitHub Actions để hủy job cũ khi có push mới; nâng tier API key nếu team scale lớn |
| AI trả lời sai file, hoặc nói "file không tồn tại" dù bạn biết nó có | Context window bị vượt do repo quá lớn, hoặc bạn chạy CLI từ thư mục gốc monorepo thay vì subfolder đúng | cd vào đúng package/subfolder trước khi chạy; dùng .claude/settings.json để giới hạn scan qua ignorePatterns cho các thư mục không liên quan (node_modules, dist, coverage) |
| Kết quả sinh test case không đúng convention project | CLAUDE.md chưa có, quá cũ, hoặc AI không đọc được do sai vị trí file |
Xác nhận CLAUDE.md nằm ở đúng root của working directory bạn đang chạy CLI; test bằng cách hỏi trực tiếp "What test framework does this project use according to your context?" |
| Slash command không hoạt động | File command đặt sai thư mục, hoặc thiếu frontmatter description |
Kiểm tra file nằm đúng .claude/commands/<name>.md, restart session sau khi thêm file mới |
Môi Trường Của Bạn Đã Sẵn Sàng Khi:
- [ ]
claude --versionvà/hoặcgemini --versionchạy được không lỗi, đã login thành công. - [ ] Prompt smoke-test đọc đúng framework, số lượng file test, và convention đặt tên của repo thật của bạn.
- [ ] File
CLAUDE.md(hoặcGEMINI.md) tồn tại ở root repo, có đủ 5 phần: Test Stack, Test File Locations, Test Conventions, Domain Context, What NOT to Generate — và nội dung phản ánh đúng project hiện tại, không phải nội dung mẫu. - [ ] Ít nhất 2 slash command (ví dụ coverage-report, bug-report) đã tạo và gọi thử thành công.
- [ ] Workflow AI QA review đã thêm vào CI (GitHub Actions hoặc GitLab CI), và đã chạy pass ít nhất một lần trên PR thử nghiệm thật.
- [ ] API key dùng trong CI là key riêng, lưu trong secrets, có budget alert, không xuất hiện ở đâu trong code hoặc log.
- [ ] Cả 3 tác vụ kiểm tra (coverage gap, sinh test case từ user story, CI integration) đều cho kết quả đúng và hữu ích trên dữ liệu thật của project bạn — không phải trên ví dụ demo.
Khi tất cả các ô trên đều tick được, bạn đã có một môi trường AI QA thực chiến — sẵn sàng để bước sang các module tiếp theo, nơi chúng ta đi sâu vào từng loại tác vụ QA cụ thể mà agent có thể đảm nhiệm.
Mẹo: Đừng chạy 3 tác vụ kiểm tra này chỉ một lần ngay sau khi cài đặt rồi coi như xong. Lặp lại đúng 3 tác vụ đó sau 3-5 ngày, trên một PR/user story khác — vì lần chạy đầu thường "đẹp" do bạn vừa cd đúng thư mục và context còn mới, còn kết quả những lần sau mới phản ánh đúng việc CLAUDE.md có bị lỗi thời, quota API có đủ, hay working directory có bị set nhầm khi chuyển qua project khác. Sự khác biệt giữa hai lần chạy đó chính là thước đo thật về việc môi trường của bạn có ổn định hay chỉ "ăn may" ở lần đầu.