Làm thế nào để đối phó với bài kiểm tra chuyển từ đầu trong TDD


8

Tôi đang cố gắng thực hành TDD trong dự án cá nhân của mình và tôi tự hỏi làm thế nào để xử lý tình huống khi sau khi thêm thử nghiệm mới, nó sẽ vượt qua từ đầu dựa trên việc thực hiện hiện tại?

Một mặt, thử nghiệm mới có thể cung cấp tài liệu bổ sung về thiết kế và bảo vệ khỏi sự vi phạm ngẫu nhiên các giả định.

Mặt khác, nếu vượt qua kiểm tra mà không có bất kỳ thay đổi mã nào thì đó là "nghi ngờ" liệu nó có thực sự kiểm tra những gì cần làm hay không.

Về cơ bản những gì có thể được thực hiện để xác nhận tính đúng đắn của bài kiểm tra khẳng định hành vi đã thực hiện?


5
Cách tiếp cận yêu thích của tôi là kiểm tra đột biến, tôi thay đổi mã được kiểm tra và kiểm tra xem thử nghiệm có bắt đầu không hay không
gnat

2
@gnat - Tôi tin rằng có một số chồng chéo nhưng tôi không cảm thấy đó là cùng một câu hỏi. Ở đây tôi đang hỏi cụ thể về TDD và tôi tin rằng "Nếu bạn thấy mình trong tình huống như vậy thì Bạn đang làm TDD sai vì ..." sẽ là một câu trả lời hợp lệ.
Phản hồi

5
không thành vấn đề vì bạn chưa làm TDD khi bạn viết bài kiểm tra đối với việc triển khai đã có (và hoạt động chính xác)
gnat

2
"và những gì bạn làm khi bạn gặp phải điều đó?" Tôi chạy thử nghiệm mới (chỉ điều này) với một công cụ bảo hiểm và kiểm tra xem đường dẫn dự kiến ​​đã được thực thi chưa. Quay trở lại chỉ là một lựa chọn nếu bạn làm dự án để đào tạo. BTW: Ngày toàn cầu của Coderetreat là một cơ hội tuyệt vời để thực hành TDD ...
Timothy Truckle

2
@ Solomonoff'sSecret cá nhân, tôi không tin bất kỳ bài kiểm tra nào tôi chưa thấy thất bại.
RubberDuck

Câu trả lời:


13

Vượt qua một bài kiểm tra từ thời điểm bạn viết nó có thể là một vấn đề với quy trình TDD của bạn, nhưng bản thân nó không có nghĩa là nó sai.

Bài kiểm tra của bạn có thể vượt qua ngẫu nhiên.

Giả sử bạn có một phương thức trả lại chi phí rút tiền bằng ATM. Bây giờ bạn được yêu cầu thêm vào quy tắc mới rằng nếu chủ sở hữu thẻ trên 60 tuổi, chi phí là 0. Vì vậy, chúng tôi kiểm tra nó, hy vọng nó sẽ thất bại:

assertTrue(ATM.withdrawalCost(clientOver60) == 0)

Bạn có thể mong đợi điều này thất bại. Nhưng nó đã qua, vì khách hàng tình cờ là khách hàng VIP, người đã rút tiền miễn phí. Bây giờ bạn có thể quay lại phương thức rút tiền và sửa đổi nó để làm cho nó thất bại, nhưng điều đó không thực sự có ý nghĩa nhiều. Viết một bài kiểm tra mới để hiển thị mã của bạn là sai:

assertTrue(ATM.withdrawalCost(nonVIPclientOver60) == 0)

Bây giờ nó thất bại, bạn đi và mã cho đến khi nó đi qua, sau đó lặp lại cho đến khi hoàn thành.

Bạn có nên xóa bài kiểm tra sau đó, vì nó không có sự khác biệt? Không! Nó mô tả chức năng dự kiến ​​của phương thức rút tiền ATM. Nếu bạn xóa nó và một ngày nào đó, chi phí rút tiền 0 cho khách hàng VIP thay đổi, khẳng định đầu tiên vẫn là đúng.

Đã nói điều này, đối với TDD thích hợp, bạn không nên mã hóa mọi thứ trước các bài kiểm tra của mình và sau đó kiểm tra những điều bạn biết bạn sẽ vượt qua. Tôi không xem xét trường hợp này bạn đang hỏi về.

Tôi tin rằng chu trình chuyển mã không thành công có nghĩa là để tránh "Tôi sẽ viết 3 bài kiểm tra này sẽ thất bại và 2 bài kiểm tra này sẽ vượt qua vì tôi đã mã hóa nó để biết bài kiểm tra sẽ là gì". Bạn nên biết một số người có thể cảm thấy khác. Nghe lý do của họ, họ có thể có giá trị quá.


10

Các thử nghiệm vượt qua ngay từ đầu thường sẽ xảy ra khi một người thực hiện một cái gì đó theo cách tổng quát hơn là thực sự cần thiết cho các thử nghiệm trong tay. Điều này khá bình thường : các bài kiểm tra đơn vị chỉ có thể cung cấp một số lượng nhỏ các giá trị đầu vào hữu hạn cho một hàm nhất định, nhưng hầu hết các hàm được viết cho một phạm vi lớn các giá trị đầu vào có thể. Thường thì việc triển khai được thiết kế riêng cho các trường hợp thử nghiệm hiện tại sẽ phức tạp hơn một giải pháp tổng quát hơn. Nếu đó là trường hợp, nó sẽ cồng kềnh và dễ bị lỗi khi thiết kế mã một cách giả tạo theo cách chỉ hoạt động cho các trường hợp thử nghiệm và thất bại cho mọi thứ khác.

Ví dụ: giả sử bạn cần một hàm để trả về mức tối thiểu của một số giá trị từ một mảng nhất định. Bạn đã thực hiện, được điều khiển bởi một thử nghiệm với một mảng chỉ chứa một hoặc hai giá trị. Nhưng thay vì thực hiện điều này một cách phức tạp bằng cách so sánh các yếu tố khác nhau (có thể chỉ là hai yếu tố đầu tiên), bạn gọi một hàm tối thiểu từ thư viện chuẩn của hệ sinh thái ngôn ngữ của bạn và do đó hãy thực hiện một lớp lót . Khi bạn quyết định thêm một bài kiểm tra với một mảng năm phần tử, bài kiểm tra có thể sẽ vượt qua ngay từ đầu.

Nhưng làm thế nào để bạn biết sau đó bài kiểm tra không "xanh" vì một lỗi trong chính bài kiểm tra? Một cách đơn giản và dễ hiểu để tiếp cận điều này là bằng cách sửa đổi tạm thời đối tượng đang thử nghiệm để làm cho thử nghiệm thất bại. Ví dụ, bạn có thể cố ý thêm một dòng if (array.size()==5) return 123vào chức năng của bạn. Bây giờ bài kiểm tra năm yếu tố của bạn sẽ thất bại, vì vậy bạn biết

  • bài kiểm tra được thực hiện
  • lệnh xác nhận trong kiểm tra được thực hiện
  • cuộc gọi Khẳng định trong bài kiểm tra xác nhận điều đúng

mà sẽ cung cấp cho bạn một số sự tự tin vào bài kiểm tra. Sau khi bạn thấy thử nghiệm thất bại, hãy hoàn tác sửa đổi và thử nghiệm sẽ vượt qua một lần nữa.

Ngoài ra, bạn có thể sửa đổi kết quả dự kiến ​​của một bài kiểm tra: giả sử bài kiểm tra vượt qua của bạn có chứa một xác nhận như

 int result = Subject.UnderTest(...);
 Assert.AreEqual(1,result);

sau đó bạn có thể chỉnh sửa kiểm tra và thay thế "1" bằng "2". Khi thử nghiệm thất bại (như mong đợi), bạn biết nó hoạt động như bình thường và bạn có thể hoàn tác thay thế và xem thử nghiệm bây giờ có chuyển sang màu xanh không. Nguy cơ đưa lỗi vào thử nghiệm bằng cách thay thế như vậy là rất nhỏ, vì vậy điều này có thể được chấp nhận đối với hầu hết các trường hợp trong thế giới thực.

Một cách khác, có thể gây tranh cãi, là đặt điểm dừng vào thử nghiệm và sử dụng trình gỡ lỗi để bước qua nó. Điều đó cũng sẽ cung cấp cho bạn một số niềm tin mã kiểm tra thực sự được thực thi và cung cấp cho bạn khả năng xác thực đường dẫn thông qua kiểm tra bằng cách kiểm tra từng bước. Tuy nhiên, người ta phải rất cẩn thận để không bỏ qua các lỗi trong đường dẫn mã cụ thể cho một thử nghiệm thất bại. Đối với các thử nghiệm phức tạp, bạn có thể cân nhắc thực hiện cả hai - làm cho nó thất bại một cách giả tạo sử dụng trình gỡ lỗi để kiểm tra nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.