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

Điều gì đã xảy ra với phạm vi kiểm tra của tôi?

Viết mã cảm thấy dễ dàng hơn nhiều so với viết các bài kiểm tra cho nó và thực hiện phương pháp một dòng thực sự cần phải được kiểm tra, dù sao? Thật là tầm thường! Bất kỳ thử nghiệm nào bạn thêm vào sẽ chỉ tăng gấp đôi hoặc gấp ba thời gian phát triển và lần sau khi bạn thay đổi mã, bạn cũng sẽ phải thay đổi thử nghiệm. Nó có vẻ như là một sự lãng phí, đặc biệt là khi bạn chỉ còn lại một chút thời gian cho ước tính của mình.

Nhưng ngay sau đó, mã của bạn chỉ được kiểm tra 20% và bất kỳ thay đổi nào bạn thực hiện đối với mã của mình đều giống như đang cố gắng thay thế lớp giữa của vô số thẻ mà không làm hỏng toàn bộ. Ở một nơi nào đó, đã xảy ra sự cố và mặc dù các quyết định bạn đưa ra có vẻ đúng vào thời điểm đó, nhưng cuối cùng bạn vẫn nhận được một cơ sở mã hoàn toàn không thể xác minh được.

Bạn đến đây bằng cách nào? Bạn muốn các thử nghiệm của mình cung cấp một mạng lưới an toàn và cho phép bạn tự tin cấu trúc lại. Họ lẽ ra phải giúp làm cho mã của bạn tốt hơn! Thay vào đó, bạn quay lại mức độ phù hợp thử nghiệm thấp về mã mà bạn không hiểu nữa và các thử nghiệm bạn đã thực hiện bằng cách nào đó khiến nó trở nên khó hơn để thay đổi mã.

Đây không phải là một thất bại về kỹ năng. Nó xảy ra với những nhà phát triển giỏi nhất. Đó là một quy trình thất bại. Với một vài thay đổi trong cách bạn viết các tính năng mới, bạn có thể bảo vệ mã của mình mà không làm chậm quá trình kiểm tra của bạn. Các bài kiểm tra của bạn có thể làm cho mã của bạn dễ hiểu hơn và linh hoạt hơn. Bạn sẽ có thể tự tin thay đổi mã của mình, biết mọi đường dẫn qua nó đều được kiểm tra.

Bạn không cần phải đưa ra quyết định

Nếu bạn đang ngồi vào bàn phím của mình để cố gắng quyết định cho dù một chút mã cần được kiểm tra, bạn đã đi sai đường. Yousho nên luôn mặc định là "Kiểm tra nó!" Ngay cả khi bài kiểm tra giọng điệu có vẻ quá tầm thường, hãy viết bài kiểm tra.

Nếu mã không thể viết được, nó sẽ dễ kiểm tra. Mã phức tạp sẽ không bao giờ có vẻ tầm thường như ngay sau khi bạn viết. Làm thế nào để bạn biết nó vẫn có vẻ tầm thường trong sáu tháng kể từ bây giờ?

Nhưng bạn không muốn kiểm tra quá mức

Một bộ thử nghiệm khổng lồ có thể là vấn đề của riêng nó. Các bài kiểm tra mất 20 phút để chạy cũng tốt như không có bài kiểm tra nào cả, vì bạn sẽ không bị lỗi mọi lúc. (Bạn nói bạn sẽ làm, nhưng tôi biết bạn sẽ không làm như vậy). Tệ hơn nữa, nếu bạn có quá nhiều thử nghiệm giòn, việc tái cấu trúc sẽ trở nên khó khăn hơn trước, vì vậy bạn sẽ không làm điều đó. Bạn sẽ kết thúc với các phương pháp dài hơn hầu hết các tiểu thuyết.

Điều này có mâu thuẫn với quan điểm trước đó của tôi không? Không cần thiết. Thử nghiệm của bạn nên luôn tập trung vào giao diện mã của bạn , không phải triển khai . Ví dụ:

class Cart
  def initialize(item_params)
    @line_items = Array(item_params).map {|item| LineItem.new(item[:name], item[:price])}
  end

  def total
    @line_items.sum(&:price)
  end
end

Có vẻ như mã ở đây cần phải kiểm tra cả Cart class và LineItem lớp. Nhưng là LineItem lớp học được sử dụng bởi anyelse? Nếu đó chỉ là chi tiết triển khai của Cart và không tiếp xúc với thế giới bên ngoài, nó thực sự cần bao nhiêu bài kiểm tra? Không thể chỉ kiểm tra thông qua Cart của bạn lớp học?

Các lớp được trích xuất bằng cách cấu trúc lại thường không cần bộ công cụ tốt nhất của chúng. Chúng chỉ là một chi tiết triển khai. Chỉ khi nào chúng được sử dụng riêng thì chúng mới cần những bài kiểm tra bổ sung đó.

Với một bộ thử nghiệm tuyệt vời dựa trên giao diện công khai, bạn có thể linh hoạt để thay đổi cách triển khai của mình mà không cần viết lại tất cả các thử nghiệm của mình. Bạn có thể làm điều này với ít nỗ lực hơn rất nhiều so với viết thậm chí là trung bình bộ thử nghiệm dựa trên việc triển khai đối tượng của bạn.

Phân bổ chi phí thử nghiệm của bạn với Phát triển theo hướng thử nghiệm

Trong phần đầu tiên, bạn đã học được rằng bạn nên kiểm tra mọi thứ. Trong phần thứ hai, bạn đã học được rằng bạn chỉ nên thử nghiệm các giao diện công cộng. It’sTest-Driven Development mang hai mục tiêu đối lập này lại với nhau.

Với Phát triển theo hướng thử nghiệm, các thử nghiệm của bạn thúc đẩy thiết kế và thực hiện mã của bạn bằng cách thực hiện theo quy trình sau:

  1. Viết một bài kiểm tra không thành công với giả định rằng mã bạn cần đã ở đó.
  2. Viết cách triển khai mã đơn giản nhất để vượt qua bài kiểm tra.
  3. Refactor để loại bỏ sự trùng lặp (hoặc làm cho mã biểu cảm hơn).
  4. Chạy lại các bài kiểm tra (để đảm bảo chúng vẫn vượt qua).
  5. Quay lại bước 1.

Bằng cách làm theo các bước này, bạn sẽ kiểm tra mọi thứ (vì không có mã nào được viết nếu không có bài kiểm tra thất bại), trong khi chỉ kiểm tra các giao diện công cộng (vì bạn không viết các bài kiểm tra mới ngay sau khi cấu trúc lại).

Nó không bao giờ chính xác là dễ dàng như vậy. Nhưng vẫn có những cách để lái thử ngay cả những đoạn mã phức tạp nhất.

TDD có một số lợi ích phụ:

  • Bạn sẽ thấy mình có một mô hình đối tượng được thử nghiệm, linh hoạt hơn (đây được cho là chính lợi ích).
  • Theo định nghĩa, hệ thống của bạn có thể kiểm tra được, giúp cho việc viết các bài kiểm tra trong tương lai ít tốn kém hơn.
  • Bạn phân bổ chi phí thử nghiệm của mình trong suốt quá trình phát triển, làm cho các ước tính của bạn chính xác hơn.
  • Nó giúp bạn luôn trôi chảy, bởi vì bạn không bao giờ phải quyết định phải làm gì tiếp theo.

Vậy làm cách nào để bắt đầu?

Bắt đầu là phần khó! Khi bạn đã bắt kịp nhịp viết mã theo hướng kiểm tra, bạn sẽ khó có thể dừng lại.

Lần tới khi bạn làm việc trên một tính năng mới, hãy thử làm theo các bước TDD. Bạn sẽ thấy mình có độ phủ mã gần như 100% với lượng công việc ít nhất có thể, bạn sẽ có một nền tảng vững chắc để xây dựng và bạn sẽ hoàn toàn tin tưởng rằng bộ thử nghiệm của mình sẽ bảo vệ bạn khi bạn phải thay đổi mã tiếp theo năm. Hoặc muộn hơn ngày hôm nay, khi các yêu cầu của bạn lại thay đổi.

Khi bạn hoàn tất, hãy gửi email cho tôi và cho tôi biết tình hình diễn ra như thế nào.

Bằng cách tuân theo quy trình thử nghiệm đơn giản, bạn có thể dành ít thời gian hơn để đưa ra các quyết định đơn giản và tìm ra lỗi, đồng thời có nhiều thời gian hơn để viết mã giải quyết nhu cầu của khách hàng và doanh nghiệp của bạn.