2009-02-05 30 views
20

Tôi tự hỏi tôi nên viết đơn vị kiểm tra cho tất cả mọi thứ. Có một số lớp rất khó để viết bài kiểm tra đơn vị. Ví dụ, tôi đang viết một số chương trình để xử lý âm thanh. Lớp học để thu âm thanh từ micrô và lớp để phát âm thanh cho loa, làm cách nào tôi có thể viết bài kiểm tra đơn vị cho các lớp đó? Tôi không thể nhận được đầu ra và đầu vào của những lớp học, vì vậy nó gần như không thể kiểm tra chúng? Các thử nghiệm duy nhất tôi có thể làm là cho getter và setter, những thử nghiệm nhàm chán. Vì vậy, câu hỏi là, dòng hướng dẫn để viết bài kiểm tra đơn vị là gì? Và làm thế nào tôi nên đối phó với các lớp học này là khó khăn để kiểm tra?Tôi có nên viết bài kiểm tra đơn vị cho mọi thứ không?

Trả lời

36

Sử dụng thử nghiệm đơn vị ở nơi có ý nghĩa - không nhằm mục đích phủ sóng 100%. Nguyên tắc chính là nghĩ rằng thay vì áp dụng kiến ​​thức hoặc sự lười biếng.

Có nói rằng: Nếu bạn có các lớp khó tự nhiên để kiểm tra, hãy cố gắng giảm số lượng phải làm. Cô lập mã không thể kiểm tra và tách API của nó thành một giao diện. Sau đó kiểm tra logic mà sử dụng API đó dựa vào mô hình hoặc sơ khai.

+1

+1: Giả lập phần cứng bằng trình mô phỏng và sử dụng phần cứng đó. –

+30

Tôi đã cố gắng chế nhạo quản lý và công ty. Nó hoạt động tốt cho đến khi ngân hàng bắt đầu tung ra MockPaychecks của tôi.Tôi đã đi ra ngoài và cố gắng giải thích rằng tôi đã lái TDD như một lực lượng thay đổi xã hội, nhưng họ gọi là an ninh. Ngân hàng ngu ngốc. – ddaa

0

Nếu bạn gặp khó khăn trong việc thiết lập một khu vực mã cụ thể để thử nghiệm, có thể điều tra một khuôn khổ mocking như jMock hoặc EasyMock.

2

Câu trả lời ngắn gọn là, Không, nhưng sau đó điều đó phù hợp với mọi thứ trong lập trình khi bạn hỏi, "Tôi có nên X cho mọi thứ không?"

Câu trả lời dài hơn là bạn nên ít nhất xem xét nó, mà bạn đang làm. Tại sao bạn không thể giả lập đầu vào vào một lớp ghi âm? Tại sao không có ghi âm bỏ qua lớp học từ một micro để tải âm thanh từ một tập tin và có đầu ra đi đến một tập tin thay vì một loa. Thử nghiệm có thể so sánh kết quả đầu ra với kết quả chính xác đã biết.

Để biết thêm thông tin về mặt triết học, hãy xem this.

1

Để trả lời câu hỏi cụ thể của bạn, hãy sử dụng cáp loopback. Kết nối loa với micrô. Viết bài kiểm tra hiển thị cho người nói và chụp từ micrô và xác minh rằng nội dung bạn đã chơi đã được chụp. Đề nghị của tôi là sử dụng một giọng sine đơn giản để một FFT có thể cho bạn biết nếu bạn bị bắt lại cùng một điều.

Câu trả lời cho câu hỏi tổng quát hơn là có, bạn nên đơn vị kiểm tra mọi thứ bạn có thể. Làm như vậy tạo ra một di sản cho sau này để thay đổi xuống đường có thể được thực hiện với sự an tâm. Nó đảm bảo rằng mã của bạn hoạt động như mong đợi. Nó cũng ghi lại cách sử dụng dự định của các giao diện. Cuối cùng, nó ép buộc kiểu mã hóa tốt hơn. Thông thường cái gì đó là khó khăn để kiểm tra đơn vị cũng được thiết kế kém. Viết cho testability có nghĩa là viết cho thiết kế tốt hơn.

13

Tôi chỉ viết các bài kiểm tra đơn vị mà tôi biết nó giúp tôi tiết kiệm thời gian. Khi tôi bắt đầu thử nghiệm đơn vị, đây chỉ là một tỷ lệ phần trăm nhỏ của các lớp (những ejb khủng khiếp của !!). Hôm nay tôi kiểm tra gần như tất cả mọi thứ và tôi tiết kiệm tổng thời gian phát triển trên mọi điều tôi làm. Nếu có một cách hiệu quả để thử nghiệm đầu vào của người dùng thông qua một micro, tôi cũng sẽ làm điều đó. Nhưng theo như tôi biết, nó không thể theo cách tiết kiệm thời gian cho tôi.

Vì vậy, tôi nghĩ bạn nên đơn vị kiểm tra mọi thứ có trong "khả năng kiểm tra" hiện tại của bạn. Bạn nên cố gắng để kéo dài khả năng này, nhưng overreaching thực sự gửi tín hiệu của các ưu tiên sai; Trong tất cả các khả năng có một số thử nghiệm khác mà xứng đáng sự chú ý của bạn nhiều hơn nữa.(Về mặt kỹ thuật tôi kiểm tra nhiễm nhưng không TDD nhiễm)

Luật pháp của lợi nhuận giảm dần áp dụng cho đơn vị thử nghiệm càng nhiều càng tốt bất kỳ thử nghiệm khác; khoản hoàn vốn của bạn trên 5% cuối cùng là rất thấp và chi phí cao.

4

Một quy tắc tôi sử dụng để quyết định phát triển các bài kiểm tra đơn vị: nếu lớp học của bạn (hoặc bất kỳ đơn vị nào) sẽ được phát hành "vào tự nhiên", thì bạn chắc chắn nên cân nhắc viết bài kiểm tra đơn vị.

Bởi "trong tự nhiên", ý tôi là: một khi mã của bạn đang ở trong tình huống mà bạn không thể dự đoán hoặc kiểm soát mọi thứ sẽ tương tác với nó như thế nào. Vì vậy, các lớp tiếp xúc thông qua một API, hoặc các lớp tiếp xúc với đầu vào của người dùng có lẽ nên được kiểm tra đơn vị.

Cá nhân, tôi nghĩ rằng việc kiểm tra đơn vị viết cho mọi thứ có thể sẽ lãng phí thời gian của bạn. Đây thực sự là một vấn đề phức tạp mà bạn cần phải cân nhắc:

  • Mức độ phức tạp của lớp học như thế nào? Các lớp đơn giản có thể không đáng để thử nghiệm.
  • Mức độ quan trọng của lớp học là gì? Mã chạy trên máy ATM hy vọng sẽ được kiểm tra đơn vị.
  • Bạn có bao nhiêu kiểm soát đối với cách lớp được sử dụng?

Sau đó có luôn:

  • Khi nào là hạn chót dự án?
  • Bạn đã dành bao nhiêu công sức cho việc tạo thử nghiệm?
  • Yêu cầu của bạn cụ thể và chi tiết hay lớp học vẫn thay đổi khá thường xuyên?

Đối với các lớp khó, có thể đọc một số về fuzz testing.

1

Ví dụ khác: Nếu bạn phát triển một công cụ trò chơi, bạn muốn kiểm tra bóng của mình và các chức năng khác, nhưng bạn phải xác nhận nó một cách trực quan - không có gì mà UnitTest cổ điển có thể quyết định.

Trường hợp của bạn: Khi ứng dụng của bạn trở nên phức tạp hơn, bạn luôn phải nhấp vào UI để kiểm tra tất cả các chức năng của mình.

Tôi sẽ viết một "TestSuite tương tác", trong đó các hộp thoại giả khác nhau (tùy chỉnh cho từng trường hợp thử nghiệm) được hiển thị chỉ với các hàm bạn cần kiểm tra. Khi bạn đóng hộp thoại, bạn sẽ được nhắc nhở nếu hành vi được mong đợi. Nhưng tôi không chắc chắn nếu có những giải pháp có sẵn mà có thể giúp đỡ ở đây.

+0

Ok, ví dụ xấu và lựa chọn từ. Nhưng thực ra không phải là quan điểm của tôi. –

+0

Để kiểm tra hộp thoại, hãy xem blog của tôi: http://darkviews.wordpress.com/2008/11/11/testing-the-impossible-user-dialogs/ –

1

Bạn có thể muốn kiểm tra chuỗi video "Thử nghiệm không thể" trong blog của tôi để biết một số ý tưởng về cách kiểm tra.

Trong trường hợp của bạn, tôi đề nghị theo dõi idea of Steve Rowe để viết kiểm tra thiết lập loa và micrô và sử dụng cáp loopback để kiểm tra mã thiết lập phần cứng cộng với API cho phép phát ra dữ liệu qua loa và đọc dữ liệu từ micrô.

Đây là bài kiểm tra đơn vị nhưng không phải là bài kiểm tra tự động. Di chuyển nó vào một bộ thử nghiệm độc lập không chạy với các thử nghiệm tự động khác.Nếu bạn muốn tự động hóa nó, hãy thiết lập một PC thứ hai với cấu hình chính xác (cộng với cáp loopback) và chạy thử nghiệm từ xa.

Sau đó, bạn chắc chắn rằng thiết lập phần cứng hoạt động, bạn có thể gửi và bạn có thể nhận âm thanh. Điều này cho phép bạn kiểm tra các lớp xử lý dữ liệu độc lập với phần cứng. Sử dụng mockups để mô phỏng loa và micrô.

+0

Bạn có thể đăng liên kết lên blog của mình không? – finnw

+0

http://darkviews.wordpress.com/tag/tdd/ Có một vài bài viết liên quan mà bạn sẽ theo thử nghiệm thẻ. –

1

Mã mà việc ghi lại và phát lại âm thanh không thể được kiểm tra đơn vị (mặc dù bạn có thể kiểm tra phương thức chụp trả về lỗi khi được gọi khi lớp đó không được liên kết thành công với tài nguyên).

Tuy nhiên, trừ khi bạn chỉ cần viết âm thanh đã ghi vào đĩa mã yêu cầu các lớp chụp và chơi của bạn chắc chắn có thể.

Hai mẩu lời khuyên:

  • Đừng thử nghiệm các trình biên dịch (ví dụ phương thức getter và setter)
  • thử nghiệm tất cả những gì có thể có thể phá vỡ
0

tôi có xu hướng để viết bài kiểm tra càng nhiều càng tốt Tôi có thể. Không chỉ để chứng minh rằng một cái gì đó hoạt động, nhưng để làm cho nó rõ ràng cho người khác khi họ chắc chắn phá vỡ nó sau này.

Tôi đã có một phương thức dài 1 dòng. Ở những nơi tương tự trong ứng dụng của tôi, tôi đã viết các bài kiểm tra đơn vị, nhưng đang vội vàng tôi nghĩ rằng nó không thể thất bại. Tôi đã sai, nó không hoạt động :-)

Lợi ích bổ sung của việc viết các bài kiểm tra đơn vị không chỉ để kiểm tra mã của bạn, mà để ai đó chưa bao giờ thấy mã của bạn trước đây có thể đọc các bài kiểm tra và hiểu mã nên làm việc cho các kịch bản cụ thể ... như một đặc điểm kỹ thuật.

+1

Dường như trang web đã thay đổi kể từ khi tôi đăng câu trả lời này. Tôi đã thay đổi phản hồi của mình, cảm ơn vì đã dành thời gian để xem lại câu trả lời của tôi :) –

1

câu trả lời giá rẻ: Test everything that could possibly break

Cuối cùng tuy nhiên bạn cần phải hiểu được giá trị kinh doanh của các bài kiểm tra bạn viết - không khác gì với bất kỳ nỗ lực khác mà bạn rộng, bất kỳ codebase khác bạn cam kết chính mình để duy trì.

0

Kiểm tra thiết kế là kỹ năng có được - bạn càng kiểm tra tốt hơn ở đó bạn nhận được. Một số điều có vẻ khó kiểm tra nhưng nếu bạn nghĩ về nó trong vài phút, bạn thường có thể tìm được cách.

Các thử nghiệm có thể lộn xộn - ví dụ: một chương trình java có thể khởi chạy một trình thông dịch hoặc thậm chí là một trình bao như bash mà lần lượt khởi chạy một loạt các bộ lọc unix mà bạn hy vọng sẽ xuất ra các tệp nhị phân giống hệt nhau. Tuy nhiên, đừng lo lắng - chất lượng của mã kiểm tra không phải cao bằng mã trong sản phẩm đã hoàn thành.

1

Tôi thử nghiệm hầu hết mọi thứ.

Bất cứ khi nào tôi viết bài kiểm tra, tôi cũng xem xét các bài kiểm tra là tài liệu hoặc hướng dẫn về cách sử dụng mã của tôi, để tôi và những người khác đọc trong tương lai.

Tôi không thử nghiệm triển khai. Tôi muốn có thể thay đổi việc triển khai mà không thay đổi các thử nghiệm của mình.

Tôi đã sử dụng TDD trong một hoặc hai năm để có thể tôi sẽ trưởng thành và dừng lại. Cho đến nay, mặc dù, tôi vẫn đang học và nghĩ rằng tôi không viết đủ các bài kiểm tra.

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