2009-07-27 22 views
13

Hầu hết các cuộc thảo luận trên trang web này là rất tích cực về thử nghiệm đơn vị. Tôi là một fan hâm mộ của đơn vị thử nghiệm bản thân mình. Tuy nhiên, tôi đã tìm thấy thử nghiệm đơn vị rộng lớn mang lại những thách thức riêng của mình. Ví dụ: kiểm tra đơn vị thường được kết hợp chặt chẽ với mã họ kiểm tra, điều này có thể làm cho các thay đổi API ngày càng tốn kém khi khối lượng kiểm tra tăng lên.Có những tình huống mà các xét nghiệm đơn vị có hại cho mã không?

Bạn đã tìm thấy các tình huống thực tế trong đó các thử nghiệm đơn vị đã gây bất lợi cho chất lượng mã hoặc thời gian giao hàng? Bạn đã xử lý những tình huống này như thế nào? Có bất kỳ 'thực hành tốt nhất' nào có thể được áp dụng cho việc thiết kế và thực hiện các bài kiểm tra đơn vị không?

Có một câu hỏi nào liên quan ở đây: Why didn't unit testing work out for your project?

Trả lời

4

Với thử nghiệm đơn vị rộng rãi, bạn sẽ bắt đầu thấy rằng các hoạt động tái cấu trúc là tốn kém hơn cho chính xác lý do bạn nói.

IMHO đây là một điều tốt. Những thay đổi lớn và tốn kém cho API nên có chi phí lớn hơn so với những thay đổi nhỏ và rẻ. Tái cấu trúc không phải là một hoạt động miễn phí và điều quan trọng là phải hiểu tác động đến cả bản thân và người tiêu dùng API của bạn. Bài kiểm tra đơn vị là thước đo tuyệt vời để đo lường mức độ thay đổi API tốn kém.

Một phần của vấn đề này mặc dù được giảm bớt bằng cách sử dụng công cụ. Hầu hết các IDE trực tiếp hoặc gián tiếp (thông qua plugin) hỗ trợ các hoạt động tái cấu trúc trong cơ sở mã của chúng. Sử dụng các hoạt động này để thay đổi các xét nghiệm đơn vị của bạn sẽ giảm bớt một chút đau.

+0

Điều này không có nghĩa là thiết kế thử nghiệm đơn vị không tốt? – txwikinger

+1

@txwikinger, tôi không thấy nó có thể là thiết kế tồi. Nếu bạn kiểm tra đơn vị cấp API và thay đổi API, nó sẽ dẫn đến những thay đổi tương ứng trong các bài kiểm tra đơn vị. – JaredPar

+1

Vâng .. kiểm tra đơn vị kiểm tra chống lại các đặc điểm kỹ thuật. Nếu điều đó thay đổi, kiểm tra đơn vị cũng cần thay đổi. Tôi có thể nghĩ rằng nó là tốt như vậy, kể từ khi thay đổi API có khả năng gây ra vỡ ở một nơi khác. – txwikinger

1

Một vượt quá dương tính giả có thể làm chậm sự phát triển xuống, do đó điều quan trọng là để thử nghiệm cho những gì bạn thực sự muốn duy trì bất biến. Điều này thường có nghĩa là viết đơn vị kiểm tra trước cho các yêu cầu, sau đó theo dõi với các bài kiểm tra đơn vị chi tiết hơn để phát hiện các thay đổi bất ngờ trong đầu ra.

1

Chủ yếu là trong trường hợp hệ thống được phát triển mà không cần kiểm tra đơn vị trong tâm trí, đó là một suy nghĩ và không phải là công cụ thiết kế. Khi bạn phát triển với các kiểm tra tự động, cơ hội phá vỡ API của bạn sẽ giảm bớt.

+0

Có thiết kế tốt nào có vấn đề với kiểm tra đơn vị không? – txwikinger

0

Nếu bạn chắc chắn mã của bạn sẽ không được sử dụng lại, sẽ không cần phải được bảo đảm, dự án của bạn là đơn giản và rất ngắn hạn; thì bạn không cần kiểm tra đơn vị.

Kiểm tra đơn vị hữu ích để tạo điều kiện thay đổi và bảo trì. Họ thực sự thêm một chút thời gian để giao hàng, nhưng nó được trả trong trung hạn/dài hạn. Nếu không có trung hạn/dài hạn, nó có thể là không cần thiết, là các bài kiểm tra thủ công đủ.

Nhưng tất cả điều này là rất khó xảy ra. Vì vậy, họ vẫn là một xu hướng :)

Ngoài ra, đôi khi có thể là một quyết định kinh doanh cần thiết phải đầu tư ít thời gian hơn trong việc kiểm tra, để có một giao khẩn cấp nhanh hơn (mà sẽ cần phải được trả với lãi suất cao hơn)

+2

Kiểm tra đơn vị cải thiện mã ngay cả khi mã sẽ không bị thay đổi trong tương lai. – dss539

+0

@ dss539 Nhưng nếu mã không bị sửa đổi, bạn không còn cần phải đọc, được thiết kế tốt, v.v. –

+4

bạn không cần đọc nó và được thiết kế tốt để đảm bảo rằng mã đã hoạt động bình thường ngay từ đầu . đơn vị kiểm tra hỗ trợ mạnh mẽ trong thiết kế và có thể bắt một vài lỗi, quá. chỉ vì một đoạn mã không bao giờ bị thay đổi không có nghĩa là nó có thể là crap. kiểm tra đơn vị giúp giảm thiểu cơ hội mà một số mã đã cho là crap – dss539

0

Có những trường hợp thử nghiệm đơn vị có thể gây bất lợi cho chất lượng mã và thời gian phân phối. Nếu bạn tạo quá nhiều đơn vị kiểm tra mã của bạn sẽ trở nên bị xáo trộn với giao diện và chất lượng mã của bạn nói chung sẽ bị ảnh hưởng. Trừu tượng là tuyệt vời nhưng bạn có thể có quá nhiều của nó.

Nếu đơn vị viết của bạn kiểm tra mẫu thử nghiệm hoặc hệ thống có nhiều khả năng thay đổi lớn, kiểm tra đơn vị của bạn sẽ có hiệu lực vào thời gian giao hàng. Trong những trường hợp này, tốt hơn nên viết bài kiểm tra chấp nhận để kiểm tra gần hơn đến hết.

+0

Tại sao bạn phải tạo nhiều giao diện? Có nhiều cách để tiêm phụ thuộc ... hay bạn đang nói về cái gì khác? – dss539

+0

Hmm, ý kiến ​​của tôi có thể chỉ đến từ việc phải thêm thử nghiệm đơn vị cho các dự án hiện có. Tôi rất thích sử dụng TDD ngay từ đầu. – gradbot

+1

Có, có những cách không xâm nhập để tiêm phụ thuộc, nhưng một số người bị ám ảnh với tách và trừu tượng tất cả mọi thứ quá mức, thường trong tên của testability. –

0

Kiểm tra đơn vị chậm thường có thể gây bất lợi cho sự phát triển.Điều này thường xảy ra khi các bài kiểm tra đơn vị trở thành các bài kiểm tra tích hợp cần phải nhấn các dịch vụ web hoặc cơ sở dữ liệu. Nếu các bài kiểm tra đơn vị của bạn mất hơn một giờ để chạy, thường bạn sẽ thấy bản thân và nhóm của bạn bị tê liệt trong giờ chờ đợi để xem thử nghiệm đơn vị có vượt qua hay không (vì bạn không muốn tiếp tục xây dựng móng gãy).

Với điều đó đang được nói, tôi nghĩ rằng các lợi ích xa hơn vượt quá những hạn chế trong tất cả trừ các trường hợp khó tính nhất.

2

Một trong những dự án tôi đã thực hiện được thử nghiệm đơn vị nhiều; chúng tôi đã có hơn 1000 bài kiểm tra đơn vị cho 20 lớp hoặc hơn. Có nhiều mã thử nghiệm hơn mã sản xuất. Các bài kiểm tra đơn vị bắt gặp các lỗi vô số được giới thiệu trong các hoạt động tái cấu trúc; họ chắc chắn làm cho nó dễ dàng và an toàn để thực hiện thay đổi, mở rộng chức năng, vv Mã phát hành có tỷ lệ lỗi rất thấp.

Để khuyến khích chính mình viết các bài kiểm tra đơn vị, chúng tôi đặc biệt chọn giữ chúng nhanh chóng và bẩn thỉu - chúng tôi sẽ thử nghiệm khi chúng tôi tạo mã dự án và các bài kiểm tra nhàm chán và 'không phải mã thực', vì vậy ngay sau khi chúng tôi viết một tập lệnh thực hiện chức năng của mã sản xuất, chúng tôi đã hoàn thành và tiếp tục. Tiêu chí duy nhất cho mã thử nghiệm là nó hoàn toàn thực hiện API của mã sản xuất.

Điều chúng tôi học được một cách khó khăn là cách tiếp cận này không mở rộng quy mô. Khi mã được phát triển, chúng tôi thấy cần phải thay đổi mẫu giao tiếp giữa các đối tượng của chúng tôi, và đột nhiên tôi có 600 bài kiểm tra đơn vị không thành công! Việc sửa lỗi này đã khiến tôi mất vài ngày. Mức độ phá vỡ thử nghiệm này xảy ra hai hoặc ba lần với các cấu trúc lại cấu trúc lớn hơn nữa. Trong mỗi trường hợp, tôi không tin rằng chúng ta có thể dự đoán được sự tiến hóa mã được yêu cầu trước đó một cách hợp lý.

Yếu tố đạo đức của câu chuyện đối với tôi là: mã kiểm tra đơn vị cần phải sạch như mã sản xuất. Bạn chỉ đơn giản là không thể lấy đi với cuttting và dán trong các bài kiểm tra đơn vị. Bạn cần phải áp dụng tái cấu trúc hợp lý và tách các thử nghiệm của bạn khỏi mã sản xuất nếu có thể bằng cách sử dụng các đối tượng proxy.

Tất nhiên điều này làm tăng thêm sự phức tạp và chi phí cho các bài kiểm tra đơn vị của bạn (và có thể giới thiệu lỗi cho các bài kiểm tra của bạn!), Do đó, nó là một sự cân bằng tốt. Nhưng tôi tin rằng khái niệm 'kiểm tra đơn vị', được thực hiện một cách độc lập, không phải là chiến thắng rõ ràng và rõ ràng mà nó thường được tạo ra. Kinh nghiệm của tôi là các bài kiểm tra đơn vị, giống như mọi thứ khác trong lập trình, đòi hỏi sự chăm sóc, và không phải là một phương pháp có thể được áp dụng một cách mù quáng. Do đó nó gây ngạc nhiên cho tôi rằng tôi đã không thấy nhiều cuộc thảo luận về chủ đề này trên các diễn đàn như thế này và trong văn học.

+1

"rằng cách tiếp cận này không quy mô" Kết luận sai. Kết luận chính xác là "Thay đổi API là tốn kém và phức tạp" bất kể khối lượng thử nghiệm. Cách tiếp cận này mở rộng quy mô và các thử nghiệm cho thấy phạm vi và độ phức tạp của các thay đổi. –

3

Có 'thực tiễn tốt nhất' nào có thể áp dụng cho thiết kế và triển khai các thử nghiệm đơn vị không?

Đảm bảo kiểm tra đơn vị của bạn chưa trở thành kiểm tra tích hợp.Ví dụ nếu bạn có các unit test cho một lớp Foo, sau đó lý tưởng nhất là kiểm tra chỉ có thể phá vỡ nếu

  1. đã có một sự thay đổi trong Foo
  2. hoặc đã có một sự thay đổi trong giao diện sử dụng bởi Foo
  3. hoặc đã có thay đổi trong mô hình miền (thông thường bạn sẽ có một số lớp như "Customer" là trung tâm của không gian vấn đề, không có chỗ cho trừu tượng và do đó không bị ẩn sau giao diện)

Nếu kiểm tra không thành công vì bất kỳ thay đổi nào khác, sau đó ey đã trở thành kiểm thử tích hợp và bạn sẽ gặp rắc rối khi hệ thống phát triển lớn hơn. Các bài kiểm tra đơn vị không nên có các vấn đề về khả năng mở rộng này vì chúng kiểm tra đơn vị bị cô lập của mã.

1

Tôi nghĩ rằng bạn đang xem xét sửa chữa một triệu chứng, thay vì nhận ra toàn bộ vấn đề. Vấn đề gốc là một API thực sự là một giao diện được xuất bản * và nó phải tuân theo các giới hạn tương tự mà bạn sẽ đặt vào bất kỳ hợp đồng lập trình nào: không thay đổi! Bạn có thể thêm vào một API, và gọi nó là API v2, nhưng bạn không thể quay trở lại và thay đổi API v1.0, nếu không bạn đã thực sự phá vỡ tính tương thích ngược, mà hầu như luôn luôn là một điều xấu cho một API để làm.

(* Tôi không có ý để gọi ra bất kỳ công nghệ giao tiếp cụ thể hoặc ngôn ngữ, giao diện có thể có nghĩa là bất cứ điều gì từ các khai báo lớp trên lên.)

tôi sẽ đề nghị rằng một Test Driven cách tiếp cận phát triển sẽ giúp ngăn ngừa nhiều của những loại vấn đề này ở nơi đầu tiên. Với TDD, bạn sẽ "cảm thấy" sự lúng túng của các giao diện trong khi bạn đang viết các bài kiểm tra, và bạn sẽ bị buộc phải sửa các giao diện đó trước đó trong quá trình thay vì đợi cho đến khi bạn đã viết một nghìn bài kiểm tra.

Một trong những lợi ích chính của Phát triển theo thử nghiệm là nó cung cấp cho bạn phản hồi tức thì về việc sử dụng có lập trình lớp/giao diện của bạn. Các hành động viết một bài kiểm tra là một thử nghiệm của thiết kế của bạn, trong khi hành động chạy thử nghiệm là thử nghiệm của hành vi của bạn. Nếu khó khăn hoặc khó khăn khi viết một bài kiểm tra cho một phương pháp cụ thể, thì phương pháp đó có thể được sử dụng không chính xác, có nghĩa là nó là một thiết kế yếu và cần được tái cấu trúc nhanh chóng.

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