loại chức năng và / hoặc lớp nào là không thể kiểm tra đơn vị và tại sao


21

Lý do chính từ nhà phát triển vì không có thử nghiệm đơn vị tốt là "Mã không được thiết kế theo kiểu thử nghiệm đơn vị". Tôi đang cố gắng hiểu loại thiết kế và mã nào không thể được thử nghiệm.


2
Lý do của bạn? Một đồng nghiệp? Quản lý? Bạn đang làm việc với ngôn ngữ / khung nào?

1
Rất nhiều mã kế thừa trong ứng dụng và không có thời gian để thiết kế lại.
Knut

4
@gnat: Tôi không đồng ý. Câu hỏi bạn trích dẫn là về các tình huống trong đó các bài kiểm tra đơn vị không hữu ích. Câu hỏi hiện tại là về các tình huống khiến bài kiểm tra đơn vị khó khăn.
Arseni Mourzenko

@MainMa rõ ràng chúng tôi đọc các câu hỏi khác nhau. "Tôi đang cố gắng hiểu loại thiết kế và mã nào không thể được thử nghiệm." => "Khi nào thì không thích hợp để kiểm tra đơn vị?"
gnat

1
@manizzzz: bạn có thể muốn chỉnh sửa câu hỏi đó.
jmoreno

Câu trả lời:


27

Một số yếu tố có thể khiến mã khó kiểm tra đơn vị. Khi đây là trường hợp, tái cấu trúc giúp cải thiện mã để có thể kiểm tra được.

Một số ví dụ về mã có thể khó kiểm tra:

  • Hàm 1000 LỘC,
  • Mã mà chủ yếu dựa vào nhà nước toàn cầu,
  • Mã yêu cầu cụ thể, phức tạp để xây dựng các đối tượng, chẳng hạn như bối cảnh cơ sở dữ liệu, thay vì dựa vào giao diện và Dependency Injection,
  • Mã thực hiện chậm ,
  • Mã Spaghetti,
  • Mã kế thừa đã được sửa đổi trong nhiều năm mà không quan tâm đến khả năng đọc hoặc bảo trì,
  • Khó hiểu mã không có nhận xét hoặc gợi ý về ý định ban đầu của tác giả (ví dụ mã sử dụng tên biến như function pGetDp_U(int i, int i2, string sText).

Lưu ý rằng việc thiếu kiến ​​trúc rõ ràng không khiến mã khó kiểm tra đơn vị, vì các kiểm thử đơn vị liên quan đến các phần nhỏ của mã. Kiến trúc không rõ ràng vẫn sẽ có tác động tiêu cực đến tích hợp và thử nghiệm hệ thống.


8
Ngoài ra, thật khó để kiểm tra mã không phụ thuộc vào các hàm không thuần túy, như số ngẫu nhiên, thời gian hiện tại, I / O có dây cứng, v.v.
9000

Việc kiểm tra mã như vậy không quan trọng - bạn chỉ cần công cụ kiểm tra phù hợp, không phải xáo trộn mã của bạn cho phù hợp với chúng. Hãy thử Microsoft Fakes cho một ví dụ.
gbjbaanb

@MainMa, tôi thích câu trả lời này. Bạn cũng sẽ sẵn sàng bình luận một chút về yếu tố nào đẩy các thử nghiệm khác nhau đến tích hợp và thử nghiệm hệ thống? Tôi biết rằng lý do tôi đã hỏi những câu hỏi tương tự với câu hỏi ở đây trong quá khứ là vì tôi không có lộ trình giải thích loại thử nghiệm nào được đặt tốt nhất ở đâu (hoặc có lẽ, đặt hiệu quả nhất ở đâu) - Tôi nghĩ kiểm tra đơn vị là một và chỉ một.
J Trana

14

Có rất nhiều điều làm cho mã khó kiểm tra đơn vị. Thật trùng hợp, rất nhiều trong số đó cũng xảy ra khiến mã khó bảo trì:

  • Luật vi phạm Demeter .
  • Tạo các đối tượng bên trong một phương thức thay vì tiêm phụ thuộc .
  • Khớp nối chặt chẽ.
  • Sự gắn kết kém.
  • Phụ thuộc rất nhiều vào tác dụng phụ.
  • Dựa nhiều vào toàn cầu hoặc singletons.
  • Không để lộ nhiều kết quả trung gian. (Tôi đã từng phải kiểm tra một hàm toán học dài mười trang với một đầu ra duy nhất và không có kết quả trung gian có sẵn. Những người tiền nhiệm của tôi về cơ bản được mã hóa bất cứ câu trả lời nào mà mã đã đưa ra).
  • Phụ thuộc nhiều và trực tiếp vào các dịch vụ khó chế giễu, như cơ sở dữ liệu.
  • Môi trường thời gian chạy khác biệt đáng kể với môi trường phát triển, giống như một mục tiêu được nhúng.
  • Các đơn vị chỉ có sẵn ở dạng biên dịch (như DLL của bên thứ ba).

Tôi nghĩ rằng đây là một câu trả lời tuyệt vời. Bạn chạm vào nhiều vấn đề cấp mã và các vấn đề nhà nước toàn cầu. @MainMa có một số vấn đề khác mà tôi nghĩ là hợp lệ, nhưng ít được xác định rõ. Jeffery Thomas đề cập đến I / O và UI. Tôi nghĩ rằng nếu bạn thêm các phần hay của ba câu trả lời này, bạn sẽ có một câu trả lời gắn kết tuyệt vời. Tôi thích câu trả lời này nhất mặc dù vì tập trung vào các antipotype.
M2tM

1
Argh - không có gì tệ hơn các xác nhận kiểm tra đơn vị không giống với yêu cầu kinh doanh và chỉ là đầu ra tại một thời điểm nhất định - ví dụ, các thiết bị giả được gọi là 3 lần? Tại sao 3? Bởi vì đó là 3 lần đầu tiên bài kiểm tra được chạy / rant :)
Michael

Khớp nối chặt chẽ chỉ xấu khi nó không phù hợp. Khớp nối chặt chẽ trong mã mà nó rất gắn kết là một điều cần thiết. Ví dụ, một khai báo biến theo sau là sử dụng của nó. Kết hợp chặt chẽ, gắn kết cao.
Dietbuddha

1
Các thử nghiệm đơn vị trong đó đầu ra được kiểm tra đối với những gì mã đã làm, mà không có bất kỳ trường hợp kinh doanh / biện minh nào, được gọi là Thử nghiệm đặc tính. Chúng được sử dụng trong bảo trì, nơi trước đây không có thử nghiệm và thường không có yêu cầu về tài liệu và bạn phải đặt một cái gì đó vào đó sẽ bị hỏng nếu đầu ra của chức năng đó thay đổi. Họ tốt hơn không có gì.
Andy Krouwel

5

Các ví dụ phổ biến về mã người không muốn kiểm tra đơn vị:

  • Mã tương tác trực tiếp với i / o (đọc tệp, gọi mạng trực tiếp, trên mạng).
  • Mã trực tiếp cập nhật giao diện người dùng.
  • Mã mà tham chiếu trực tiếp singletons hoặc các đối tượng toàn cầu.
  • Mã mà thay đổi ngầm định đối tượng hoặc trạng thái đối tượng phụ.

Sử dụng một khung giả, tất cả các ví dụ này có thể được kiểm tra đơn vị. Nó chỉ hoạt động để thiết lập các thay thế giả cho các phụ thuộc nội bộ.

Những thứ thực sự không thể được kiểm tra đơn vị:

  • Các vòng lặp vô hạn (đối với trình quản lý luồng, trình điều khiển hoặc một số loại mã chạy dài khác)
  • Một số loại hoạt động lắp ráp trực tiếp (mà một số ngôn ngữ hỗ trợ)
  • Mã yêu cầu quyền truy cập đặc quyền (không phải là không thể, chỉ là không phải là một ý tưởng tốt)

2

Đây là một vài lĩnh vực có thể làm cho việc viết bài kiểm tra đơn vị trở nên khó khăn hơn. Tuy nhiên, tôi sẽ nhấn mạnh rằng điều đó không có nghĩa là bạn nên giảm giá các kỹ thuật hữu ích vì chúng có thể làm tăng thêm sự phức tạp cho thử nghiệm của bạn. Như với bất kỳ mã hóa nào, bạn nên thực hiện phân tích của riêng mình để xác định xem lợi ích có vượt quá chi phí hay không, và không chấp nhận một cách mù quáng những gì một số người ngẫu nhiên đăng trên mạng.

Viết mã kém

  • khớp nối không phù hợp (thường là khớp nối chặt chẽ nếu không nên)
  • mã bồn rửa nhà bếp (nơi một chức năng có quá nhiều logic / trách nhiệm)

Sự phụ thuộc của nhà nước trong một phạm vi khác nhau

Chi phí cho hầu hết các vòng xoắn ngoài tầm kiểm soát trừ khi bạn biết bạn đang làm gì. Thật không may, nhiều người thường không biết cách sử dụng các kỹ thuật này theo cách để giảm thiểu những thứ như kiểm tra độ phức tạp.

  • Người độc thân
  • Quả cầu
  • Đóng cửa

Trạng thái bên ngoài / hệ thống

  • Phụ thuộc phần cứng / thiết bị
  • Mạng phụ thuộc
  • Hệ thống tập tin phụ thuộc
  • Phụ thuộc giữa quá trình
  • Các phụ thuộc cuộc gọi hệ thống khác

Đồng thời

  • Luồng (khóa, phần quan trọng, vv)
  • ngã ba
  • Quân đoàn
  • Gọi lại
  • Bộ xử lý tín hiệu (không phải tất cả, nhưng một số)

2

Không có thứ gọi là mã không thể kiểm tra được. Tuy nhiên, có một vài ví dụ về mã THỰC SỰ, THỰC SỰ khó kiểm tra (đến mức có thể không đáng để nỗ lực):

Tương tác phần cứng - Nếu mã trực tiếp thao tác phần cứng (ví dụ, ghi vào thanh ghi để di chuyển thiết bị vật lý), thì việc kiểm tra đơn vị có thể quá khó khăn hoặc tốn kém. Nếu bạn sử dụng phần cứng thực sự cho thử nghiệm, điều đó có thể tốn kém để có được phản hồi phù hợp vào khai thác thử nghiệm (còn nhiều thiết bị hơn!) Và nếu bạn không, bạn phải mô phỏng hành vi chính xác của các đối tượng vật lý - không có mẹo nhỏ nào trong Một số trường hợp.

Tương tác đồng hồ - Điều này thường dễ dàng hơn, vì hầu như luôn luôn có thể giả định các chức năng đồng hồ hệ thống khá tầm thường. Nhưng khi bạn không thể, thì các thử nghiệm này trở nên không thể quản lý được - các thử nghiệm dựa trên thời gian thực có xu hướng mất nhiều thời gian để chạy và theo kinh nghiệm của tôi, chúng có xu hướng rất dễ vỡ vì tải hệ thống khiến mọi thứ mất nhiều thời gian hơn , gây ra lỗi thử nghiệm ảo.


0

Ba nhóm chính của tôi cho việc này là:

  • mã dựa trên các dịch vụ bên ngoài

  • các hệ thống không cho phép người kiểm tra sửa đổi trạng thái độc lập với ứng dụng.

  • kiểm tra môi trường không sao chép thiết lập sản xuất.

Đây là những gì tôi đã trải nghiệm nhiều nhất khi một nhà phát triển biến kỹ sư QA.

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.