testing/10-types

Mỗi loại test bắt một loại lỗi khác nhau Every test catches a different kind of failure

Chọn sai loại nghĩa là bạn đang đo rất cẩn thận đúng thứ mình không sợ. Trang này xếp mười loại kiểm thử theo phạm vi chúng chạm tới, và nói thẳng mỗi loại bắt được gì, bỏ lọt gì, và bạn phải trả giá bằng cái gì. Pick the wrong one and you're carefully measuring the thing you weren't afraid of. This page lays out ten kinds of test by how far they reach, and says plainly what each one catches, what it misses, and what it costs you.

CodeCrackAI · 10 Types of Testing

Phổ phạm viThe scope spectrum

Vị trí trên trục = test chạm tới đâu. Chấm đặc chạy trong CI khép kín; vòng nét đứt chạy trên hệ thống đang sống. Hai loại nằm ngoài trục vì chúng không thuộc về một tầng nào. Position on the axis is how far a test reaches. Solid dots run inside sealed CI; dashed rings run against a live system. Two types sit off the axis because they don't belong to any single layer.

Scope spectrum of ten testing types Regression — chính sách, sống ở mọi tầng bên dưới Regression — a policy, lives at every layer below Unit Contract Smoke Load Snapshot Integration End-to-End Chaos một hàmone function production đang phục vụ kháchlive production traffic Mutation — kiểm thử chính bộ test ở trên Mutation — tests the tests above

← kéo ngang để xem hết ← scroll sideways to see it all

Chọn cái nàoWhich one to pick

Bắt đầu từ nỗi sợ, không bắt đầu từ danh sách công cụ. Start from the fear, not from the tool list.

Trước hết: có thể bạn chưa cần loại nào cảFirst: you may need none of them

Prototype sẽ vứt sau hai tuần, script chạy một lần, sản phẩm chưa có người dùng thật — chi phí của lỗi gần bằng không, nên test là chi phí thuần. Thứ rẻ hơn nên có trước: type system chặt, linter, error tracking, feature flag và rollback 30 giây. Bắt đầu viết test khi người dùng thật có thể mất tiền hoặc mất dữ liệu, khi bạn phá chỗ khác tới lần thứ hai, hoặc khi có người thứ hai chạm vào code. A prototype you'll bin in two weeks, a script that runs once, a product with no real users — the cost of failure is near zero, so tests are pure cost. Cheaper things first: a strict type system, a linter, error tracking, feature flags and a 30-second rollback. Start testing when real users can lose money or data, when you've broken something else for the second time, or when a second person touches the code.

“Logic của tôi tính sai”“My logic computes the wrong answer”Unit
“Hai mảnh ghép không khớp — và tôi dựng được cả hai”“Two pieces don't fit — and I can start both”Integration
“Hai mảnh ghép không khớp — nhưng hai team deploy riêng”“Two pieces don't fit — but two teams deploy separately”Contract
“Người dùng không hoàn tất được việc”“Users can't complete the job”End-to-End
“Có gì đó đổi mà tôi không cố ý”“Something changed that I didn't intend”Snapshot
“Bản vừa deploy có sống không”“Is the build I just shipped alive”Smoke
“Chuyện này đã từng xảy ra rồi”“This happened before”Regression
“Hệ thống chịu được bao nhiêu”“How much traffic can we take”Load
“Cơ chế dự phòng có thật sự chạy không”“Does the fallback actually work”Chaos
“Bộ test của tôi có giá trị không”“Is my suite worth anything”Mutation

Mười loại, tra cứu chi tiếtTen types, in detail

Câu đánh đổi được tách riêng ở cuối mỗi thẻ. Hạn chế là khuyết tật; đánh đổi là cái giá bạn trả một cách có ý thức. The trade-off sits on its own at the bottom of each card. Limits are defects; a trade-off is a price you pay on purpose.

Unit

Phạm viScope

Một hàm, tách khỏi mọi thứ xung quanh. Không mạng, không đĩa, không đồng hồ thật.One function, isolated from everything. No network, no disk, no real clock.

inputfunctionassert

Dùng choUse for

  • Tính giá, thuế, chiết khấu, làm tròn tiềnPricing, tax, discounts, money rounding
  • Parser, formatter, máy trạng thái, rule kiểm tra dữ liệuParsers, formatters, state machines, validation rules

ĐượcGain

  • Dưới 10ms mỗi test; phản hồi ngay khi đang gõUnder 10ms each; feedback while you type
  • Đỏ là chỉ thẳng vào một hàmRed points straight at one function

MấtLose

  • Xanh hết mà hệ thống vẫn chết vì hai module hiểu sai nhauAll green while the system is down over a shape mismatch
  • Mock sai là xanh giả; mù trước lỗi config và schemaA wrong mock is a false green; blind to config and schema

Đổi bằng chứng “hệ thống thật sự chạy” lấy tốc độ phản hồi và độ chính xác khi định vị lỗi.Trades proof that the system actually runs for feedback speed and pinpoint diagnosis.

→Mô tả được đúng/sai chỉ bằng input và output, không nhắc tới DB hay HTTP.You can define right and wrong purely from input and output, no DB or HTTP.

Integration

Phạm viScope

Nhiều thành phần thật chạy cùng nhau, với DB thật trong container thay vì đồ giả.Real components running together against a real containerised database.

Service AService BDB thậtreal DB

Dùng choUse for

  • Repository đối chiếu schema thật, migration và rollbackRepositories against the real schema, migrations and rollbacks
  • Transaction, khoá, truy vấn phức tạp chỉ lộ lỗi trên engine thậtTransactions, locking, queries that only break on the real engine

ĐượcGain

  • Bắt schema drift và lỗi cấu hình — hai nguồn sự cố lớn nhấtCatches schema drift and config errors — two top incident causes
  • Ít mock hơn nên ít xanh giả hơnFewer mocks, so fewer false greens

MấtLose

  • Chậm hơn unit 10–100 lần, cần Docker và CI khoẻ10–100× slower, needs Docker and real CI hardware
  • Dễ flaky vì state sót lại; đỏ thì thủ phạm ở tầng nào cũng đượcFlaky from leftover state; red could mean any layer

Đổi tốc độ và độ rõ khi lỗi lấy bằng chứng rằng các mảnh ghép thật sự khớp.Trades speed and diagnostic clarity for proof that the pieces actually fit.

→Lỗi bạn sợ nằm ở khoảng trống giữa hai module, không nằm trong module nào.The failure you fear lives in the gap between two modules, not inside either.

End-to-End

Phạm viScope

Mô phỏng người dùng thật bấm qua trọn luồng, từ trình duyệt xuống DB rồi ngược lên màn hình.A simulated user clicking a whole flow, browser to database and back to the screen.

clickUIAPIDB

Dùng choUse for

  • Đăng ký, thanh toán, phân quyền — mọi luồng chạm tới tiềnSign-up, checkout, authorisation — anything touching money
  • Upload → xử lý nền → tải kết quả vềUpload → background processing → download the result

ĐượcGain

  • Bằng chứng duy nhất rằng người dùng làm được việcThe only proof a user can get the job done
  • Bắt CORS, routing, biến môi trường thiếu, cert hết hạnCatches CORS, routing, missing env vars, expired certs

MấtLose

  • Chậm nhất và flaky nhất trong mười loạiSlowest and flakiest of the ten
  • Đỏ không nói tầng nào hỏng; đổi một nút là sửa hai chục testRed names no layer; one renamed button breaks twenty tests

Đổi thời gian CI và công bảo trì lấy bằng chứng duy nhất rằng người dùng thật hoàn tất được việc.Trades CI time and maintenance for the only proof real users can finish real work.

→Luồng này hỏng là công ty mất tiền ngay hôm nay.If this flow breaks, the company loses money today.

Contract

Phạm viScope

Hai bên thống nhất hình dạng API, rồi mỗi bên tự kiểm tra với hợp đồng — không cần dựng cả hai cùng lúc.Both sides agree the API shape, then verify against it independently — no shared environment.

ConsumercontractProvider CI

Dùng choUse for

  • Microservices nhiều team, mỗi team deploy theo nhịp riêngMicroservices across teams deploying on their own cadence
  • App mobile với bản cũ còn sống; schema sự kiện trên KafkaMobile apps with old versions still live; Kafka event schemas

ĐượcGain

  • Bắt breaking change trước khi deploy, nhanh như unit testCatches breaking changes pre-deploy, at unit-test speed
  • Tài liệu API được kiểm chứng tự động nên không lỗi thờiAPI docs verified automatically, so they can't go stale

MấtLose

  • Chỉ kiểm hình dạng, không kiểm ngữ nghĩaVerifies shape, never meaning
  • Cần broker và kỷ luật quy trình; contract lỗi thời còn hại hơn không cóNeeds a broker and discipline; a stale contract is worse than none

Đổi công vận hành broker và kỷ luật quy trình lấy quyền deploy độc lập giữa các team.Trades broker upkeep and process discipline for the right to deploy independently.

→Hai team deploy riêng và bạn không có cách nào dựng cả hệ thống lên để test.Two teams ship separately and you can't stand the whole system up.

Snapshot

Phòng hồi quyChange guard

Ghi lại output dạng văn bản, lần sau đem so; khác là đỏ và người duyệt quyết định.Record the output as text, compare next run; any difference goes to a human.

render.snapdiff

Dùng choUse for

  • Output component, response JSON, output CLIComponent output, JSON responses, CLI output
  • Cấu hình sinh tự động: terraform plan, manifest KubernetesGenerated config: terraform plan, Kubernetes manifests

ĐượcGain

  • Một dòng phủ được một output lớn, gần như miễn phíOne line covers a large output, essentially free
  • Bắt thay đổi vô tình khi nâng thư việnCatches accidental changes from library upgrades

MấtLose

  • Bấm cập nhật cho hết đỏ là xoá sạch giá trịUpdating to clear red erases all the value
  • Không nói tại sao sai; output không ổn định gây flakyNever says why it's wrong; unstable output makes it flaky

Đổi sự rõ ràng về ý định — không ai biết bạn đang khẳng định điều gì — lấy độ phủ rộng gần như miễn phí.Trades clarity of intent — nobody knows what you're claiming — for near-free breadth.

→Bạn không quan tâm giá trị cụ thể, chỉ muốn biết có gì đổi ngoài ý muốn.You don't care about the values, only whether something changed unintentionally.

Smoke

Phòng hồi quyChange guard

Năm tới mười check nông chạy dưới một phút sau deploy, chỉ để trả lời: bản này có đáng chạy tiếp không.Five to ten shallow checks under a minute after deploy, answering one thing: is this build worth continuing.

deploy< 60sgate / rollback

Dùng choUse for

  • Cổng chặn sau deploy, nối thẳng vào auto-rollbackA post-deploy gate wired into auto-rollback
  • Sau khi xoay secret, nâng hạ tầng, chạy migrationAfter rotating secrets, upgrading infra, running migrations

ĐượcGain

  • Chặn sớm, tiết kiệm hàng chục phút CI mỗi lần build hỏngFails fast, saving tens of CI minutes per broken build
  • Bắt secret thiếu, DNS sai, quyền IAM chưa cấpCatches missing secrets, wrong DNS, ungranted IAM

MấtLose

  • Nông nên bỏ lọt gần hết lỗi logic; xanh chỉ nghĩa là chưa chếtShallow, so it misses logic bugs; green only means “not dead”
  • Rất dễ phình thành E2E rồi mất lý do tồn tạiDrifts into an E2E suite and loses its reason to exist

Đổi gần như toàn bộ độ sâu lấy một câu trả lời đáng tin trong vòng một phút.Trades almost all depth for a trustworthy answer inside one minute.

→Bạn cần biết trong một phút rằng bản build này không chết ngay từ vạch xuất phát.You need to know within a minute that this build isn't dead on arrival.

Regression

Phòng hồi quyChange guard

Không phải kỹ thuật mà là chính sách: mỗi bug đã sửa để lại một test vĩnh viễn.Not a technique but a policy: every fixed bug leaves a permanent test behind.

bugtest ĐỎRED testfix

Dùng choUse for

  • Mọi bug production, không ngoại lệEvery production bug, no exceptions
  • Edge case dữ liệu thật: tên có dấu, lệch timezone, số âm, emojiReal data edge cases: accents, timezone shifts, negatives, emoji

ĐượcGain

  • Gần như miễn phí: bug đã cho sẵn kịch bản và kỳ vọngNearly free: the bug hands you the scenario and expectation
  • Suite lớn dần đúng ở chỗ hệ thống hay gãyThe suite grows where the system actually breaks

MấtLose

  • Suite phình dần, CI chậm dần nếu không ai dọnThe suite swells and CI slows if nobody prunes
  • Test cũ ghim hành vi lỗi thời và chặn thay đổi đúngOld tests pin obsolete behaviour and block correct changes

Đổi việc CI chậm dần theo năm tháng lấy sự chắc chắn rằng không lỗi nào xuất hiện hai lần.Trades CI that slows year by year for the guarantee no bug appears twice.

→Ai đó vừa nói “chuyện này đã từng xảy ra rồi”.Someone just said “this happened before”.

Load

Chịu tải & chịu lỗiCapacity & resilience

Tăng tải có kiểm soát để tìm điểm gãy, không phải để lấy một dấu tích pass.A controlled traffic ramp to find the breaking point, not to earn a pass tick.

10 rps1k rpsp99 / knee

Dùng choUse for

  • Trước đợt sale, mở bán vé, đăng ký nhập họcBefore a sale, a ticket drop, an enrolment window
  • Sau khi thêm cache, đổi DB, tách service; định cỡ autoscalingAfter adding cache, switching DB, splitting a service; sizing autoscaling

ĐượcGain

  • Biết trần trước khi người dùng biết hộ bạnYou learn the ceiling before users find it for you
  • Lộ nút thắt cụ thể: pool cạn, N+1, GC pauseSurfaces exact bottlenecks: pool exhaustion, N+1, GC pauses

MấtLose

  • Số chỉ đúng với môi trường đã đo, không quy đổi tuyến tínhNumbers hold only for the environment measured; no linear scaling
  • Dữ liệu tổng hợp làm cache hit gần 100% và phép đo vô nghĩaSynthetic data pushes cache hits to ~100% and voids the measurement

Đổi chi phí dựng môi trường giống production lấy quyền biết trước giới hạn, thay vì phát hiện lúc hai giờ sáng.Trades the cost of a production-like environment for knowing your limit before 2am does.

→Bạn biết hệ thống chạy đúng; bạn không biết nó chạy được tới đâu.You know the system is correct; you don't know how far it goes.

Chaos

Chịu tải & chịu lỗiCapacity & resilience

Chủ động gây lỗi trên hệ thống đang sống để chứng minh cơ chế phục hồi thật sự chạy.Deliberate failure injection into a live system to prove recovery actually works.

giả thuyếthypothesiskill podSLO

Dùng choUse for

  • Failover DB, timeout và retry giữa service, mất một AZDB failover, cross-service timeouts and retries, losing an AZ
  • Hành vi khi cache chết: degrade mềm hay sập thẳngBehaviour when the cache dies: graceful or hard failure

ĐượcGain

  • Biến giả định thành sự kiện quan sát đượcTurns assumptions into observed events
  • Lộ cascading failure và diễn tập quy trình trực sự cốExposes cascading failure and rehearses the on-call process

MấtLose

  • Không có observability thì chỉ là phá hoại có kế hoạchWithout observability it's just scheduled vandalism
  • Rủi ro chạm khách hàng thật, không bao giờ bằng khôngReal customer risk that never drops to zero

Đổi một rủi ro nhỏ có kiểm soát hôm nay lấy việc không nhận một sự cố không kiểm soát vào đêm bất kỳ.Trades a small controlled risk today for not taking an uncontrolled outage some random night.

→Bạn có cơ chế dự phòng nhưng chưa bao giờ tận mắt thấy nó chạy.You have a fallback and you've never once watched it run.

Mutation

Kiểm thử của kiểm thửTesting the tests

Cố tình làm hỏng code rồi chạy lại suite. Test vẫn xanh nghĩa là nó không kiểm gì ở chỗ đó.Break the code on purpose and rerun the suite. Still green means it wasn't checking anything there.

sourcemutantkilled / survived

Dùng choUse for

  • Thẩm định suite của module tính tiền, phân quyềnAuditing suites for billing and authorisation modules
  • Thay chỉ tiêu coverage; audit trước một đợt refactor lớnReplacing coverage targets; auditing before a large refactor

ĐượcGain

  • Đo chất lượng khẳng định, không đo số dòng chạy quaMeasures assertion quality, not lines executed
  • Chỉ đích danh nhánh nào đang không được kiểmNames the exact branch nobody is checking

MấtLose

  • Rất chậm; mutant tương đương tạo nhiễuVery slow; equivalent mutants create noise
  • Chỉ dùng được khi suite đã nhanh và không flakyOnly usable once the suite is fast and non-flaky

Đổi thời gian máy tính bằng giờ lấy câu trả lời thật cho câu hỏi “bộ test này có giá trị không”.Trades hours of machine time for an honest answer to “is this suite worth anything”.

→Coverage 95% mà bạn vẫn không dám tin bộ test này.Coverage says 95% and you still don't trust the suite.

Bảng đánh đổiTrade-off table

Trục so sánh lấy từ chính chủ đề: tốc độ phản hồi, phạm vi bắt lỗi, độ rõ khi đỏ, công bảo trì và nguy cơ flaky. The axes come from the subject itself: feedback speed, detection range, clarity when red, maintenance and flake risk.

LoạiType Tốc độSpeed Bắt được gìWhat it catches Độ rõ khi đỏClarity when red Bảo trìMaintenance Nguy cơ flakyFlake risk
Unitmili giâymillisecondsMột hàmOne functionRất caoVery highThấpLowRất thấpVery low
IntegrationgiâysecondsVài module + DBSeveral modules + DBTrung bìnhMediumTrung bìnhMediumTrung bìnhMedium
End-to-EndphútminutesToàn bộ luồngA whole user flowThấpLowCaoHighCaoHigh
ContractgiâysecondsRanh giới APIAPI boundariesCaoHighTrung bìnhMediumThấpLow
Snapshotmili giâymillisecondsHình dạng outputOutput shapeThấpLowThấp nhưng hay nhiễuLow but noisyTrung bìnhMedium
Smokegiâyseconds“Còn sống hay không”“Is it alive”CaoHighRất thấpVery lowThấpLow
Regressiontuỳ tầngdepends on layerLỗi đã từng xảy raBugs that already happenedCaoHighTích luỹ dầnAccumulatesTuỳ tầngDepends on layer
Loadchục phúttens of minutesGiới hạn năng lựcCapacity limitsTrung bìnhMediumCaoHighTrung bìnhMedium
Chaoschục phúttens of minutesKhả năng phục hồiRecovery behaviourTrung bìnhMediumCaoHighKhông áp dụngNot applicable
MutationgiờhoursChất lượng chính bộ testQuality of the suite itselfRất caoVery highThấpLowThấpLow

Anti-patternsAnti-patterns

Những thói quen trông giống kỷ luật kỹ thuật nhưng đang phá giá trị của cả bộ test. Habits that look like engineering discipline while quietly destroying the suite's value.

Đặt mục tiêu coverage 100%Targeting 100% coverage Coverage đếm dòng chạy qua, không đếm khẳng định; test không có assert vẫn nâng số.Coverage counts executed lines, not assertions; a test with none still raises it. Dùng mutation score cho module quan trọng; coverage chỉ để tìm vùng chưa ai chạm.Use mutation score on critical modules; keep coverage for spotting untouched areas.
Kim tự tháp lộn ngược: nhiều E2E, ít unitThe inverted pyramid: many E2E, few unit CI 40 phút, flaky liên tục, rồi cả team ngừng tin màu đỏ.40-minute CI, constant flakes, then the team stops believing red. Đẩy khẳng định xuống tầng thấp nhất tái hiện được lỗi.Push assertions down to the lowest layer that reproduces the failure.
Retry cho tới khi xanhRetrying until green Giấu một bug thật dưới cái nhãn “flaky”.Hides a real bug behind the “flaky” label. Cách ly, gắn người chịu trách nhiệm và hạn xử lý; không sửa được thì xoá.Quarantine it with a named owner and a deadline; delete it if it can't be fixed.
Cập nhật snapshot cho hết đỏUpdating snapshots to clear red Snapshot mất toàn bộ ý nghĩa, chỉ còn là một file lớn màu xanh.The snapshot loses all meaning and becomes a large green file. Review diff snapshot như review code, ngay trong pull request.Review snapshot diffs like code, inside the pull request.
Dùng chung một DB cho mọi testOne shared database for every test Test này phá state của test kia; chạy song song là hỏng.Tests corrupt each other's state; parallel runs break. Container hoặc schema riêng cho từng lần chạy.A fresh container or schema per run.
Chạy chaos khi chưa có observabilityRunning chaos without observability Phá thứ mình không quan sát được thì không học được gì.Breaking what you can't observe teaches you nothing. Dựng dashboard và alert trước, tiêm lỗi sau.Build dashboards and alerts first, inject failure second.
Sửa bug mà không để lại testFixing a bug without leaving a test Cùng bug đó quay lại sau ba tháng, và lần này mất niềm tin.The same bug returns in three months, and this time it costs trust. Viết test đỏ trước, sửa code sau. Không đỏ trước thì chưa tái hiện được bug.Red test first, fix second. If it never went red, you never reproduced the bug.

Ba câu cần nhớThree things to remember

01Mỗi loại test mua một loại tự tin khác nhau. Câu hỏi đúng không phải “loại nào tốt nhất” mà “hôm nay tôi sợ điều gì nhất”.Each type buys a different kind of confidence. The right question isn't “which is best” but “what am I most afraid of today”.
02Test xanh không chứng minh code đúng — nó chỉ chứng minh những điều bạn đã nghĩ tới đều ổn. Mutation test là loại duy nhất ở đây chất vấn chính điều đó.A green suite doesn't prove the code is correct — it proves everything you thought of is fine. Mutation testing is the only type here that interrogates that claim.
03Giá trị của một bộ test nằm ở tốc độ phản hồi và độ tin cậy của tín hiệu. Một suite chậm hoặc flaky còn tệ hơn không có, vì nó dạy cả team bỏ qua màu đỏ.A suite's value is feedback speed and signal reliability. A slow or flaky suite is worse than none, because it teaches the team to ignore red.