Nền tảng
Tư duy Shift Left
Đẩy mọi hoạt động phát hiện lỗi về càng sớm càng tốt. Lỗi tìm ra lúc viết yêu cầu rẻ gấp hàng trăm lần lỗi tìm ra khi người dùng đã cài app.
Nội dung bài
Thuật ngữ trong bài (15)
- acceptance criteria · tiêu chí nghiệm thu
- quality gate · cổng chất lượng
- sprint · chu kỳ làm việc
- build · bản dựng
- CI · tích hợp liên tục
- commit · điểm lưu thay đổi
- merge · gộp nhánh
- pull request · yêu cầu gộp mã
- integration test · kiểm thử tích hợp
- regression · lỗi tái phát
- unit test · kiểm thử đơn vị
- feature flag · công tắc tính năng
- release · bản phát hành
- rollback · quay về bản cũ
- incident · sự cố
Ý tưởng trong một câu
Vẽ dòng đời một thay đổi từ trái sang phải — ý tưởng, yêu cầu, thiết kế, code, test, release, người dùng — rồi kéo mọi hoạt động phát hiện lỗi về phía bên trái nhất có thể.
Đây không phải một công cụ hay một giai đoạn. Đây là câu hỏi phải hỏi mỗi khi phát hiện một lỗi: lẽ ra lỗi này có thể bị bắt sớm hơn ở đâu?
Vì sao sang phải thì đắt
Cùng một lỗi, chi phí sửa tăng theo cấp số nhân theo chặng nó bị phát hiện:
| Bắt được ở đâu | Ai phải động vào | Chi phí tương đối |
|---|---|---|
| Lúc viết yêu cầu | Chủ sản phẩm sửa một câu | 1 |
| Lúc thiết kế | Chủ sản phẩm + chủ kỹ thuật | 3 |
| Lúc dev đang gõ code | Một dev, vài phút | 5 |
| Lúc review code | Hai người, nửa ngày | 10 |
| Lúc test | Dev + test, làm lại từ đầu | 30 |
| Sau khi release | Cả đội, thêm sự cố, thêm rollback | 100 |
| Người dùng gặp và bỏ app | Không sửa được nữa | Không đo được |
Con số cụ thể tuỳ dự án, nhưng hình dạng đường cong thì luôn đúng: càng sang phải càng đắt, và độ đắt tăng nhanh hơn nhiều so với cảm giác của người trong cuộc.
Chi phí đắt nhất ở cột cuối không phải tiền công sửa lỗi. Nó là niềm tin của người dùng, và thứ đó không mua lại được bằng một bản vá.
Shift left trong Alliance App nghĩa là gì
Với mỗi loại rủi ro, ta xác định vị trí bên trái nhất mà nó có thể bị bắt, rồi dựng cơ chế ở đúng chỗ đó:
| Loại rủi ro | Nếu không shift left thì bắt được lúc | Ta bắt nó ở đâu | Bằng cách nào |
|---|---|---|---|
| Hiểu sai yêu cầu | Lúc demo cuối sprint | Trước khi dev nhận việc | Definition of Ready, acceptance criteria kiểm chứng được |
| Thiếu trường hợp biên | Lúc test | Lúc viết yêu cầu | Buộc liệt kê rỗng, lỗi, mạng chậm, quyền không đủ |
| Lỗi cú pháp, kiểu dữ liệu | Lúc chạy CI | Ngay trong trình soạn thảo | Kiểm tra kiểu, lỗi tĩnh chạy khi gõ |
| Sai quy ước, định dạng | Lúc review | Lúc lưu tệp và lúc tạo commit | Tự động định dạng, móc kiểm tra trước commit |
| Lỗi logic | Lúc test thủ công | Lúc dev đang viết | Unit test viết cùng lúc với code |
| Lỗi tích hợp giữa module | Sau khi merge | Trước khi merge | Integration test chạy trên pull request |
| Hồi quy | Sau khi release | Mỗi lần đẩy code | Bộ test luồng quan trọng chạy tự động |
| Hiệu năng kém | Người dùng than | Trên pull request | Ngưỡng thời gian khởi động, kích thước gói trong CI |
| Lỗ hổng bảo mật | Bị khai thác | Lúc thiết kế | Soát mối đe doạ khi thiết kế, quét phụ thuộc trong CI |
| Thiết kế sai hướng | Lúc code xong | Trước khi viết dòng nào | Soát thiết kế, bản mẫu bấm được |
| Rủi ro của bản release | Khi 100% người dùng dính | Khi 5% người dùng dính | Release từng phần, feature flag |
Đọc bảng này theo cột thứ ba: đó là danh sách các quality gate của dự án, và mỗi cổng tồn tại vì một lý do cụ thể chứ không phải vì thủ tục.
Ba tầng phản hồi, tính bằng thời gian
Shift left đo được bằng độ trễ phản hồi: từ lúc dev gõ sai tới lúc dev biết mình sai.
| Tầng | Mục tiêu độ trễ | Gồm những gì |
|---|---|---|
| Trong máy dev | Dưới 10 giây | Kiểm tra kiểu, lỗi tĩnh, định dạng, unit test của phần đang sửa |
| Trước khi đẩy lên | Dưới 2 phút | Móc trước commit, toàn bộ unit test, build thử |
| Trên pull request | Dưới 10 phút | Integration test, UI test luồng chính, quét phụ thuộc, ngưỡng hiệu năng |
Vượt các mốc này thì dev sẽ bắt đầu bỏ qua. Một bộ test chạy 40 phút không phải là cổng chặn — nó là thứ người ta học cách né. Tốc độ phản hồi là một yêu cầu chất lượng, không phải tiện nghi.
Shift left không phải là đẩy việc sang cho dev
Đây là chỗ hay hiểu sai nhất. Shift left không có nghĩa là bỏ vai trò test và bắt dev gánh thêm. Nó có nghĩa là:
- Người test tham gia từ lúc viết yêu cầu, không phải chờ tới cuối để nhận bản build. Câu hỏi "cái này test kiểu gì?" đặt ra lúc viết acceptance criteria là câu hỏi rẻ nhất trong cả dự án.
- Người test dành sức cho thứ máy không làm được: test thăm dò, trải nghiệm thật, kịch bản lạ. Việc lặp lại thì tự động hoá.
- Bảo mật tham gia lúc thiết kế, không phải lúc sắp release nói "không được đâu".
Nếu áp dụng shift left mà kết quả là dev làm thêm giờ còn tester rảnh hơn, thì đang làm sai.
Câu hỏi bắt buộc sau mỗi lỗi
Mỗi khi một lỗi lọt tới chặng sau hơn mức đáng lẽ, trong buổi cải tiến hoặc báo cáo sự cố phải trả lời:
- Lỗi này bị bắt ở chặng nào?
- Chặng sớm nhất có thể bắt được nó là chặng nào?
- Vì sao chặng đó không bắt được — thiếu cơ chế, cơ chế có mà không chạy, hay cơ chế chạy mà không đủ?
- Ta dựng gì để lần sau nó bị bắt ở chặng sớm hơn?
Câu 4 là đầu ra bắt buộc. Một buổi phân tích lỗi kết thúc bằng "lần sau cẩn thận hơn" là một buổi thất bại — cẩn thận hơn không phải là cơ chế, và nó không sống sót qua ngày bận rộn.
Chỉ số theo dõi
Shift left có làm thật hay không thì nhìn vào bốn con số này theo tháng:
| Chỉ số | Hướng tốt |
|---|---|
| Tỷ lệ lỗi phát hiện trước khi merge so với sau khi merge | Tăng |
| Số lỗi lọt tới người dùng mỗi bản release | Giảm |
| Thời gian từ lúc đẩy code tới lúc biết kết quả kiểm tra | Giảm |
| Tỷ lệ hạng mục bị trả lại vì hiểu sai yêu cầu | Giảm |
Bốn con số này được soát trong buổi sức khoẻ hệ thống hằng tuần. Con số nào đi sai hướng hai tuần liên tiếp thì mở hạng mục sửa.
Giới hạn
Shift left không miễn phí. Kéo quá đà thì thành phân tích lê thê, thiết kế hàng tháng trời mà không ai viết một dòng code. Ranh giới thực dụng:
- Chỉ shift left thứ kiểm chứng được sớm. Thứ chỉ biết được khi có người dùng thật thì đừng cố đoán trên giấy — hãy release từng phần và đo.
- Mỗi quality gate phải chặn được một loại lỗi đã từng xảy ra thật. Gate dựng vì lo xa mà chưa từng bắt được gì thì bỏ đi.
- Thời gian bỏ ra ở bên trái phải nhỏ hơn thời gian tiết kiệm ở bên phải. Không chắc thì thử một sprint rồi đo.

