Service Level Testing for Microservices in Swiggy

Bài tóm tắt Swiggy 2021 3. Quy mô lớn Độ khó: Trung bình

Swiggy · 2021 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc

Đọc qua trình duyệt (bytes.swiggy.com là blog Medium custom domain, crawler bị chặn, Wayback "Temporarily Offline"; mở bản medium.com/swiggy-bytes); raw/ chỉ là placeholder.

Bối cảnh

  • Năm 2021 Swiggy chạy hơn 400 microservice production; vài năm trước chỉ vài chục. Cùng lúc tốc độ deploy giảm: tính năng kéo từ ngày thành tuần, sửa nhỏ cũng mất nhiều ngày dev và test.
  • Điều tra cho thấy nhiều loại lỗi (mạng, I/O, hợp đồng API) unit test không phủ. Theo Swiggy, unit test hợp với module độc lập trong monolith, còn ở microservice phần lớn code là giao tiếp: dựng endpoint, client DB, client gọi service khác, marshal/unmarshal; unit test bỏ qua đúng phần đó.

Thay đổi chính

  • Service level test (SLT): test hộp đen qua API của một service, service chạy với endpoint giống production, dependency dựng cục bộ (database, queue, cache) và endpoint HTTP/gRPC mà service gọi thì mock.
  • Vấn đề: viết SLT lâu hơn viết code ("tốn thời gian hơn code thật"): phải dựng dependency, khởi service với cấu hình giống production, và kiểm cả tác dụng phụ (message đã publish lên queue, đã ghi DB). Họ đã thử CI chuyên dụng, docker-compose, Spring test helper, Testcontainers; không cái nào giải hết, mà developer phải học từng cái. gripMock không cho chỉnh mock từ trong code test, nên chạy test không còn một bước.
  • Thư viện Oh-My-Test-Helper (Go và Java) gom các mẫu lặp: khởi container Kafka một dòng rồi gắn bootstrap server vào cấu hình app, produce message để test consumer; khởi mock gRPC từ định nghĩa proto, tạo stub và đếm request đã nhận ngay trong test.

Vì sao

  • Theo Swiggy: trong 6 tháng gần trăm microservice dùng thư viện, các service này đạt coverage trên 90% dễ dàng; thời gian viết SLT từ vài ngày (trong kế hoạch dự án) xuống vài giờ. Bài không có số về lỗi production giảm.

Bài học cho SWE

  • Khi chuyển sang microservice, chỗ lỗi dịch từ logic sang biên giao tiếp; tầng test chính nên dịch theo (test ở mức API của service với dependency thật).
  • Test khó viết thì không ai viết: đầu tư vào thư viện dựng dependency và kiểm tác dụng phụ là cách nhân rộng.
  • Mock phải điều khiển được từ chính code test thì test mới tự chứa và chạy một bước.

Liên quan