Không có định nghĩa duy nhất, và đó là lý do câu này hay được hỏi để xem bạn hiểu mục đích hay chỉ thuộc nhãn.
Cách phân biệt dùng được trong thực tế, dựa trên thứ test kiểm soát được:
- Unit test: chỉ chạy code trong process, không chạm mạng, không chạm file, không chạm DB. Chạy vài mili giây, chạy song song thoải mái, không cần dọn dẹp.
- Integration test: có chạm ít nhất một thành phần ngoài process — DB, message queue, HTTP client. Chậm hơn (chục đến trăm mili giây), cần dữ liệu sạch giữa các lần chạy.
- E2E: chạy qua giao diện/HTTP thật của hệ thống đã deploy, gồm nhiều service.
Với câu hỏi ban đầu: test chạy repository trên Postgres thật (kể cả bằng Docker/Testcontainers) là integration test, dù nó chỉ kiểm tra một hàm.
Điều quan trọng hơn cái nhãn: quyết định gì theo nó. Test nhanh và độc lập thì chạy mỗi lần lưu file; test chạm DB thì gom vào một lệnh riêng chạy trong CI. Trả lời được điều này thì tranh cãi "unit là gì" trở nên không cần thiết.