Đoạn mã nào của bạn chưa được kiểm thử? Có phải là mã xử lý các tình huống phức tạp mà bạn không kiểm soát được? Luồng (thread), chạy lệnh, git, mạng, hay giao diện người dùng?
Ứng dụng của chúng ta trở nên thú vị nhất khi chúng phức tạp. Chúng cũng nguy hiểm nhất lúc đó. Và đó chính là lý do tại sao mã khó kiểm thử chính là loại mã cần được kiểm thử kỹ lưỡng nhất. Điều đó không phải lúc nào cũng xảy ra.
Thay vào đó, mỗi khi bạn chạm vào mã đó, bạn chạm nhẹ. Bạn tiến cẩn thận. Có thể bạn làm một chút kiểm thử thủ công. Và khi bạn gửi pull request, bạn hy vọng đồng nghiệp không nhận ra những bài kiểm thử đó không tồn tại.
Nhưng điều đó sẽ không làm mọi thứ tốt hơn. Bạn sẽ gặp lại cùng những vấn đề, cùng những lỗi, cùng căng thẳng vào lần sau – và mọi lần tiếp theo. Làm sao để cuối cùng những bài kiểm thử thách thức đó trở thành thứ bạn có thể tin cậy?
Chuyển đổi tâm thế
Điều令人沮丧 nhất về những bài kiểm thử này? Viết nó sẽ mất gấp mười lần thời gian so với cảm giác của bạn. Nếu bạn ước lượng thời gian bài kiểm thử tiết kiệm được so với thời gian viết bài kiểm thử, nó dường như không đáng giá.
Nhưng không chỉ về bài kiểm thử này. Nó về tất cả bài kiểm thử tương lai của bạn.
Hầu hết mã được kiểm thử tốt nhất mà tôi đã thấy đều có nhiều hỗ trợ. Không chỉ mã trong test/models. Mã được kiểm thử cực tốt có các fake, mock, bộ fixture kiểm thử tốt, các tùy chọn cấu hình chuyên dụng cho kiểm thử.
Tất cả những đó tốn thời gian để viết và lắp ráp.
Nhưng một khi đã có, cảm giác thật tuyệt vời. Bạn có thể nghĩ ra bài kiểm thử sau bài kiểm thử, cảm thấy an tâm về mã của mình, và tự tin về tốc độ di chuyển nhờ khoản đầu tư bạn đã làm.
Bạn có thể tin cậy vào công việc bạn đã làm.
Vì vậy, không chỉ về việc ngăn chặn lỗi trong mã phức tạp. Cũng là làm cho mã tương lai dễ dàng kiểm thử hơn, từng mảnh một.
Làm nó thành bài kiểm thử tích hợp (tạm thời)
Đôi khi, tuy nhiên, không phải vì hiểu giá trị – tôi hiểu. Thay vào đó, tôi chỉ bị mắc chắc vì không biết cách viết một bài kiểm thử đơn vị nhỏ, nhanh.
Làm sao bạn biết mình đang chạy đúng lệnh git trong công cụ triển khai, mà không thực sự chạy git? Làm sao để chắc chắn bạn gửi đúng header cho máy chủ từ xa?
Với đủ thời gian, bạn có thể xây dựng một fake chất lượng cho bài kiểm thử dựa vào.
Nhưng khi điều đó dường như quá nhiều để suy nghĩ, bạn có thể thử cách khác. Tách kiểm thử thành hai bước riêng biệt: "kiểm thử mã" và "viết mock".
Chỉ cần gọi máy chủ đó. Chỉ cần chạy lệnh đó. Tại sao?
- Dễ dàng bắt đầu hơn nhiều. Bạn có thể đang kiểm thử những lệnh đó thủ công, phải không? Chạy trong console, hoặc thử trong trình duyệt? Chỉ cần sao chép vào bài kiểm thử.
- Khi cuối cùng bạn viết mock hoặc fake, bạn có thể dùng các bài kiểm thử này để đảm bảo mock hoạt động. Nếu bạn thấy hành vi giống nhau trong thế giới thực và từ fake của bạn, fake của bạn có thể là tốt!
Bạn có thể không muốn giữ những bài kiểm thử này mãi mãi:
- Chúng có tất cả vấn đề của bài kiểm thử tích hợp. Chúng có thể chậm. Chúng có thể cần kết nối internet trực tiếp. Chúng có thể dễ vỡ, vì phụ thuộc vào hành vi mà ứng dụng của bạn thực sự không quan tâm.
- Bạn có thể không kiểm thử được một số thứ trong thế giới thực. Ví dụ: làm sao để ép buộc mã lỗi cụ thể khi bạn không kiểm soát máy chủ ở đầu kia?
- Bạn có thể bị chặn bởi máy chủ bạn phụ thuộc, và điều đó có thể làm hỏng bài kiểm thử (và ứng dụng của bạn!). Điều này thực sự đã xảy ra với tôi, và đó là một vấn đề lớn.
Vì vậy, viết bài kiểm thử như một bài kiểm thử tích hợp thực tế không phải là giải pháp vĩnh viễn, thậm chí không phải dài hạn. Nhưng ngay cả với những nhược điểm đó, nó vẫn hữu ích. Và sau khi bạn thay thế nó, bạn vẫn có thể giữ bài kiểm thử tích hợp đó, trong một bộ riêng. Như vậy, bạn luôn có thể kiểm tra mã của mình dựa trên thực tế, không chỉ giả định.
Một số mã chỉ khó kiểm thử. Nó mất một thời gian để xây dựng hạ tầng bạn cần để viết bài kiểm thử tin cậy nhanh chóng. Và nhiều lúc, nó không dường như đáng giá.
Nhưng khi bạn ngừng suy nghĩ về bài kiểm thử đơn lẻ đó, và suy nghĩ về giá trị của việc làm cho tất cả bài kiểm thử tương lai dễ dàng hơn, việc kiểm thử mã phức tạp trở nên có động lực hơn nhiều. Và một khi bài kiểm thử đầu tiên xong, các bài còn lại dường như kỳ diệu trở nên dễ dàng viết hơn nhiều.
Đôi khi, tuy nhiên, điều đó vẫn chưa đủ. Nếu bạn biết cách đảm bảo mã hoạt động trong thế giới thực, nhưng chỉ không biết cách kiểm thử nó?
Khi đó xảy ra, hãy ngừng nhìn vào bài kiểm thử như thứ cần giữ thuần khiết và cô lập. Thay vào đó, hãy thấy nó như một cách để tự động hóa những gì bạn đang làm thủ công.
Nó không hoàn hảo, và bạn nên thay thế nó sớm nhất có thể. Nhưng những bài kiểm thử đó có thể给你 sự tự tin bạn cần để viết và thay đổi mã phức tạp nhanh chóng.