Có một điều như là có quá nhiều bài kiểm tra đơn vị?


139

Tôi đã được giao nhiệm vụ viết bài kiểm tra đơn vị cho một ứng dụng hiện có. Sau khi hoàn thành tệp đầu tiên của tôi, tôi có 717 dòng mã kiểm tra cho 419 dòng mã gốc.

Là tỷ lệ này sẽ trở nên không thể quản lý khi chúng tôi tăng phạm vi bảo hiểm mã của chúng tôi?

Sự hiểu biết của tôi về kiểm thử đơn vị là kiểm tra từng phương thức trong lớp để đảm bảo rằng mọi phương thức đều hoạt động như mong đợi. Tuy nhiên, trong yêu cầu kéo, lãnh đạo công nghệ của tôi lưu ý rằng tôi nên tập trung vào thử nghiệm cấp cao hơn. Ông đề nghị thử nghiệm 4-5 trường hợp sử dụng thường được sử dụng nhất với lớp đang đề cập, thay vì kiểm tra toàn diện từng chức năng.

Tôi tin tưởng nhận xét của lãnh đạo công nghệ của tôi. Anh ấy có nhiều kinh nghiệm hơn tôi, và anh ấy có bản năng tốt hơn khi thiết kế phần mềm. Nhưng làm thế nào để một nhóm nhiều người viết các bài kiểm tra cho một tiêu chuẩn mơ hồ như vậy; đó là, làm thế nào để tôi biết các đồng nghiệp của mình và tôi chia sẻ cùng một ý tưởng cho "các trường hợp sử dụng phổ biến nhất"?

Đối với tôi, phạm vi kiểm tra đơn vị 100% là một mục tiêu cao cả, nhưng ngay cả khi chúng tôi chỉ đạt 50%, chúng tôi sẽ biết rằng 100% trong số 50% đó được bảo hiểm. Mặt khác, viết bài kiểm tra cho một phần của mỗi tệp để lại rất nhiều chỗ để gian lận.


145
Nó phụ thuộc. Bạn đang viết một trò chơi tic-tac-toe, hay bạn đang viết mã để quản lý lò phản ứng hạt nhân?
Bryan Oakley

11
Với đủ nhiều bài kiểm tra đơn vị, bạn có thể phát hiện các vấn đề triển khai phần cứng kỳ lạ như lỗi Pentium FDIV hoặc các mối tương quan trong các nguyên hàm mã hóa, do đó có vẻ như không có giới hạn cứng nào mà không có bài kiểm tra đơn vị nào có thể hữu ích. Chỉ là một giới hạn thực tế khi nó quá tốn kém.
Nat

5
Thử nghiệm ở cấp độ cao hơn sẽ cung cấp cho bạn viễn cảnh tốt hơn về phạm vi bảo hiểm thực sự. Theo phạm vi bảo hiểm thực tế tôi có nghĩa là một điều có nhiều khả năng xảy ra trong quá trình sử dụng thường xuyên của hệ thống. Đó là loại bảo hiểm bạn muốn đạt được đầu tiên. Trong 50% cuối cùng đạt được có thể có YAGNI hoặc mã chết mà sau khi xóa sẽ góp phần tăng phạm vi bảo hiểm chung.
Laiv

5
Nếu bạn nhận được quá nhiều bài kiểm tra (mà hiện tại bạn không có), vấn đề rất có thể là mã bạn đang kiểm tra có quá nhiều. Vì vậy, trách nhiệm duy nhất không được tôn trọng. Khi mã được phân chia tốt, việc kiểm tra cũng sẽ không tạo ra nhiều gánh nặng. Nếu các lớp học làm nhiều, có nhiều tác dụng phụ, vv nó sẽ trở thành một cơn ác mộng.
Luc Franken

12
Tài liệu thử nghiệm sqlite là một tài liệu thú vị: sqlite.org/testing.html . Trích dẫn: "thư viện SQLite bao gồm khoảng 122,9 KSLOC của mã C. Để so sánh, dự án có mã kiểm tra và kịch bản thử nghiệm gấp 745 lần - 91596.1 KSLOC."
dùng60561

Câu trả lời:


180

Có, với phạm vi bảo hiểm 100%, bạn sẽ viết một số bài kiểm tra mà bạn không cần. Thật không may, cách đáng tin cậy duy nhất để xác định bài kiểm tra nào bạn không cần là viết tất cả chúng, sau đó đợi 10 năm hoặc lâu hơn để xem bài kiểm tra nào không bao giờ thất bại.

Duy trì nhiều bài kiểm tra thường không có vấn đề. Nhiều nhóm đã tích hợp tự động và kiểm tra hệ thống trên phạm vi bao phủ 100% đơn vị kiểm tra đơn vị.

Tuy nhiên, bạn không ở trong giai đoạn bảo trì thử nghiệm, bạn đang chơi đuổi kịp. Sẽ tốt hơn rất nhiều khi có 100% các lớp học của bạn ở phạm vi kiểm tra 50% so với 50% các lớp học của bạn ở phạm vi kiểm tra 100% và khách hàng tiềm năng của bạn dường như đang cố gắng để bạn phân bổ thời gian phù hợp. Sau khi bạn có đường cơ sở đó, thì bước tiếp theo thường là đẩy 100% trong các tệp được thay đổi trong tương lai.


11
Cảm ơn câu trả lời của bạn. Nó giúp đặt câu hỏi của tôi trong quan điểm và giải quyết vấn đề thực sự - thái độ của tôi! +1
dùng2954463

43
@astra Thái độ của bạn không tệ đến thế. Thật tốt khi hỏi tại sao. Để trả lời câu hỏi tuyệt vời khác của bạn: "Làm thế nào để tôi biết các đồng nghiệp của mình và tôi chia sẻ cùng một ý tưởng cho" các trường hợp sử dụng phổ biến nhất "? Bạn hãy để họ xem xét các bài kiểm tra của bạn. Hãy nhìn vào họ. rất nhiều và có thể họ cũng sẽ như vậy. Các bài kiểm tra đánh giá mã hiếm khi lãng phí thời gian. Mặc dù tôi có xu hướng làm việc tại nhà ga hơn là phòng hội thảo
candied_orange

18
Một thử nghiệm không bao giờ thất bại trong 10 năm thậm chí không đảm bảo nó không cần thiết, nó có thể thất bại trong năm 11.
Pharap

24
Thực tế, bạn có thể có cách tiếp cận ngược lại. Viết các bài kiểm tra mà bạn nghĩ bao gồm các trường hợp phổ biến. Nhưng sau đó, mỗi khi bạn gặp một thất bại, hãy viết một bài kiểm tra để bao quát khu vực đó.
stannius

10
@Pharap Vấn đề duy nhất của tôi với câu trả lời này là có một giả định ngầm định rằng một bài kiểm tra chỉ có thể thêm giá trị khi thất bại. Một bài kiểm tra đơn vị tốt cũng cung cấp một hình thức tài liệu sống tuyệt vời. Nó cũng tăng thêm giá trị khi bạn viết bài kiểm tra, bằng cách buộc bạn phải suy nghĩ về khả năng sử dụng lại / khả năng kết hợp / mã hóa. Mã chưa được kiểm tra theo kinh nghiệm của tôi có xu hướng là những con thú nguyên khối không linh hoạt.
ArTs

66

Nếu bạn đã làm việc trên các cơ sở mã lớn được tạo bằng cách sử dụng Phát triển dựa trên thử nghiệm, bạn sẽ biết có thể có quá nhiều thử nghiệm đơn vị. Trong một số trường hợp, hầu hết các nỗ lực phát triển bao gồm cập nhật các thử nghiệm chất lượng thấp sẽ được triển khai tốt nhất dưới dạng kiểm tra bất biến, điều kiện tiên quyết và hậu điều kiện trong các lớp có liên quan, trong thời gian chạy (tức là thử nghiệm là tác dụng phụ của thử nghiệm cấp cao hơn ).

Một vấn đề khác là việc tạo ra các thiết kế chất lượng kém, sử dụng các kỹ thuật thiết kế hướng hàng hóa, dẫn đến sự phổ biến của mọi thứ để kiểm tra (nhiều lớp, giao diện, v.v.). Trong trường hợp này, gánh nặng dường như có thể đang cập nhật mã thử nghiệm, nhưng vấn đề thực sự là thiết kế kém chất lượng.


16
Nâng cao để chỉ ra các điều kiện trước, sau điều kiện và bất biến nên được coi là thử nghiệm đơn vị. Theo cách đó, mỗi lần sử dụng là một bài kiểm tra đơn vị khi mã gỡ lỗi đó được kích hoạt.
Persixty

Đây là một câu trả lời tuyệt vời và phù hợp hoàn hảo với kinh nghiệm của tôi.
Tony Enni

Và một vấn đề nữa: Nếu bạn có kiểm tra kiểm soát (bạn thực sự nên!) Có số lượng lớn chất lượng thấp, thậm chí có thể các bài kiểm tra chạy dài sẽ làm chậm mọi thứ mà không cung cấp bất kỳ lợi ích thực sự nào. Và sau đó rõ ràng là sự thật thú vị khi bạn thay đổi một điều trong một lớp và hàng trăm bài kiểm tra thất bại.
Voo

3
Đây là một câu trả lời tốt hơn nhiều so với câu trả lời được chấp nhận! "Trong một số trường hợp, hầu hết các nỗ lực phát triển bao gồm cập nhật các bài kiểm tra chất lượng thấp" - Tôi đã trải nghiệm điều này và nó rất tệ. Nhiều hơn là không có bài kiểm tra nào cả, trong một số khía cạnh.
Benjamin Hodgson

36

Trả lời cho những câu hỏi của bạn

Có một điều như là có quá nhiều bài kiểm tra đơn vị?

Chắc chắn ... Chẳng hạn, bạn có thể có nhiều thử nghiệm thoạt nhìn có vẻ khác nhau nhưng thực sự thử nghiệm cùng một thứ (về mặt logic phụ thuộc vào cùng một dòng mã ứng dụng "thú vị" đang thử nghiệm).

Hoặc bạn có thể kiểm tra phần bên trong mã của mình không bao giờ lộ ra ngoài (nghĩa là không phải là một phần của bất kỳ loại hợp đồng giao diện nào), nơi người ta có thể tranh luận về việc liệu điều đó có hợp lý hay không. Ví dụ, từ ngữ chính xác của thông điệp tường trình nội bộ hoặc bất cứ điều gì.

Tôi đã được giao nhiệm vụ viết bài kiểm tra đơn vị cho một ứng dụng hiện có. Sau khi hoàn thành tệp đầu tiên của tôi, tôi có 717 dòng mã kiểm tra cho 419 dòng mã gốc.

Điều đó đánh tôi là khá bình thường. Các thử nghiệm của bạn dành rất nhiều dòng mã cho thiết lập và phân tích trên đầu các thử nghiệm thực tế. Tỷ lệ có thể cải thiện, hoặc có thể không. Bản thân tôi khá nặng kiểm tra, và thường đầu tư nhiều địa điểm và thời gian vào các bài kiểm tra hơn mã thực tế.

Là tỷ lệ này sẽ trở nên không thể quản lý khi chúng tôi tăng phạm vi bảo hiểm mã của chúng tôi?

Tỷ lệ không có yếu tố rất nhiều. Có những phẩm chất khác của các bài kiểm tra có xu hướng làm cho chúng không thể quản lý được. Nếu bạn thường xuyên phải cấu trúc lại một loạt các bài kiểm tra khi thực hiện các thay đổi khá đơn giản trong mã của mình, bạn nên xem xét kỹ các lý do. Và đó không phải là bạn có bao nhiêu dòng, mà là cách bạn tiếp cận mã hóa các bài kiểm tra.

Sự hiểu biết của tôi về kiểm thử đơn vị là kiểm tra từng phương thức trong lớp để đảm bảo rằng mọi phương thức đều hoạt động như mong đợi.

Điều đó đúng với các bài kiểm tra "đơn vị" theo nghĩa chặt chẽ. Ở đây, "đơn vị" là một cái gì đó giống như một phương thức hoặc một lớp. Điểm kiểm thử "đơn vị" là chỉ kiểm tra một đơn vị mã cụ thể, không phải toàn bộ hệ thống. Lý tưởng nhất là bạn sẽ loại bỏ toàn bộ phần còn lại của hệ thống (sử dụng gấp đôi hoặc không có gì).

Tuy nhiên, trong yêu cầu kéo, lãnh đạo công nghệ của tôi lưu ý rằng tôi nên tập trung vào thử nghiệm cấp cao hơn.

Sau đó, bạn rơi vào cái bẫy giả định rằng mọi người thực sự có nghĩa là kiểm tra đơn vị khi họ nói kiểm tra đơn vị. Tôi đã gặp nhiều lập trình viên nói "kiểm thử đơn vị" nhưng có nghĩa là một cái gì đó khá khác biệt.

Ông đề nghị thử nghiệm 4-5 trường hợp sử dụng thường được sử dụng nhất với lớp đang đề cập, thay vì kiểm tra toàn diện từng chức năng.

Chắc chắn, chỉ tập trung vào 80% mã quan trọng hàng đầu cũng giảm tải ... Tôi đánh giá cao việc bạn nghĩ rất cao về ông chủ của mình, nhưng điều này không đánh tôi là sự lựa chọn tối ưu.

Đối với tôi, phạm vi kiểm tra đơn vị 100% là một mục tiêu cao cả, nhưng ngay cả khi chúng tôi chỉ đạt 50%, chúng tôi sẽ biết rằng 100% trong số 50% đó được bảo hiểm.

Tôi không biết "phạm vi kiểm tra đơn vị" là gì. Tôi giả sử bạn có nghĩa là "phạm vi bảo hiểm mã", tức là sau khi chạy bộ kiểm tra, mọi dòng mã (= 100%) đã được thực thi ít nhất một lần.

Đây là một số liệu sân bóng đẹp, nhưng cho đến nay không phải là tiêu chuẩn tốt nhất người ta có thể bắn. Chỉ thực hiện các dòng mã không phải là toàn bộ hình ảnh; ví dụ, điều này không giải thích cho các đường dẫn khác nhau thông qua các nhánh phức tạp, lồng nhau. Đó là nhiều hơn một số liệu chỉ ngón tay của mình vào các đoạn mã được kiểm tra quá ít (rõ ràng, nếu một lớp có độ bao phủ mã 10% hoặc 5%, thì có gì đó không đúng); mặt khác, phạm vi bảo hiểm 100% sẽ không cho bạn biết bạn đã kiểm tra đủ chưa hay bạn đã kiểm tra đúng chưa.

Thử nghiệm hội nhập

Nó làm tôi khó chịu đáng kể khi mọi người liên tục nói về thử nghiệm đơn vị ngày hôm nay, theo mặc định. Theo tôi (và kinh nghiệm), kiểm thử đơn vị là tuyệt vời cho các thư viện / API; trong các lĩnh vực định hướng kinh doanh nhiều hơn (nơi chúng ta nói về các trường hợp sử dụng như trong câu hỏi), chúng không nhất thiết là lựa chọn tốt nhất.

Đối với mã ứng dụng chung và trong doanh nghiệp trung bình (nơi kiếm tiền, đạt thời hạn và đáp ứng sự hài lòng của khách hàng là điều quan trọng và bạn chủ yếu muốn tránh các lỗi trực tiếp trên mặt người dùng hoặc có thể dẫn đến thảm họa thực sự - chúng tôi không nói NASA phóng tên lửa ở đây), tích hợp hoặc tính năng kiểm tra là nhiều hơn hữu ích.

Những người đi đôi với Phát triển hướng hành vi hoặc Phát triển theo hướng tính năng; những người không làm việc với các bài kiểm tra đơn vị (nghiêm ngặt), theo định nghĩa.

Để giữ cho nó ngắn (ish), một bài kiểm tra tích hợp / tính năng thực hiện toàn bộ ngăn xếp ứng dụng. Trong một ứng dụng dựa trên web, nó sẽ hoạt động giống như một trình duyệt nhấp qua ứng dụng (và không, rõ ràng không cần phải đơn giản như vậy, có những khung rất mạnh để thực hiện điều đó - hãy xem http: // dưa chuột. io cho một ví dụ).

Ồ, để trả lời các câu hỏi cuối cùng của bạn: bạn khiến cả nhóm của bạn có phạm vi kiểm tra cao bằng cách đảm bảo rằng một tính năng mới chỉ được lập trình sau khi thử nghiệm tính năng của nó đã được triển khai và thất bại. Và vâng, điều đó có nghĩa là mọi tính năng. Điều này đảm bảo cho bạn phạm vi bảo hiểm 100% (tích cực). Theo định nghĩa, nó đảm bảo rằng một tính năng của ứng dụng của bạn sẽ không bao giờ "biến mất". Nó không đảm bảo phạm vi bảo hiểm 100% mã (ví dụ: trừ khi bạn chủ động lập trình các tính năng tiêu cực, bạn sẽ không thực hiện xử lý lỗi / xử lý ngoại lệ).

Nó không đảm bảo cho bạn một ứng dụng không có lỗi; tất nhiên bạn sẽ muốn viết các bài kiểm tra tính năng cho các tình huống lỗi rõ ràng hoặc rất nguy hiểm, nhập sai người dùng, hack (ví dụ: quản lý phiên xung quanh, bảo mật và như vậy), v.v .; nhưng ngay cả chỉ lập trình các bài kiểm tra tích cực cũng mang lại lợi ích to lớn và hoàn toàn khả thi với các khung hiện đại, mạnh mẽ.

Các thử nghiệm tính năng / tích hợp rõ ràng có các con giun riêng (ví dụ: hiệu năng; thử nghiệm dự phòng khung bên thứ 3; vì bạn thường không sử dụng gấp đôi nên chúng cũng có xu hướng khó viết hơn, theo kinh nghiệm của tôi ...), nhưng tôi d dùng ứng dụng được kiểm tra tính năng tích cực 100% so với ứng dụng được kiểm tra đơn vị 100% mã (không phải thư viện!) mỗi ngày.


1
Kiểm thử tích hợp là tuyệt vời nhưng không thay thế cho kiểm tra đơn vị, cũng không phải cho các ứng dụng kinh doanh. Có nhiều vấn đề với chúng: a) theo định nghĩa, chúng mất nhiều thời gian để chạy (điều đó cũng có nghĩa là các bài kiểm tra gia tăng khá vô dụng), b) chúng làm cho việc xác định vấn đề thực sự rất khó khăn (oh 50 bài kiểm tra tích hợp vừa thất bại, sự thay đổi nào gây ra điều đó?) và c) chúng bao gồm các đường dẫn mã giống nhau lặp đi lặp lại.
Voo

1
a) là một vấn đề vì nó làm cho việc chạy thử nghiệm trên các kiểm tra bị kiểm soát cồng kềnh và làm cho các lập trình viên ít có thể chạy thử nghiệm nhiều lần trong khi phát triển, kết hợp với b) làm giảm hiệu quả và khả năng chẩn đoán nhanh lỗi. c) có nghĩa là việc thay đổi một điều nhỏ có thể dễ dàng khiến hàng chục hoặc hàng trăm (đã có) các bài kiểm tra tích hợp của bạn không thành công, điều đó có nghĩa là bạn sẽ mất rất nhiều thời gian để sửa chúng. Điều này cũng có nghĩa là các bài kiểm tra tích hợp chủ yếu chỉ kiểm tra các đường dẫn hạnh phúc, bởi vì việc viết các bài kiểm tra này được nhắm mục tiêu là cồng kềnh hoặc không thể.
Voo

1
@Voo, tất cả những gì bạn viết là đúng, và theo như tôi có thể nói tôi đã đề cập đến tất cả các vấn đề bạn lưu ý trong câu trả lời ...
AnoE

Nếu bạn đồng ý với bản tóm tắt đó, tôi thực sự không thấy làm thế nào bạn có thể đi đến kết luận rằng bạn thích kiểm tra tích hợp hơn các bài kiểm tra đơn vị. Các bộ kiểm thử tích hợp toàn diện của các chương trình lớn phải mất hàng giờ hoặc thậm chí vài ngày để chạy, chúng rất tuyệt để có nhưng vô dụng trong quá trình phát triển thực tế. Và các bài kiểm tra chấp nhận của bạn (điều mà mọi người đang làm, phải không?) Sẽ nắm bắt được nhiều vấn đề tương tự mà các bài kiểm tra tích hợp sẽ thấy bị bỏ qua bởi các bài kiểm tra đơn vị - mặc dù điều ngược lại là không đúng.
Voo

24

Có, có thể có quá nhiều bài kiểm tra đơn vị. Nếu bạn có phạm vi bảo hiểm 100% với các bài kiểm tra đơn vị và không có bài kiểm tra tích hợp nào, bạn có một vấn đề rõ ràng.

Một số tình huống:

  1. Bạn quá kỹ sư kiểm tra của bạn để thực hiện cụ thể. Sau đó, bạn phải vứt bỏ các bài kiểm tra đơn vị khi bạn cấu trúc lại, không nói khi bạn thay đổi triển khai (một điểm đau rất thường xuyên khi thực hiện tối ưu hóa hiệu suất).

    Một sự cân bằng tốt giữa các bài kiểm tra đơn vị và kiểm tra tích hợp làm giảm vấn đề này mà không mất phạm vi bảo hiểm đáng kể.

  2. Bạn có thể có phạm vi bảo hiểm hợp lý cho mỗi cam kết với 20% bài kiểm tra bạn có, để lại 80% còn lại để tích hợp hoặc ít nhất là các bài kiểm tra riêng biệt; các tác động tiêu cực chính mà bạn thấy trong kịch bản này là những thay đổi chậm do bạn phải chờ một thời gian lớn để các thử nghiệm được thực thi.

  3. Bạn sửa đổi quá nhiều mã để cho phép bạn kiểm tra nó; ví dụ, tôi đã thấy rất nhiều sự lạm dụng IoC trên các thành phần sẽ không bao giờ cần phải sửa đổi hoặc ít nhất là rất tốn kém và ưu tiên thấp để khái quát hóa chúng, nhưng mọi người đầu tư rất nhiều thời gian để tổng quát hóa và tái cấu trúc chúng để cho phép thử nghiệm đơn vị chúng .

Tôi đặc biệt đồng ý với đề xuất nhận bảo hiểm 50% cho 100% tệp, thay vì bảo hiểm 100% cho 50% tệp; tập trung nỗ lực ban đầu của bạn vào các trường hợp tích cực phổ biến nhất và các trường hợp tiêu cực nguy hiểm nhất, không đầu tư quá nhiều vào xử lý lỗi và các đường dẫn bất thường, không phải vì chúng không quan trọng mà vì bạn có thời gian hạn chế và vũ trụ thử nghiệm vô hạn, Vì vậy, bạn cần phải ưu tiên cho bất kỳ trường hợp.


2
Đây không phải là vấn đề với các bài kiểm tra đơn vị, nhưng với tổ chức vì đã ưu tiên sai bằng cách yêu cầu một số cụ thể cho phạm vi kiểm tra đơn vị mà không tốn tài nguyên để tạo và thực hiện các bài kiểm tra phù hợp ở các cấp độ khác.
jwenting

2
Đồng ý mạnh mẽ về # 3 và cũng sẽ mở rộng nó để chuyển thủ công trong các trường hợp của các lớp cấp thấp hơn đến các lớp cấp cao hơn. Nếu một thứ cấp cao phụ thuộc vào một số thứ cấp thấp để hoàn thành công việc, thì không sao. Nếu nó che giấu các chi tiết đó từ người gọi, tôi sẽ gọi đó là thiết kế tốt. Nhưng nếu sau đó bạn biến phần thứ cấp thấp của giao diện vật cấp cao và khiến người gọi vượt qua vì nó làm cho bài kiểm tra của bạn đẹp, thì bây giờ cái đuôi đang vẫy con chó. (Nếu vật phẩm cấp thấp được tái sử dụng ở nhiều nơi và thay đổi rất nhiều, điều đó sẽ thay đổi mọi thứ. Theo kinh nghiệm của tôi, đó không phải là điển hình.)
johncip

Tôi thích mô tả của bạn @johncip, chắc chắn đó là một ví dụ thường thấy về việc một lớp tốt đẹp trở nên khủng khiếp như thế nào bằng cách thêm một loạt các tham số cần thiết không cần thiết cho nhà xây dựng ...
Bruno Guardia

19

Hãy nhớ rằng mỗi bài kiểm tra có một chi phí cũng như một lợi ích. Hạn chế bao gồm:

  • một bài kiểm tra phải được viết;
  • một bài kiểm tra mất (thường là một lượng rất nhỏ) thời gian để chạy;
  • một thử nghiệm phải được duy trì với mã - các thử nghiệm phải thay đổi khi các API mà chúng đang thử nghiệm thay đổi;
  • bạn có thể phải thay đổi thiết kế của mình để viết bài kiểm tra (mặc dù những thay đổi này thường là tốt hơn).

Nếu chi phí vượt xa lợi ích, một bài kiểm tra tốt hơn là không nên viết. Ví dụ: nếu chức năng khó kiểm tra, API thay đổi thường xuyên, tính chính xác tương đối không quan trọng và khả năng kiểm tra tìm thấy lỗi là thấp, có lẽ bạn không nên viết nó.

Đối với tỷ lệ kiểm tra cụ thể của bạn đối với mã, nếu mã đủ dày đặc logic thì tỷ lệ đó có thể được bảo hành. Tuy nhiên, có lẽ không đáng để duy trì tỷ lệ cao như vậy trong suốt một ứng dụng thông thường.


12

Vâng, có một điều như quá nhiều bài kiểm tra đơn vị.

Trong khi kiểm tra là tốt, mọi kiểm tra đơn vị là:

  • Một gánh nặng bảo trì tiềm năng được kết hợp chặt chẽ với API

  • Thời gian có thể dành cho việc khác

  • Một lát thời gian trong bộ Kiểm tra đơn vị
  • Có thể không thêm giá trị thực vì nó có hiệu lực trùng lặp với một số thử nghiệm khác có cơ hội rất nhỏ mà một số thử nghiệm khác sẽ vượt qua và thử nghiệm này sẽ thất bại.

Sẽ là khôn ngoan khi nhắm đến phạm vi bảo hiểm mã 100% nhưng điều đó không có nghĩa là một bộ thử nghiệm mà mỗi thử nghiệm cung cấp độc lập 100% mã trên một số điểm nhập được chỉ định (chức năng / phương thức / cuộc gọi, v.v.).

Mặc dù được đưa ra mức độ khó để có thể đạt được phạm vi bảo hiểm tốt và loại bỏ các lỗi nhưng sự thật có lẽ là có một thứ như 'các bài kiểm tra đơn vị sai' cũng như 'quá nhiều bài kiểm tra đơn vị'.

Thực dụng cho hầu hết các mã chỉ ra:

  1. Hãy chắc chắn rằng bạn có phạm vi bao phủ 100% của các điểm vào (mọi thứ sẽ được kiểm tra bằng cách nào đó) và nhằm mục đích gần với phạm vi bao phủ 100% mã của các đường dẫn 'không lỗi'.

  2. Kiểm tra mọi giá trị hoặc kích thước tối thiểu / tối đa có liên quan

  3. Kiểm tra bất cứ điều gì bạn nghĩ là một trường hợp đặc biệt hài hước đặc biệt là các giá trị 'lẻ'.

  4. Khi bạn tìm thấy một lỗi, hãy thêm một bài kiểm tra đơn vị sẽ phát hiện ra lỗi đó và suy nghĩ xem có nên thêm trường hợp tương tự nào không.

Đối với các thuật toán phức tạp hơn cũng xem xét:

  1. Làm một số thử nghiệm số lượng lớn của nhiều trường hợp.
  2. So sánh kết quả với việc thực hiện 'lực lượng vũ phu' và kiểm tra các bất biến.
  3. Sử dụng một số phương pháp sản xuất các trường hợp thử nghiệm ngẫu nhiên và kiểm tra chống lại vũ phu và các điều kiện hậu kỳ bao gồm cả bất biến.

Ví dụ: kiểm tra thuật toán sắp xếp với một số đầu vào ngẫu nhiên và xác thực dữ liệu được sắp xếp ở cuối bằng cách quét nó.

Tôi muốn nói rằng lãnh đạo công nghệ của bạn đang đề xuất thử nghiệm 'mông trần tối thiểu'. Tôi đang cung cấp 'thử nghiệm chất lượng giá trị cao nhất' và có một phổ ở giữa.

Có thể cấp cao của bạn biết thành phần bạn đang xây dựng sẽ được nhúng vào một số phần lớn hơn và đơn vị được kiểm tra kỹ lưỡng hơn khi được tích hợp.

Bài học quan trọng là thêm các bài kiểm tra khi tìm thấy lỗi. Điều này dẫn tôi đến bài học tốt nhất của tôi về việc phát triển các bài kiểm tra đơn vị:

Tập trung vào các đơn vị không phải là đơn vị phụ. Nếu bạn đang xây dựng một đơn vị ngoài các đơn vị phụ, hãy viết các bài kiểm tra rất cơ bản cho các đơn vị phụ cho đến khi chúng hợp lý và đạt được phạm vi bảo hiểm tốt hơn bằng cách kiểm tra các đơn vị phụ thông qua các đơn vị kiểm soát của chúng.

Vì vậy, nếu bạn đang viết một trình biên dịch và cần phải viết một bảng ký hiệu (giả sử). Nhận bảng biểu tượng và chạy với một bài kiểm tra cơ bản và sau đó làm việc (giả sử) trình phân tích cú pháp khai báo điền vào bảng. Chỉ thêm các thử nghiệm thêm vào đơn vị 'độc lập' của bảng biểu tượng nếu bạn tìm thấy lỗi trong đó. Mặt khác, tăng độ bao phủ bằng các thử nghiệm đơn vị trên trình phân tích cú pháp khai báo và sau đó là toàn bộ trình biên dịch.

Điều đó đạt được hiệu quả tốt nhất (một thử nghiệm của toàn bộ là thử nghiệm nhiều thành phần) và để lại nhiều năng lực hơn cho thiết kế lại và sàng lọc vì chỉ giao diện 'bên ngoài' được sử dụng trong các thử nghiệm có xu hướng ổn định hơn.

Kết hợp với các điều kiện trước kiểm tra mã gỡ lỗi, các điều kiện hậu bao gồm các bất biến ở tất cả các cấp bạn có được phạm vi kiểm tra tối đa từ việc thực hiện kiểm tra tối thiểu.


4
Tôi sẽ không nói rằng bảo hiểm 100% là thực dụng. Bảo hiểm 100% là một tiêu chuẩn cực kỳ cao.
Bryan Oakley

Thật không may, ngay cả phương pháp ngẫu nhiên cũng có thể bỏ lỡ lỗi. Không có thay thế cho bằng chứng, ngay cả khi không chính thức.
Frank Hileman

@BryanOakley Điểm lấy. Đó là một lời nói quá. Nhưng điều quan trọng là đến gần nó hơn là mọi người cho tín dụng. "Tôi đã thử nghiệm con đường dễ dàng, tất cả đều tốt" sẽ luôn gây ra vấn đề sau này.
Persixty

@FrankHileman Câu hỏi không phải là "Thử nghiệm đơn vị có phải là sự thay thế tốt cho việc thiết kế phần mềm một cách cẩn thận, logic kiểm tra tĩnh và thuật toán chứng minh" không thì câu trả lời là 'không'. Cả hai phương pháp sẽ không tự sản xuất phần mềm chất lượng cao.
Persixty

3

Thứ nhất, không nhất thiết phải có nhiều dòng thử nghiệm hơn mã sản xuất. Mã kiểm tra là (hoặc nên) tuyến tính và dễ hiểu - độ phức tạp cần thiết của nó là rất, rất thấp, cho dù mã sản xuất có hay không. Nếu độ phức tạp của các thử nghiệm bắt đầu tiếp cận với mã sản xuất, thì có khả năng bạn đã gặp vấn đề.

Có, có thể có quá nhiều thử nghiệm đơn vị - một thử nghiệm suy nghĩ đơn giản cho thấy rằng bạn có thể tiếp tục thêm các thử nghiệm không cung cấp giá trị bổ sung và tất cả các thử nghiệm được thêm vào đó có thể ức chế ít nhất một số phép tái cấu trúc.

Theo tôi, lời khuyên chỉ kiểm tra những trường hợp phổ biến nhất là thiếu sót. Chúng có thể hoạt động như các thử nghiệm khói để tiết kiệm thời gian thử nghiệm hệ thống, nhưng các thử nghiệm thực sự có giá trị bắt các trường hợp khó thực hiện trong toàn hệ thống. Ví dụ, có thể sử dụng lỗi được kiểm soát đối với các lỗi cấp phát bộ nhớ để thực hiện các đường dẫn khôi phục có thể có chất lượng hoàn toàn không xác định. Hoặc vượt qua số 0 dưới dạng giá trị mà bạn biết sẽ được sử dụng làm số chia (hoặc số âm sẽ được căn bậc hai) và đảm bảo bạn không nhận được ngoại lệ chưa được xử lý.

Các bài kiểm tra có giá trị tiếp theo là những bài kiểm tra giới hạn cực hạn hoặc điểm biên. Ví dụ: một hàm chấp nhận các tháng (dựa trên 1) trong năm nên được kiểm tra bằng 0, 1, 12 và 13, để bạn biết rằng các chuyển đổi hợp lệ-không hợp lệ được đặt đúng chỗ. Đó là thử nghiệm quá mức để sử dụng 2..11 cho các thử nghiệm này.

Bạn đang ở một vị trí khó khăn, trong đó bạn phải viết các bài kiểm tra cho mã hiện có. Dễ dàng hơn để xác định các trường hợp cạnh khi bạn đang viết (hoặc sắp viết) mã.


3

Sự hiểu biết của tôi về kiểm thử đơn vị là kiểm tra từng phương thức trong lớp để đảm bảo rằng mọi phương thức đều hoạt động như mong đợi.

Cách hiểu này là sai.

Kiểm tra đơn vị xác minh hành vi của đơn vị được kiểm tra .

Theo nghĩa đó, một đơn vị không nhất thiết là "một phương thức trong một lớp". Tôi thích định nghĩa của một đơn vị của Roy Osherove trong Nghệ thuật kiểm tra đơn vị :

Một đơn vị là tất cả các mã sản xuất có cùng lý do để thay đổi.

Dựa trên điều này, một bài kiểm tra đơn vị sẽ xác minh mọi hành vi mong muốn của mã của bạn. Trường hợp "mong muốn" ít nhiều được lấy từ các yêu cầu.


Tuy nhiên, trong yêu cầu kéo, lãnh đạo công nghệ của tôi lưu ý rằng tôi nên tập trung vào thử nghiệm cấp cao hơn.

Anh ấy đúng, nhưng theo một cách khác hơn anh ấy nghĩ.

Từ câu hỏi của bạn, tôi hiểu rằng bạn là "người thử nghiệm chuyên dụng" trong dự án đó.

Sự hiểu lầm lớn là anh ta mong bạn viết bài kiểm tra đơn vị (ngược lại với "kiểm tra bằng cách sử dụng khung kiểm tra đơn vị"). Viết các bài kiểm tra ynit là trách nhiệm của các nhà phát triển , không phải người kiểm tra (trong một thế giới lý tưởng, tôi biết ...). Mặt khác, bạn đã gắn thẻ câu hỏi này với TDD, ngụ ý chính xác điều này.

Công việc của bạn là người kiểm tra là viết (hoặc thực hiện thủ công) mô-đun và / hoặc kiểm tra ứng dụng. Và loại thử nghiệm này chủ yếu nên xác minh rằng tất cả các đơn vị làm việc trơn tru với nhau. Điều đó có nghĩa là bạn phải chọn các trường hợp thử nghiệm của mình để mỗi đơn vị được thực hiện ít nhất một lần . Và kiểm tra đó là chạy. Kết quả thực tế ít quan trọng hơn vì nó có thể thay đổi với các yêu cầu trong tương lai.

Để nhấn mạnh sự tương tự ô tô đổ một lần nữa: Có bao nhiêu thử nghiệm được thực hiện với một chiếc xe ở cuối dây chuyền lắp ráp? Chính xác là một: nó phải tự lái xe đến bãi đậu xe ...

Vấn đề ở đây là:

Chúng ta cần nhận thức được sự khác biệt đó giữa "kiểm tra đơn vị" và "kiểm tra tự động bằng cách sử dụng khung kiểm tra đơn vị".


Đối với tôi, phạm vi kiểm tra đơn vị 100% là một mục tiêu cao cả, nhưng ngay cả khi chúng tôi chỉ đạt 50%, chúng tôi sẽ biết rằng 100% trong số 50% đó được bảo hiểm.

Kiểm tra đơn vị là một mạng lưới an toàn. Họ cung cấp cho bạn sự tự tin để cấu trúc lại mã của bạn để giảm nợ kỹ thuật hoặc thêm hành vi mới mà không sợ phá vỡ hành vi đã thực hiện.

Bạn không cần bảo hiểm 100% mã.

Nhưng bạn cần bảo hiểm hành vi 100%. (Có, phạm vi bảo hiểm mã và phạm vi bảo hiểm tương quan bằng cách nào đó, nhưng chúng không giống nhau vì lợi ích của nó.)

Nếu bạn có phạm vi bảo hiểm dưới 100%, việc chạy bộ thử nghiệm thành công có nghĩa là không có gì vì bạn có thể đã thay đổi một số hành vi chưa được kiểm tra. Và bạn sẽ được khách hàng chú ý ngay sau ngày phát hành trực tuyến ...


Phần kết luận

Vài bài kiểm tra tốt hơn không có bài kiểm tra. Không còn nghi ngờ gì nữa!

Nhưng không có gì giống như có quá nhiều bài kiểm tra đơn vị.

Điều này là do mỗi bài kiểm tra đơn vị xác minh một kỳ vọng duy nhất về hành vi mã . Và bạn không thể viết nhiều bài kiểm tra đơn vị hơn bạn mong đợi về mã của mình. Và một lỗ hổng trong dây nịt an toàn của bạn là cơ hội cho một sự thay đổi không mong muốn gây hại cho hệ thống sản xuất.


2

Hoàn toàn đồng ý. Tôi từng là một SDET cho một công ty phần mềm lớn. Nhóm nhỏ của chúng tôi đã phải duy trì mã kiểm tra đã từng được xử lý bởi một nhóm lớn hơn nhiều. Trên hết, sản phẩm của chúng tôi có một số phụ thuộc liên tục đưa ra các thay đổi đột phá, có nghĩa là bảo trì thử nghiệm liên tục cho chúng tôi. Chúng tôi không có tùy chọn để tăng quy mô đội, vì vậy chúng tôi đã phải vứt bỏ hàng ngàn bài kiểm tra ít giá trị hơn khi chúng thất bại. Nếu không, chúng tôi sẽ không bao giờ có thể theo kịp các khiếm khuyết.

Trước khi bạn loại bỏ điều này như một vấn đề quản lý đơn thuần, hãy xem xét rằng nhiều dự án trong thế giới thực bị giảm nhân sự khi họ tiếp cận tình trạng di sản. Đôi khi nó thậm chí bắt đầu xảy ra ngay sau khi phát hành đầu tiên.


4
"Trên hết, sản phẩm của chúng tôi có một số phụ thuộc liên tục đưa ra các thay đổi đột phá, có nghĩa là bảo trì thử nghiệm liên tục cho chúng tôi." - Những bài kiểm tra mà bạn nói yêu cầu bảo trì âm thanh như những bài kiểm tra có giá trị nếu sự phụ thuộc của bạn liên tục bị phá vỡ.
CodeMonkey

2
Đó không phải là vấn đề với các bài kiểm tra, nhưng với tổ chức.
jwenting

2
@CodeMonkey Các phụ thuộc không bị phá vỡ. Họ đã được cập nhật theo cách yêu cầu thay đổi sản phẩm của chúng tôi. Vâng, các bài kiểm tra là có giá trị, nhưng gần như không có giá trị như những người khác. Kiểm tra tự động có giá trị nhất khi kiểm tra thủ công tương đương khó.
mrog

2
@jwenting Vâng, đó là vấn đề tổ chức, không phải vấn đề về mã. Nhưng điều đó không thay đổi thực tế là có quá nhiều bài kiểm tra. Một bài kiểm tra thất bại không thể điều tra là vô ích, bất kể nguyên nhân.
mrog

"SDET" là gì?
Peter Mortensen

1

Có nhiều dòng mã kiểm tra hơn mã sản phẩm không nhất thiết là một vấn đề, giả sử bạn đang cấu trúc lại mã kiểm tra để loại bỏ sao chép-dán.

Vấn đề là có các bài kiểm tra là tấm gương phản chiếu việc triển khai của bạn, không có ý nghĩa kinh doanh - ví dụ: các bài kiểm tra được tải bằng giả và sơ khai và chỉ khẳng định rằng một phương thức gọi một phương thức khác.

Một câu trích dẫn tuyệt vời trong bài viết "tại sao hầu hết các thử nghiệm đơn vị là lãng phí" là các thử nghiệm đơn vị nên có một "lời tiên tri rộng rãi, chính thức, độc lập về tính chính xác và ... giá trị kinh doanh có thể hiểu được"


0

Một điều tôi không thấy được đề cập là các bài kiểm tra của bạn cần phải nhanh chóng và dễ dàng cho bất kỳ nhà phát triển nào có thể chạy bất cứ lúc nào.

Bạn không muốn phải kiểm tra kiểm soát nguồn và đợi một giờ hoặc hơn (tùy thuộc vào kích thước cơ sở mã của bạn) trước khi kiểm tra hoàn tất để xem liệu thay đổi của bạn có phá vỡ điều gì không - bạn muốn có thể làm điều đó trên máy riêng của bạn trước khi bạn đăng ký để kiểm soát nguồn (hoặc ít nhất, trước khi bạn thay đổi). Lý tưởng nhất, bạn sẽ có thể chạy thử nghiệm của mình với một tập lệnh hoặc nhấn nút.

Và khi bạn chạy các thử nghiệm đó cục bộ, bạn muốn chúng chạy nhanh - theo thứ tự giây. Bất kỳ chậm hơn, và bạn sẽ bị cám dỗ để không chạy chúng đủ hoặc tất cả.

Vì vậy, có quá nhiều bài kiểm tra chạy tất cả chúng mất vài phút hoặc có một vài bài kiểm tra quá phức tạp có thể là một vấ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.