Computer >> Máy Tính >  >> Lập trình >> Ruby

Kiểm tra bao nhiêu là quá nhiều?

Bạn biết cảm giác đau đớn như thế nào khi làm việc với mã được kiểm tra không tốt. Mỗi khi bạn sửa một lỗi, bạn tạo ra năm lỗi khác. Và khi những điều làm hoạt động, bạn không bao giờ thực sự biết liệu nó được thiết kế theo cách đó hay chỉ hoạt động ngẫu nhiên.

Mặt khác, bạn vừa viết những gì có vẻ giống như 200 bài kiểm tra để gửi một tính năng nhỏ. Bạn liên tục phải thiết kế lại mã đã hoạt động để đạt được phạm vi kiểm tra 100%. Bạn không thể tránh khỏi cảm giác rằng mã được kiểm tra tốt nhất của bạn bằng cách nào đó đang bị ít hơn có thể đọc được. Và tệ nhất là bạn đang bắt đầu kiệt sức với ứng dụng của mình.

Phải có trung gian. Vậy kiểm tra bao nhiêu là lượng phù hợp?

Sẽ thật tuyệt nếu bạn có thể sử dụng một con số tròn trịa đẹp như một quy tắc:số dòng mã thử nghiệm nhiều gấp đôi so với mã ứng dụng, hoặc phạm vi thử nghiệm là 95%. Nhưng ngay cả việc nói "mức độ phù hợp kiểm tra 95%" là không rõ ràng.

Mức độ phù hợp có thể là một chỉ báo mã được kiểm tra tốt, nhưng đó không phải là đảm bảo của mã được kiểm tra tốt. Tôi đã có các ứng dụng được bảo vệ 100% có nhiều lỗi hơn các ứng dụng có mức độ phù hợp 85%.

Vì vậy, số lượng thử nghiệm phù hợp không thể là một con số. Thay vào đó, đó là về một cái gì đó mờ hơn và khó xác định hơn. Đó là về kiểm tra hiệu quả .

Kiểm tra hiệu quả

Kiểm tra hiệu quả là tất cả về việc đạt được nhiều lợi ích nhất với số lượng công việc ít nhất. Nghe thật tuyệt phải không?

Nhưng có rất nhiều thứ cần được thử nghiệm hiệu quả hơn. Vì vậy, thật hữu ích khi nghĩ về ba điều cụ thể:kích thước, sự cô lập và tiêu điểm.

Kích thước

Các bài kiểm tra tích hợp thật tuyệt vời. Chúng phản ánh con đường mà một người thực tế đi qua ứng dụng của bạn. Họ kiểm tra tất cả mã của bạn, hoạt động cùng nhau, giống như cách mã được sử dụng trong thế giới thực.

Nhưng các bài kiểm tra tích hợp diễn ra chậm. Chúng có thể dài và lộn xộn. Và nếu bạn muốn kiểm tra kỹ lưỡng một phần nhỏ trong hệ thống của mình, chúng sẽ thêm rất nhiều chi phí.

Các bài kiểm tra đơn vị nhỏ hơn. Chúng chạy nhanh hơn. Dễ dàng nghĩ ra chúng vì bạn chỉ cần ghi nhớ một phần nhỏ của hệ thống trong đầu khi viết chúng.

Nhưng chúng cũng có thể là giả. Chỉ vì một cái gì đó hoạt động trong một thử nghiệm đơn vị không có nghĩa là nó cũng sẽ hoạt động trong thế giới thực. (Đặc biệt nếu bạn đang chế nhạo nhiều).

Vậy làm cách nào để bạn cân bằng những thứ đó?

Vì các bài kiểm tra đơn vị rất nhanh và dễ viết, nên không tốn nhiều chi phí để có nhiều chúng. Vì vậy, chúng là một nơi tuyệt vời để kiểm tra những thứ như các trường hợp phức tạp và logic phức tạp.

Khi bạn đã có một loạt các phần đã được kiểm tra tốt trong hệ thống của mình, bạn vẫn phải lấp đầy những khoảng trống. Bạn phải kiểm tra cách các phần đó tương tác và toàn bộ hành trình mà ai đó có thể thực hiện thông qua ứng dụng của bạn. Nhưng vì hầu hết các trường hợp và logic cạnh của bạn đều được kiểm tra bằng các bài kiểm tra đơn vị của bạn, bạn chỉ cần một vài trong số các bài kiểm tra tích hợp chậm hơn, phức tạp hơn này.

Bạn sẽ nghe thấy ý tưởng này được gọi là “Kim tự tháp thử nghiệm”. Đó là một vài bài kiểm tra tích hợp, nằm trên cơ sở của nhiều bài kiểm tra đơn vị. Và nếu bạn muốn tìm hiểu thêm về nó, hãy xem chương thứ ba của cuốn sách của tôi, Thực hành đường ray.

Isolation

Tuy nhiên, nếu hệ thống của bạn phức tạp, nó có thể giống như vô số thử nghiệm để bao gồm mọi tình huống bạn có thể gặp phải. Đây có thể là dấu hiệu cho thấy bạn cần xem xét lại thiết kế ứng dụng của mình. Có nghĩa là các phần trong hệ thống của bạn phụ thuộc quá chặt chẽ vào nhau.

Giả sử bạn có một đối tượng có thể ở một trong một số trạng thái khác nhau:

case user.type
when :admin
  message = admin_message
when :user
  message = user_message
when :author
  message = author_message
else
  message = anonymous_message
end

if user.preferred_notification_method = :email
  send_email(message)
elsif user.preferred_notification_method = :text
  send_text_message(message)
else
  queue_notification(message) 
end

Nếu bạn muốn kiểm tra mọi con đường có thể có ở đây, bạn sẽ có 12 tình huống khác nhau để kiểm tra:

  1. Người dùng là quản trị viên, preferred_notification_method là email
  2. Người dùng là quản trị viên, preferred_notification_method là văn bản
  3. Người dùng là quản trị viên, preferred_notification_method không
  4. Người dùng là người dùng, preferred_notification_method là email
  5. Người dùng là người dùng, preferred_notification_method là văn bản
  6. Người dùng là người dùng, preferred_notification_method không
  7. Người dùng là tác giả, preferred_notification_method là email
  8. Người dùng là tác giả, preferred_notification_method là văn bản
  9. Người dùng là tác giả, preferred_notification_method không
  10. Người dùng ẩn danh, preferred_notification_method là email
  11. Người dùng ẩn danh, preferred_notification_method là văn bản
  12. Người dùng ẩn danh, preferred_notification_method không

Có rất nhiều trường hợp cần kiểm tra vì “gửi tin nhắn dựa trên phương thức thông báo” và “tạo tin nhắn dựa trên kiểu người dùng” được gắn với nhau. Bạn có thể có thể thu hẹp với ít hơn, nhưng điều đó không rõ ràng - và nó chỉ yêu cầu các lỗi.

Nhưng điều gì sẽ xảy ra nếu bạn phá vỡ chúng?

message = get_message_based_on_user_type(user.type)

send_notification(message, user.preferred_notification_method)

Giờ đây, bạn có thể kiểm tra từng phần riêng biệt.

Đối với phần đầu tiên, bạn có thể kiểm tra xem thông báo phù hợp được trả về cho từng loại người dùng.

Đối với phần thứ hai, bạn có thể kiểm tra xem một tin nhắn nhất định có được gửi chính xác hay không dựa trên giá trị của preferred_notification_method .

Và cuối cùng, bạn có thể kiểm tra xem phương thức gốc sẽ chuyển thông báo được trả về từ do_stuff_based_on_user_type cùng với send_email_or_text . Vì vậy, bây giờ, bạn có 8 trạng thái để kiểm tra:

  1. Người dùng là quản trị viên
  2. Người dùng là một người dùng
  3. Người dùng là tác giả
  4. Người dùng ẩn danh
  5. preferred_notification_method là email
  6. preferred_notification_method là văn bản
  7. preferred_notification_method không
  8. và một thử nghiệm cho phương thức gốc

Tại đây, bạn lưu bốn bài kiểm tra bằng cách ngắt mã để bạn có thể kiểm tra riêng. Trong ví dụ thứ hai, rõ ràng hơn là bạn có thể vượt qua với ít thử nghiệm hơn. Và bạn có thể tưởng tượng khi bạn thêm nhiều trạng thái hơn, việc tách mã của bạn thành một ý tưởng thậm chí còn tốt hơn.

Cần có thời gian và thực hành trước khi bạn tìm thấy sự cân bằng tốt nhất giữa tính riêng biệt và khả năng đọc. Nhưng nếu bạn phá vỡ sự phụ thuộc của mình đúng chỗ, bạn có thể vượt qua với ít thử nghiệm hơn.

Tiêu điểm

Ứng dụng của bạn phải được thử nghiệm tốt. Nhưng điều đó không có nghĩa là mọi phần trong ứng dụng của bạn đều đáng được chú ý như nhau trong các bài kiểm tra.

Ngay cả khi bạn nhắm đến phạm vi kiểm tra 100%, bạn vẫn sẽ không kiểm tra mọi thứ. Chẳng hạn, bạn có thể sẽ không kiểm tra mọi dòng văn bản trong chế độ xem của mình hoặc bạn đang thăm dò ý kiến ​​cập nhật cứ 5 giây một lần thay vì 10 dòng.

Đó là nơi tập trung vào. Viết ít bài kiểm tra hữu ích hơn. Và đưa ra quyết định tỉnh táo, nơi bạn có thể dành thời gian tốt nhất cho mình.

Tập trung là một thứ khác khó làm đúng. Đây là một vài câu hỏi tôi tự hỏi bản thân để giúp tôi tập trung vào các bài kiểm tra quan trọng nhất:

  • Điều này được kết nối với nhau như thế nào với phần còn lại của ứng dụng của tôi? Nếu nó bị vỡ, bao nhiêu mảnh khác sẽ bị vỡ cùng với nó?

  • Khả năng điều này sẽ thay đổi một cách tự nhiên như thế nào? Nếu các thử nghiệm của tôi không thành công, đó là do lỗi hay do ai đó đã cập nhật một số văn bản trong giao diện người dùng?

  • Tác động của việc phá vỡ này là gì? Tôi sẽ tính phí thẻ tín dụng của ai đó hai lần hay chỉ là kết thúc với một số văn bản bị thiếu?

  • Phần này được sử dụng thường xuyên như thế nào? Nó có quan trọng đối với hành vi của ứng dụng hay là một trang giới thiệu bị chôn vùi ở đâu đó trong chân trang?

Bạn không nên chỉ kiểm tra các bộ phận quan trọng. Nhưng bạn sẽ có một ứng dụng cảm thấy chất lượng cao hơn nếu bạn dành thời gian thử nghiệm tốt.

Nếu bạn cố gắng kiểm tra mọi con đường có thể mà ai đó có thể đi qua ứng dụng của bạn, bạn sẽ không bao giờ giao hàng. TDD hữu ích, nhưng nó sẽ không giải quyết được tất cả các vấn đề thử nghiệm của bạn.

Tất nhiên, điều đó không có nghĩa là bạn hoàn toàn không nên thử nghiệm.

Bạn có thể sử dụng kim tự tháp thử nghiệm để giữ cho các thử nghiệm của bạn nhỏ. Bạn có thể cô lập và phá vỡ các phần phụ thuộc để chuyển m * n các trường hợp thử nghiệm thành m + n . Và bạn có thể sắp xếp thứ tự ưu tiên để có thể dành nhiều thời gian hơn để kiểm tra các phần quan trọng nhất của ứng dụng.

Vì vậy, bao nhiêu bạn kiểm tra? Bạn có cân nhắc bất kỳ ý tưởng nào trong số này khi xây dựng ứng dụng của mình không? Và làm cách nào để bạn biết cần tập trung vào những phần nào của ứng dụng? Để lại nhận xét và cho tôi biết tất cả về điều đó!