2011-12-06 17 views
6

Gần đây tôi đã tham gia một công ty nơi họ sử dụng TDD, nhưng nó vẫn còn chưa rõ ràng đối với tôi, ví dụ, chúng ta có một bài kiểm tra:Tại sao thử nghiệm cụ thể này có thể hữu ích?

[TestMethod] 
public void ShouldReturnGameIsRunning() 
{ 
    var game = new Mock<IGame>(); 
    game.Setup(g => g.IsRunning).Returns(true); 
    Assert.IsTrue(game.Object.IsRunning); 
} 

mục đích của nó là gì? Theo như tôi hiểu, đây là thử nghiệm không có gì! Tôi nói rằng vì nó chế nhạo một giao diện, và nói rằng, trả về true cho IsRunning, nó sẽ không bao giờ trả về một giá trị khác ...

Tôi có thể nghĩ sai, như mọi người nói đó là một thực hành tốt, v.v ... hoặc là thử nghiệm này sai?

+3

Thông thường không phải là vô nghĩa này. – sarnold

+3

Bạn có hai điều khác nhau đang xảy ra trong câu hỏi này - "Mục đích của TDD là gì?" và "Điểm của bài kiểm tra này là gì?" - hãy cẩn thận để hai người tách biệt trong đầu của bạn. Giá trị (hoặc không) của TDD không thể được đánh giá một cách công bằng từ một thử nghiệm đơn lẻ (có thể là người nghèo). – Bevan

+0

Tôi ước tôi có thể đóng tài khoản này dưới dạng bản sao của http://stackoverflow.com/questions/tagged/tdd?sort=votes&pagesize=50 –

Trả lời

5

Bài kiểm tra không hợp lệ. Moq là một khuôn khổ được sử dụng để "giả" các đối tượng được sử dụng bởi phương pháp được thử nghiệm. Nếu bạn đang thử nghiệm IsRunning, bạn có thể sử dụng Mock để cung cấp triển khai nhất định cho những phương thức mà IsRunning phụ thuộc vào, ví dụ như để gây ra một số đường dẫn thực thi nhất định để thực thi.

Mọi người có thể nói với bạn cả ngày rằng thử nghiệm đầu tiên tốt hơn; bạn sẽ không nhận ra rằng nó thực sự là cho đến khi bạn bắt đầu tự mình thực hiện và nhận ra rằng bạn có ít lỗi hơn với mã bạn đã viết thử nghiệm đầu tiên, điều này sẽ giúp bạn tiết kiệm thời gian và đồng nghiệp của bạn và có thể làm cho chất lượng mã của bạn cao hơn.

+0

hmm Tôi nghi ngờ rằng ... có một giao diện IGame không được kiểm tra, đó là lý do tại sao tôi không nhận được ý tưởng về điều này ... – user1082693

+0

không có ý nghĩa gì về việc thực hiện một giao diện IGame khác, họ nên thử nghiệm đối tượng Game thay vì giao diện, phải không? Làm thế nào về việc lái xe thiết kế mã? Tôi có nghĩa là, làm thế nào tôi nên xác định rằng phải có một tài sản IsRunning? – user1082693

+0

@ user1082693: Đúng. Bây giờ nếu bạn đang thử nghiệm hành vi của phương thức dựa trên một số giá trị trả về của phương thức 'IGame', thì Moq chắc chắn sẽ có ích - tạo ra một phân lớp hoàn toàn mới của' IGame' chỉ cho mục đích thử nghiệm sẽ chứng minh đau đớn. Đối với thử nghiệm cho một thuộc tính nhất định, tôi sẽ cho phép các cấu trúc mã như giao diện và các lớp trừu tượng thực thi các quy tắc đó. –

3

Có thể là bài kiểm tra đã được viết (trước) mã thực hành tốt.

Cũng có thể là đây là một thử nghiệm vô nghĩa được tạo bởi một công cụ.

+0

Tôi không nghĩ rằng có bất kỳ công cụ nào tạo ra bài kiểm tra ở đây, vì vậy có thể họ đã viết bài kiểm tra trước mã sau đó .. hmmm – user1082693

+6

Phụ thuộc vào định nghĩa của bạn về "công cụ"! :) – griegs

+3

+1 và chúng tôi có thể có nghĩa là ý nghĩa phổ biến của từ "công cụ";) –

6

Thử nghiệm này là trích xuất một giao diện và xác minh rằng giao diện hiển thị bộ khởi động Boolean có tên IsRunning.

Bài kiểm tra này có thể được viết trước khi interface tồn tại và có thể trước khi mọi lớp bê tông IGame tồn tại. Tôi sẽ tưởng tượng, nếu dự án là của bất kỳ sự trưởng thành nào, thì có những bài kiểm tra khác thực hiện việc triển khai thực tế và xác minh hành vi cho cấp đó, và có thể sử dụng chế nhạo trong bối cảnh cách ly truyền thống hơn là cố định hình dạng lý thuyết.

Giá trị của các loại kiểm tra này là nó buộc một người phải suy nghĩ về cách hình dạng hoặc vật thể sẽ được sử dụng. Một cái gì đó dọc theo dòng của "Tôi không biết chính xác những gì một trò chơi sẽ làm gì được nêu ra, nhưng tôi biết rằng tôi sẽ muốn kiểm tra xem nó đang chạy ...". Vì vậy, kiểu thử nghiệm này là nhiều hơn để thúc đẩy các quyết định thiết kế, cũng như xác thực hành vi.

Không phải là thử nghiệm có giá trị nhất trên hành tinh, nhưng phục vụ mục đích của nó theo ý kiến ​​của tôi.

Chỉnh sửa: Tôi đã ở trên tàu đêm qua khi tôi đang đánh máy, nhưng tôi muốn giải đáp trực tiếp với Andrew Whitaker trong câu trả lời.

Người ta có thể cho rằng chữ ký trong chính giao diện là đủ để thực thi hợp đồng mong muốn. Tuy nhiên, điều này thực sự phụ thuộc vào cách bạn xử lý các giao diện của bạn và cuối cùng là cách bạn xác thực hệ thống mà bạn đang thử nghiệm.

Có thể có giá trị hữu hình trong việc nêu rõ chức năng này là một thử nghiệm. Bạn đang xác minh rõ ràng rằng đây là chức năng mong muốn cho một số IGame.

Cho phép sử dụng trường hợp, giả sử rằng với tư cách là nhà thiết kế, bạn biết rằng bạn muốn hiển thị công khai cho IsRunning, vì vậy bạn thêm nó vào giao diện.Nhưng hãy nói rằng một nhà phát triển khác nhận được điều này và thấy một thuộc tính, nhưng không thấy bất kỳ tập quán nào của nó ở bất kỳ nơi nào khác trong mã, người ta có thể giả định rằng nó đủ điều kiện để xóa (hoặc loại bỏ mã-thối, thường là một điều tốt) mà không có hại. Tuy nhiên, sự tồn tại của thử nghiệm này cho thấy sự hợp lý này nên tồn tại.

Nếu không có thử nghiệm này, nhà phát triển có thể sửa đổi giao diện, thả triển khai và dự án vẫn sẽ biên dịch và chạy có vẻ chính xác. Và nó sẽ được cho đến sau đó nhiều rằng ai đó có thể nhận thấy rằng giao diện đã được thay đổi.

Với thử nghiệm này, ngay cả khi nó xuất hiện như thể không có ai đang sử dụng nó, bộ thử nghiệm của bạn sẽ thất bại. Bản chất tự viết của bài kiểm tra cho bạn biết rằng ShouldReturnGameIsRunning(), ít nhất nó sẽ sinh ra một cuộc trò chuyện nếu IGame thực sự nên để lộ một số IsRunning getter.

+1

Tôi nhận được nó ... Tôi sẽ hỏi họ vào ngày mai, vì vậy nó có lẽ nên được lái xe thiết kế, và sau đó tôi nên tạo ra nhiều xét nghiệm để kiểm tra logic, phải không? – user1082693

+0

@ 32bitkid: Điều này có thể chỉ là ý kiến ​​của tôi, nhưng không phải là một thử nghiệm overkill cho điều này?Sẽ không chỉ đơn giản là xác định chữ ký cho phương thức trong giao diện tạo ra "hợp đồng" mà thử nghiệm này đang thử nghiệm? –

+1

@AndrewWhitaker. Tôi nghĩ rằng nó phụ thuộc vào cách bạn nghĩ về việc xác nhận hệ thống mà bạn đang thử nghiệm. Có thể có một số giá trị trong việc nêu rõ điều này như là một thử nghiệm rằng đây là một chức năng mong muốn cho một 'IGame'. Nếu nó là chữ ký duy nhất, nếu trên một sử dụng nó bất cứ nơi nào nó có thể xuất hiện như thể nó có thể được gỡ bỏ mà không gây hại. Bài kiểm tra này nêu rõ sự phù hợp này nên tồn tại. Nếu không, ngay cả khi không có ai đang sử dụng nó, các thử nghiệm của bạn sẽ không thành công –

1

Một khả năng khác là mã được viết bởi ai đó, vào thời điểm đó, không hiểu cách sử dụng khung mocking đặc biệt đó - và đã viết một hoặc nhiều bài kiểm tra đơn giản để tìm hiểu. Kent Beck đã nói về loại "bài kiểm tra học tập" trong cuốn sách TDD gốc của mình.

0

Thử nghiệm này có thể đã có điểm trong quá khứ. Nó có thể đã được thử nghiệm một lớp bê tông. Nó có thể đã được thử nghiệm một trừu tượng - vì đôi khi nó có ý nghĩa để thử một lớp trừu tượng mà bạn muốn kiểm tra. Tôi có thể thấy một người theo dõi (ít thông tin hơn (như bản thân mình)) của cách TDD làm những việc có thể đã để lại một mớ hỗn độn nhỏ như thế này. Dọn dẹp mã chết và mã thử nghiệm chết, không thực sự phù hợp với quy trình làm việc tự nhiên của màu đỏ, xanh lục, refactor (vì nó không phá vỡ bất kỳ kiểm thử nào!). Tuy nhiên, lịch sử không phải là biện minh cho một bài kiểm tra mà không làm gì ngoài việc gây nhầm lẫn cho người đọc. Vì vậy, hãy là một boyscout tốt và loại bỏ nó.

0

Trong phản đối trung thực của tôi, đây chỉ là rác, nó chỉ chứng minh rằng moq hoạt động như mong đợi

Các vấn đề liên quan