TDD + Vertical Slicing với AI — cách build feature production trong 1-2 ngày

TDD (Test-Driven Development — viết test trước rồi code) + Vertical Slicing (cắt feature mỏng từ UI xuống DB) là combo mạnh nhất cho AI Coding 2026. Mỗi slice = 1 vòng Red-Green-Refactor = AI gen 1 phần nhỏ pass test. Khác vibe coding (no test) và spec-driven (spec rồi gen full). Bài này dạy workflow 5 bước, ví dụ 6 slice cho feature đặt hàng, 5 cảm bẫy.

13 phút đọcCập nhật 2026-05-19
Đang tải audio...
Mục lục bài viết(28)
TDD Red-Green-Refactor cycle + Vertical Slicing — cắt feature end-to-end mỏng

TDD + Vertical Slicing với AI: bánh cake = feature đầy đủ (UI + API + DB), bạn cắt thành slice dọc mỏng — mỗi slice end-to-end deploy được. Mỗi slice chạy 1 vòng Red → Green → Refactor: viết test fail → AI gen code pass → AI cleanup. Combo này = AI quality cao + velocity cao. Ảnh: AI-generated bằng ChatGPT gpt-image-2.

Hiểu đơn giản nhất

Bạn có bánh cake 5 lớp (kem, mứt, bánh xốp, mousse, cốt) — đại diện feature đầy đủ với 5 tầng (UI, validation, business logic, API, database).

Cách SAI (horizontal): ăn từ trên xuống — ăn hết kem rồi mới ăn mứt rồi mới ăn bánh xốp. Đến lớp 4 đã ngán, lớp 5 không động đến. = build hết DB trước rồi API rồi UI = user chỉ thấy lớp UI sau 3 tháng.

Cách ĐÚNG (vertical slicing): cắt 1 SLICE DỌC mỏng — bạn ăn được CẢ 5 LỚP trong 1 miếng. Slice tiếp theo cũng đủ 5 lớp. Mỗi slice = 1 user story end-to-end deploy được.

TDD thêm vào: trước khi cắt slice, viết test mô tả slice phải đạt gì → cắt slice → kiểm tra test pass. AI 2026 gen code theo test = code chuẩn, không hallucination.

TDD là gì? Định nghĩa + lịch sử

TDD (Test-Driven Development — phát triển theo test) = phương pháp viết test trước, code sau. Kent Beck (creator Extreme Programming, JUnit, ngày nay ở Anthropic) xuất bản sách "Test-Driven Development: By Example" năm 2003.

Cycle 3 bước:

  • RED — viết 1 test mô tả behavior mong muốn → chạy test → FAIL (vì code chưa có)
  • GREEN — viết code TỐI THIỂU để test pass → chạy test → PASS
  • REFACTOR — cleanup code (đặt tên, extract function, remove duplication) — chạy test vẫn pass

Lặp cycle này cho từng behavior nhỏ. Kết quả: code có 100% test coverage, design tốt (test-friendly = loose coupling), tự tin refactor.

Tại sao 2003 không bùng nổ? Kent Beck đưa TDD năm 2003, nhưng dev coi là "chậm" vì:

  • Viết test = mất 40-60% thời gian build
  • Junior khó write test trước (chưa biết design)
  • Tool chậm (Junit chạy 30s mỗi suite)

Tại sao 2026 bùng nổ? AI thay đổi game:

  • AI viết test trong 30 giây từ behavior description
  • AI gen code pass test trong 1-2 phút
  • Vitest chạy dưới 2s mỗi suite (Vite-powered)
  • TDD overhead từ 40-60% → 15-25%

Ví dụ thực tế: Anthropic 2026 có 80% codebase covered bằng TDD. Kent Beck (ở Anthropic) nhiều lần public nói: "AI làm TDD trở lại mainstream sau 23 năm". Tại VN, từ 2024 Shopee VN engineering blog confirm shift sang TDD cho mọi feature payment + checkout (golden path zero-bug).

Red-Green-Refactor — ví dụ cụ thể

Feature mini: validate email format.

RED — Test fail

// email.test.ts
import { isValidEmail } from './email';
 
describe('isValidEmail', () => {
  it('returns true for valid email', () => {
    expect(isValidEmail('[email protected]')).toBe(true);
  });
 
  it('returns false for missing @', () => {
    expect(isValidEmail('user.vietcodex.com')).toBe(false);
  });
 
  it('returns false for empty string', () => {
    expect(isValidEmail('')).toBe(false);
  });
});
$ pnpm test email.test.ts
 Cannot find module './email' (failed to import)

Test fail. RED. ✓

GREEN — Code tối thiểu pass

Prompt cho Claude:

Tạo file email.ts với function isValidEmail(email: string): boolean.
Make all tests in email.test.ts pass. Don't over-engineer.

AI gen:

// email.ts
export function isValidEmail(email: string): boolean {
  if (!email) return false;
  return /^[^@]+@[^@]+\.[^@]+$/.test(email);
}
$ pnpm test email.test.ts
 returns true for valid email
 returns false for missing @
 returns false for empty string

Test pass. GREEN. ✓

REFACTOR — Cleanup

Prompt:

Refactor email.ts: (1) extract regex thành constant với comment giải thích, (2) thêm JSDoc cho function. Đảm bảo test vẫn pass.

AI gen:

// email.ts
// RFC 5322 simplified: [email protected]
const EMAIL_REGEX = /^[^@]+@[^@]+\.[^@]+$/;
 
/**
 * Check if string is a valid email format.
 * Note: only structural check, NOT verify deliverability.
 */
export function isValidEmail(email: string): boolean {
  if (!email) return false;
  return EMAIL_REGEX.test(email);
}
$ pnpm test email.test.ts
 (3 pass)

REFACTOR done. Code clean, test still pass.

→ Lặp cycle cho behavior tiếp theo (vd: case-insensitive, max length, internationalized domains).

Vertical Slicing — Bill Wake INVEST

Bill Wake (XP coach, ex-IBM) năm 2003 đặt tên INVEST — 6 tiêu chí cho slice tốt:

  • Independent — slice không phụ thuộc slice khác
  • Negotiable — có thể đàm phán scope
  • Valuable — user thấy giá trị end-to-end
  • Estimable — đoán được thời gian
  • Small — 1-2 ngày dev
  • Testable — test acceptance criteria được

So sánh Horizontal vs Vertical:

So sánh Horizontal Layering vs Vertical Slicing — Big Bang Risk vs Continuous Value

Horizontal Layering xây hết tầng UI → API → DB rồi mới wire — user không thấy gì đến tháng 3. Vertical Slicing cắt slice end-to-end mỏng, mỗi slice deploy được sau 1-2 ngày — user thấy progress liên tục, feedback sớm, pivot rẻ. Ảnh: AI-generated bằng ChatGPT gpt-image-2.

Tiêu chíHorizontal (xếp lớp)Vertical (cắt dọc)
Phương phápBuild DB → API → UI tuần tựBuild slice end-to-end
Thấy giá trịCuối cùng (sau 3 tháng)Mỗi slice (1-2 ngày)
User feedbackLate + riskyEarly + iterative
DeployBig bang 1 lầnContinuous (mỗi slice)
RiskCao (3 tháng đầu tư)Thấp (mỗi slice 1-2 ngày)
Skill yêu cầuDB-first thinkingEnd-to-end thinking
Phù hợpHệ thống cũ migrationFeature mới, MVP, AI Coding

Ví dụ thực tế: Project booking salon VietCodex (xem spec-driven-dev case study) áp dụng vertical slicing — 8 feature cắt thành 32 slice nhỏ. Slice 1 deploy ngày 3, slice 32 deploy ngày 19. Client thấy progress mỗi tuần, request adjust 4 slice midway → không phá kế hoạch. Horizontal sẽ phải redesign từ đầu.

Workflow TDD + Slicing với AI — 5 bước

Bước 1: Slice feature

Bạn nhìn feature lớn (vd: "User đặt hàng và thanh toán"), cắt thành slice INVEST. Có thể dùng AI hỗ trợ:

Tôi muốn build feature: User đặt hàng + thanh toán VNPay.
Stack: Next.js + Drizzle + Postgres + VNPay sandbox.
Cắt thành vertical slice theo INVEST. Liệt kê 5-8 slice, mỗi slice 1-2 ngày dev.

AI output 6 slice (xem section sau).

Bước 2: Viết test cho slice 1

Bạn pick slice 1 nhỏ nhất. Tả behavior:

Slice 1: User xem product detail.
- GET /product/[id] return 200 + tên + giá + ảnh
- Product không tồn tại return 404
- ID không valid format (không phải số) return 400

Gen Playwright test cho 3 case này.

AI gen tests/product-detail.spec.ts. Bạn review (10 giây).

Bước 3: Run test → RED

pnpm test:e2e product-detail.spec.ts

Test fail (chưa có endpoint). RED. ✓

Bước 4: AI gen code → GREEN

Make these 3 tests pass. Stack: Next.js App Router + Drizzle.
Create: app/product/[id]/page.tsx + lib/products/get-by-id.ts.
Don't over-engineer.

AI gen 2 files. Run test:

pnpm test:e2e product-detail.spec.ts
 returns 200 with product
 returns 404 if not exist
 returns 400 if invalid id

GREEN. ✓

Bước 5: Refactor + ship slice

Refactor cả 2 files: (1) extract error response thành helper, (2) thêm JSDoc, (3) cleanup. Tests must still pass.

AI refactor. Test pass. Commit + deploy preview.

→ Quay lại Bước 2 cho slice 2.

Velocity: 1 slice = 1-3 giờ với AI 2026. 1 ngày = 3-5 slice = 1/2 feature production-ready.

Ví dụ 6 slice cho feature đặt hàng

Feature: "User đặt hàng và thanh toán VNPay".

#SliceTest acceptanceNgày
1View product detail (/product/[id])200 + product info, 404 if missing1
2Add to cart (LocalStorage)Click "Thêm vào giỏ" → cart count +11
3View cart (/cart)List items, update qty, remove, sum total2
4Checkout form (/checkout)Name + phone + address → POST /api/orders → return orderId2
5VNPay redirect + IPNRedirect to VNPay sandbox → return → IPN callback update order status3
6Order success page (/order/[id])Show order detail, status PAID after IPN1

Tổng 10 ngày từ slice 1 đến slice 6 hoàn chỉnh. Mỗi slice deploy preview, owner test trên Vercel preview URL.

Insight quan trọng: Slice 5 (thanh toán) phức tạp nhất, nhưng KHÔNG phải đầu tiên — bạn validate UX trước với slice 1-4 (LocalStorage cart). Nếu user feedback "không cần cart, mua nhanh 1-click" → có thể skip slice 2-3, đi thẳng slice 4. Vertical slicing cho phép pivot.

So sánh Vibe / Spec-driven / TDD-slicing

Tiêu chíVibe codingSpec-drivenTDD + Slicing
Bắt đầuPrompt tự doViết specCắt slice + viết test
TestManual cuốiAC từ specTest trước code
IterationPrompt-error-fixPlan trước, gen fullMỗi slice 1 cycle
QualityTrung bìnhCaoCao nhất
Velocity (build)Nhanh nhấtTrung bìnhTrung bình
Velocity (maintain)Chậm nhấtNhanhNhanh nhất
Test coverage0-30%50-80%90-100%
Refactor confidenceThấpTrung bìnhCao nhất
Phù hợpMVP, prototypeProduction teamProduction critical (payment, auth)
Skill yêu cầuThấpTrung bìnhCao (biết viết test)

Tools 2026 cho TDD + Slicing

Test frameworks

  • Vitest — unit + integration test, Vite-powered, chạy dưới 2s. Default cho Next.js 2026.
  • Playwright — E2E browser test. Codegen tự động từ click thật.
  • MSW (Mock Service Worker) — mock HTTP request realistic, dùng cùng app code.

AI integrations

  • Claude Code/test slash command sinh test từ behavior description
  • Cursor — Cmd+K → "write tests for this function" trong file context
  • GitHub Copilot — autocomplete test cases khi đặt tên test rõ ràng

CI/CD

  • GitHub Actions — run test mỗi PR
  • Vercel Preview — deploy preview mỗi slice
  • Codecov / Codacy — report coverage % mỗi commit

5 cảm bẫy phổ biến

Bẫy 1: Slice quá mỏng (Sliver)

❌ Slice "thêm column phone vào table users" — chỉ DB layer, user không thấy gì. ✅ Slice "user nhập SĐT khi checkout, lưu DB, gửi SMS xác nhận" — end-to-end.

Mitigation: Mỗi slice phải có user-visible value. Nếu user không thấy gì → ghép vào slice khác.

Bẫy 2: Slice quá dày (Epic)

❌ Slice "toàn bộ feature thanh toán" — 5 ngày dev, blocker cho 5 slice khác. ✅ Cắt thành 3 slice: redirect → IPN callback → success page.

Mitigation: Slice dưới 2 ngày dev. Nếu trên 2 ngày → cắt nhỏ.

Bẫy 3: Mock thay vì DB thật

❌ Test với mock Postgres — pass nhưng prod fail (mock không match thật). ✅ Test với Docker Postgres ephemeral — chạy 5s, fail-fast.

Mitigation: Mock chỉ external API (VNPay sandbox, SendGrid). DB phải thật (test container).

Bẫy 4: Test implementation thay vì behavior

expect(component.state.count).toBe(1) — test internal, brittle khi refactor. ✅ expect(screen.getByText('Đã thêm')).toBeVisible() — test behavior user thấy.

Mitigation: Test "what user sees + does", không test "how code structured".

Bẫy 5: Skip refactor step

❌ Test pass → commit → next slice. Code messy tăng dần. ✅ Sau GREEN, spend 5-10 phút refactor: extract function, rename, remove dup.

Mitigation: Set timer 10 phút refactor mỗi slice. Skip = tech debt.

Case study VN — VietCodex booking salon

Project: SaaS booking salon 12 chi nhánh (xem spec-driven case study).

8 feature spec → cắt thành 32 vertical slice (4 slice/feature trung bình). Mỗi slice 1-2 ngày với Claude Code + Vitest + Playwright.

Workflow 1 slice (slice "User chọn ngày giờ booking"):

  1. Slice (5 phút) — define: "User chọn ngày + giờ trong calendar, validate không quá khứ + không trùng booking khác"
  2. Test (15 phút) — Claude gen booking-time.spec.ts với 6 case (today/yesterday/conflict/empty/valid/edge)
  3. RED (1 phút) — run, fail
  4. GREEN (30 phút) — Claude gen app/booking/select-time/page.tsx + lib/booking/validate-time.ts → run pass
  5. REFACTOR (10 phút) — extract DatePicker component, rename, cleanup
  6. Deploy (5 phút) — Vercel preview URL share client

Total: 1h10m / slice. 32 slice = ~40h = 5 ngày dev tập trung. 8 feature production-ready với 92% test coverage.

So sánh horizontal approach: cùng project ước tính 8 tuần với 60% coverage. TDD-slicing tiết kiệm 6.5 tuần + 32% coverage cao hơn.

Tóm tắt 1 dòng

TDD + Vertical Slicing = combo mạnh nhất AI Coding 2026: cắt feature thành slice end-to-end mỏng (1-2 ngày dev) theo INVEST của Bill Wake → mỗi slice chạy cycle RED-GREEN-REFACTOR của Kent Beck → AI viết test từ behavior + gen code pass test + refactor cleanup. Quality + Velocity cao nhất so vibe codingspec-driven. Phù hợp production critical (payment, auth, data sensitive). Tools 2026: Vitest + Playwright + MSW + Claude Code /test.

Đọc tiếp


Cần build SaaS / app production với 90%+ test coverage trong 2-4 tuần? VietCodex áp dụng TDD + Vertical Slicing + Claude Code — mỗi slice deploy preview cho bạn test ngay. Xem methodology hoặc đặt audit FREE 30 phút.

Câu hỏi thường gặp

TDD là gì? Kent Beck đặt tên năm nào?
TDD (Test-Driven Development — phát triển theo test) là phương pháp viết test FAIL trước, sau đó viết code TỐI THIỂU để pass, rồi refactor. Kent Beck (creator XP — Extreme Programming) xuất bản sách 'Test-Driven Development: By Example' năm 2003. Cycle: RED (test fail) → GREEN (code pass) → REFACTOR (cải tiến). Với AI 2026, mỗi cycle = AI gen 1 phần nhỏ pass test cụ thể, không hallucination.
Vertical slicing là gì? Khác horizontal layering ra sao?
Vertical slicing (cắt dọc) = chia feature thành các SLICE mỏng end-to-end (UI + API + DB cho 1 user story nhỏ). Horizontal layering (xếp lớp ngang) = build tất cả DB trước, rồi tất cả API, rồi tất cả UI. Ví dụ: feature 'đặt hàng' theo vertical = 6 slice (xem product → add cart → view cart → checkout → pay → confirm), mỗi slice deployable + có giá trị user. Theo horizontal = build 5 table → 20 endpoint → 10 page rồi mới wire — user không thấy gì đến cuối.
TDD và vertical slicing có liên quan gì?
Quan hệ cộng hưởng: TDD cho QUALITY (test trước = code chuẩn), Vertical Slicing cho VELOCITY (cắt nhỏ = ship liên tục). Combine: mỗi slice = 1 vòng TDD nhỏ. Slice nhỏ → test viết được trong 5 phút → AI gen code pass test trong 10 phút → slice ship trong 1-2 giờ. 1 ngày làm 4-8 slice = 1 feature production-ready.
AI có viết test được không? Test AI gen có đáng tin không?
AI viết test TỐT nếu bạn mô tả behavior cụ thể (Given-When-Then). Cách dùng: bạn viết 1 acceptance criteria → AI gen test → bạn review test (10 giây) → chạy test (fail vì chưa có code) → AI gen code pass test. AI gen test KHÔNG đáng tin nếu bạn nói chung chung 'test cho function này'. Quy tắc: bạn BIẾT behavior, AI VIẾT test theo behavior — không ngược lại.
Tôi nên dùng Vitest, Jest, hay Playwright?
2026 lựa chọn: **Vitest** cho unit + integration test (nhanh nhất, Vite-powered, Next.js friendly). **Playwright** cho E2E (browser automation, screenshot, video recording). **MSW** (Mock Service Worker) để mock API calls. Combo tốt nhất: Vitest 80% test (logic) + Playwright 20% test (golden path UI flow). Jest đã lỗi thời sau 2024 — chậm hơn Vitest 3x.
TDD có chậm hơn vibe coding bao nhiêu?
Build phase: TDD chậm 40-60% (viết test mất thời gian). Maintain phase: TDD nhanh 10x (test catch bug khi refactor). Break-even point: 4-6 tuần. Sau 6 tuần, TDD code velocity > vibe code vì không sợ break. AI 2026 thu hẹp gap: AI gen test nhanh = TDD chỉ chậm 15-25% so vibe.
Vertical slice nên dày bao nhiêu?
Quy tắc INVEST của Bill Wake (2003): Independent, Negotiable, Valuable, Estimable, Small, Testable. **Small = 1-2 ngày dev**. Quá mỏng (chỉ thêm 1 column DB) = không tạo giá trị user. Quá dày (cả feature) = không ship liên tục. Khoảng vàng: 1 slice deliver 1 user story testable end-to-end trong 1-2 ngày.
Có thể skip refactor step trong TDD không?
KHÔNG. Refactor là cốt lõi TDD. Red-Green-Refactor 3 bước cân bằng. Skip refactor → code messy tăng dần (tech debt), trade-off TDD biến mất. Refactor không phải redesign — chỉ cleanup: đặt tên rõ hơn, extract function, remove duplication. Với AI: sau khi test pass, prompt 'refactor file X để: (1) extract function helper, (2) đặt tên rõ hơn, (3) loại bỏ duplicate'.