Bạn có viết bài kiểm tra đơn vị cho tất cả thời gian trong TDD không?


8

Tôi đã thiết kế và phát triển mã với phong cách TDD trong một thời gian dài. Điều làm tôi băn khoăn về TDD là viết các bài kiểm tra cho mã không chứa bất kỳ logic kinh doanh hoặc hành vi thú vị nào. Tôi biết TDD là một hoạt động thiết kế nhiều hơn thử nghiệm nhưng đôi khi tôi cảm thấy thật vô ích khi viết thử nghiệm trong các kịch bản này.

Ví dụ: tôi có một kịch bản đơn giản như "Khi người dùng nhấp vào nút kiểm tra, nó sẽ kiểm tra tính hợp lệ của tệp" . Đối với kịch bản này, tôi thường bắt đầu viết các bài kiểm tra cho lớp người trình bày / trình điều khiển như lớp dưới đây.

@Test
public void when_user_clicks_check_it_should_check_selected_file_validity(){
    MediaService service =mock(MediaService);
    View view =mock(View);

    when(view.getSelectedFile).thenReturns("c:\\Dir\\file.avi");

    MediaController controller =new MediaController(service,view);
    controller.check();

    verify(service).check("c:\\Dir\\file.avi");
}

Như bạn có thể thấy không có quyết định thiết kế hoặc mã thú vị để xác minh hành vi. Tôi đang kiểm tra các giá trị từ chế độ xem được chuyển đến MediaService. Tôi thường viết nhưng không thích những bài kiểm tra kiểu này. Bạn làm gì về những tình huống này? Bạn có viết bài kiểm tra cho tất cả các thời gian?

CẬP NHẬT:

Tôi đã thay đổi tên và mã kiểm tra sau khi khiếu nại. Một số người dùng nói rằng bạn nên viết bài kiểm tra cho các trường hợp tầm thường như thế này để trong tương lai ai đó có thể thêm hành vi thú vị. Nhưng những gì về Code Code cho ngày hôm nay, thiết kế cho ngày mai. ? Nếu ai đó, bao gồm cả tôi, thêm mã thú vị hơn trong tương lai, bài kiểm tra có thể được tạo cho nó sau đó. Tại sao tôi phải làm điều đó ngay bây giờ cho các trường hợp tầm thường?


1
"Một số người dùng nói rằng bạn nên viết các bài kiểm tra cho các trường hợp tầm thường như thế này để trong tương lai ai đó có thể thêm các hành vi thú vị. Nhưng những gì về Code Code cho ngày hôm nay, thiết kế cho ngày mai. ? "Phản bác rực rỡ! +1
maple_shaft

Câu trả lời:


5

Tôi không nhắm đến 100% bảo hiểm mã. Và tôi thường không viết các bài kiểm tra về các phương thức rõ ràng sẽ không chứa bất kỳ logic nghiệp vụ nào và / hoặc nhiều hơn một vài dòng mã. Nhưng tôi vẫn viết các bài kiểm tra đơn vị (sử dụng TDD) của các phương thức có vẻ không phức tạp. Điều này chủ yếu là vì tôi muốn có bài kiểm tra đơn vị, khi quay lại mã đó hàng tháng hoặc thậm chí nhiều năm sau đó, và muốn làm cho nó phức tạp hơn. Luôn luôn dễ dàng hơn để mở rộng các thử nghiệm hiện tại, hơn là phải xây dựng tất cả từ đầu. Như Noufal đã nói, đó là chủ quan. Lời khuyên của tôi là viết các bài kiểm tra, nếu bạn nghĩ rằng phương pháp này hơi phức tạp hoặc có khả năng trở nên phức tạp hơn.


2

Đây là câu hỏi TDD thứ hai ngày hôm nay truyền tải sự khó chịu ở số lượng bài kiểm tra được viết.

"Chỉ kiểm tra nếu bạn muốn nó hoạt động."

Tôi không thực sự chắc chắn tôi hiểu bài kiểm tra trong câu hỏi.

Bạn có đang kiểm tra rằng Đại biểu điều khiển.Check () cho dịch vụ (phụ thuộc) với đối số là giá trị tệp đã chọn từ chế độ xem không? Nếu có, Đây là một thử nghiệm tốt. Nó cho phép bạn kiểm tra bộ điều khiển mà không cần thực hiện dịch vụ thực tế. (kiểm tra vi mô dựa trên tương tác).

Cập nhật: Bây giờ tôi đã rõ về những gì bạn đang cố kiểm tra, có lẽ tôi sẽ di chuyển một số mã xung quanh và đổi tên một số thứ để nó có nội dung "Kiểm tra phương tiện kiểm tra phương tiện kiểm tra tệp được chọn vào dịch vụ phương tiện." - đó là một thông số hợp lệ cho bộ điều khiển.

public class TestMediaController

@Test
public void DelegatesSelectedFileCheckToMediaService(){
    string selectedMediaFileInView = "c:\\Dir\\file.avi";

    when(_view.getSelectedFile).thenReturns(selectedMediaFileInView);

    new MediaController(_service, _view).check();

    verify(_service).check(selectedMediaFileInView);
}

Có Nó đại biểu cho lớp dịch vụ.

Nhưng câu hỏi: có đáng để viết bài kiểm tra này để chỉ xác minh tham số được truyền từ chế độ xem sang lớp dịch vụ không?

@ Có - nó kiểm tra xem check () có dây chính xác không. Cần có một thử nghiệm khác mà Service.Check () hoạt động sau khi nhận được cuộc gọi. Thử nghiệm này có vẻ tầm thường ngày hôm nay nhưng khi thời gian trôi qua, ai đó có thể thêm nhiều mã hơn vào phương thức này (ví dụ: mệnh đề bảo vệ nếu một số điều kiện trở lại;) và phá vỡ hành vi hiện có. Thử nghiệm này bảo vệ an toàn chống lại điều đó.
Gishu

Ok tôi đã nhận được ý kiến ​​của bạn nhưng những gì về Code Code cho ngày hôm nay, thiết kế cho ngày mai. ? Nếu ai đó hoặc tôi thêm mã thú vị hơn trong tương lai tôi có thể tạo thử nghiệm cho nó sau đó. Tại sao tôi phải làm điều đó ngay bây giờ cho các trường hợp tầm thường?

1
@mcaaltuntas: toàn bộ quan điểm của TDD là bạn kiểm tra đặc tả kỹ thuật hiện tại, để nếu thay đổi mã trong tương lai không còn thỏa mãn thông số kỹ thuật hiện tại, bạn hãy tìm hiểu về nó. Cho dù bây giờ bạn nghĩ việc triển khai thông số kỹ thuật dễ đến mức nào, thì trong tương lai ai đó có thể thay đổi mã mà không cần chú ý đến yêu cầu cụ thể này, trong trường hợp họ có thể phá vỡ nó và họ sẽ không nhận ra rằng họ cần thêm thử nghiệm cho nó . Nếu bạn không viết bài kiểm tra ngay bây giờ, thì bạn không làm TDD. Nếu bạn không muốn kiểm tra toàn bộ thông số, đó là cuộc gọi của bạn, nhưng bạn không áp dụng TDD cho phần đó.
Steve Jessop

1

Tôi sẽ không viết một bài kiểm tra như thế (hoặc ít nhất là tôi sẽ không đặt tên cho nó như thế). Thay vào đó, tôi sẽ viết một bài kiểm tra cho tính năng yêu cầu cuộc gọi đó check(), để nếu kiểm tra đó hoặc một hành động tương đương không được thực hiện, tính năng cấp cao sẽ không hoạt động. Tại sao mã của bạn cần gọi check()phương thức?

Nói chung, tôi cố gắng giữ các thử nghiệm tách rời khỏi các chi tiết triển khai, để ít nhất tên của thử nghiệm chỉ nói về các tính năng bên ngoài do đối tượng cung cấp. Chi tiết thực hiện như các đối tượng và phương thức không được đề cập trong tên thử nghiệm.

Điều này giúp thực hiện tái cấu trúc dễ dàng hơn (không cần thay đổi kiểm tra khi bạn thay đổi triển khai) và nó cũng sẽ giúp bạn dễ dàng tìm hiểu xem thử nghiệm đã hết hạn chưa (tính năng mà nó chỉ định không còn cần thiết nữa) . Nó cũng sẽ giúp dễ dàng nhận thấy mã không cần thiết / mã chết, bởi vì bản tóm tắt mức thấp (chẳng hạn như getters và setters) sẽ chỉ được thêm / giữ nếu chúng được yêu cầu bởi các tính năng cấp cao hơn.


Ok. Bạn nói đúng về cách đặt tên, bạn có thể nghĩ về tên của nó "khi người dùng nhấp vào kiểm tra thì nên kiểm tra thuộc tính của tệp đã chọn". Nhưng câu hỏi không phải là về cách đặt tên Bạn có viết bài kiểm tra cho mã "rõ ràng" hay không

Tôi đã thay đổi tên thử nghiệm nhưng câu hỏi vẫn còn.

Hệ thống nên làm gì, nếu kiểm tra thất bại? Ném một ngoại lệ hay cái gì khác? Tôi có thể sẽ viết hai bài kiểm tra: điều gì xảy ra khi tập tin hợp lệ và khi nó không hợp lệ. Nếu có nhiều cách một tệp có thể không hợp lệ, tôi sẽ viết các bài kiểm tra đó trực tiếp với MediaService.
Esko Luontola

Có Probaby Tôi cũng sẽ viết hai bài kiểm tra nhưng không chống lại lớp Trình điều khiển, tôi sẽ viết chúng chống lại (như bạn đã nói) lớp MediaService. Vì vậy, trên thực tế kiểm tra chỉ xác minh lớp dịch vụ đã được gọi với các tham số từ chế độ xem. Bạn có nghĩ rằng đáng để viết bài kiểm tra này để chỉ xác minh các đối số được truyền từ chế độ xem sang lớp dịch vụ không?

"Bạn có nghĩ rằng đáng để viết bài kiểm tra này để chỉ xác minh các đối số được truyền từ chế độ xem sang lớp dịch vụ không?" Nó phụ thuộc. Nếu có các kiểm tra đầu cuối tại chỗ để đảm bảo rằng kiểm tra hoạt động (nghĩa là nó đưa ra thông báo lỗi hoặc một cái gì đó khi tệp không hợp lệ), thì đối với kiểm tra đơn vị của bộ điều khiển, có thể chỉ cần kiểm tra phương thức đó được gọi là; nó sẽ bảo vệ nhanh hơn trong quá trình tái cấu trúc so với các thử nghiệm từ đầu đến cuối.
Esko Luontola

0

Đây là chủ quan. Tôi không phải lúc nào cũng làm TDD nhưng khi tôi làm, tôi cố gắng giữ phạm vi bảo hiểm mã làm số liệu của mình để kiểm tra xem toàn diện hay không. Đôi khi, tôi trở nên lười biếng và chỉ đơn giản là bỏ qua những phần mà đối với tôi có vẻ "rõ ràng". Đôi khi, tôi vi phạm chu kỳ Đỏ, Xanh lục, Tái cấu trúc và viết nhiều mã hơn mức cần thiết nhưng theo thời gian, tôi đã hòa vào nhịp điệu hơn là tôi thấy thoải mái.


0

Tương tác giữa các lớp như trên và bản gốc đơn giản hơn tôi sẽ viết một bài kiểm tra cho. Các tương tác có thể trở nên phức tạp hơn theo thời gian vì vậy có công việc mặt đất tại chỗ là một điều tốt.


0

Nếu ai đó hoặc tôi thêm mã thú vị hơn trong tương lai tôi có thể tạo thử nghiệm cho nó sau đó. Tại sao tôi phải làm điều đó ngay bây giờ cho các trường hợp tầm thường?

Bạn cho rằng trong tương lai sẽ có người biết rằng phần tử UI này tồn tại và những gì nó gọi trên phần phụ trợ.

Dự án hiện tại của tôi có hơn 30 nhà phát triển trên sáu nhóm riêng biệt trong cùng một cơ sở mã. Bổ sung UI tầm thường biến mất trong sương mù mọi lúc. Không ai sẽ quay lại và thêm một trường hợp thử nghiệm cho điều này sau này bởi vì không ai sẽ nhớ nó ở đó và khi nó phá vỡ nhu cầu trở thành "Tại sao họ không viết một bài kiểm tra? Nó sẽ rất đơn giản!"


0

Như thường lệ...

Nó phụ thuộc

Thật khó để thấy sự hữu ích của thử nghiệm cụ thể này trong bối cảnh TDD vì chúng ta không biết câu chuyện.

Nếu câu chuyện là [người dùng phương tiện] Tôi muốn [có thể kiểm tra tính hợp lệ của phương tiện] Để [Tôi sẽ biết khi nào tệp không có sẵn]

sau đó kịch bản được đưa ra [một nút phương tiện kiểm tra] Khi [người dùng nhấp vào nút] Sau đó [tính hợp lệ của tệp được chọn]

có ý nghĩa. Nó tầm thường, nhưng nó có ý nghĩa.

Nếu câu chuyện bao quát lớn hơn câu chuyện này, thì định nghĩa kịch bản có thể quá hẹp.

Nhớ lại:

TDD! = Kiểm tra đơn vị

Tính năng kiểm tra TDD . Nếu đó là một tính năng, thì nó xứng đáng được thử nghiệm để xác minh 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.