Đơn vị kiểm tra nhiều điều kiện trong một câu lệnh IF


25

Tôi có một đoạn mã trông giống như thế này:

function bool PassesBusinessRules()
{
    bool meetsBusinessRules = false;

    if (PassesBusinessRule1 
         && PassesBusinessRule2
         && PassesBusinessRule3)
    {
         meetsBusinessRules= true;
    }

    return meetsBusinessRules;
}

Tôi tin rằng nên có bốn bài kiểm tra đơn vị cho chức năng đặc biệt này. Ba để kiểm tra từng điều kiện trong câu lệnh if và đảm bảo nó trả về false. Và một thử nghiệm khác đảm bảo chức năng trả về đúng.

Câu hỏi: Có nên thực sự có mười bài kiểm tra đơn vị thay thế? Chín mà kiểm tra từng con đường thất bại có thể. I E:

  • Sai Sai Sai
  • Sai Sai Đúng
  • Sai Đúng Sai

Và như vậy cho mỗi sự kết hợp có thể.

Tôi nghĩ đó là quá mức cần thiết, nhưng một số thành viên khác trong nhóm của tôi thì không. Cách tôi nhìn nhận là nếu BusinessRule1 thất bại thì nó sẽ luôn trả về false, không quan trọng nếu nó được kiểm tra trước hay cuối cùng.


Trình biên dịch có sử dụng đánh giá tham lam cho toán tử && không?
suszterpatt

12
Nếu bạn đã viết 10 bài kiểm tra đơn vị, bạn sẽ kiểm tra && toán tử, không phải phương thức của bạn.
Mert Akcakaya

2
Sẽ không có tám bài kiểm tra nếu bạn đã kiểm tra tất cả các kết hợp có thể? Ba tham số boolean bật hoặc tắt.
Kris Harper

3
@Mert: Chỉ khi bạn có thể đảm bảo rằng && sẽ luôn ở đó.
Misko

Hickey: Nếu chúng ta dành nó để viết bài kiểm tra, đó là thời gian chúng ta không dành để làm việc khác. Mỗi người trong chúng ta cần đánh giá cách sử dụng thời gian tốt nhất để tối đa hóa kết quả của mình, cả về số lượng và chất lượng. Nếu mọi người nghĩ rằng dành năm mươi phần trăm thời gian của họ để viết bài kiểm tra thì tối đa hóa kết quả của họ, thì họ ổn cho họ. Tôi chắc chắn điều đó không đúng với tôi. Tôi muốn dành thời gian đó để suy nghĩ về vấn đề của mình. Tôi chắc chắn rằng, đối với tôi, điều này tạo ra các giải pháp tốt hơn, với ít khuyết điểm hơn bất kỳ việc sử dụng thời gian nào khác của tôi. Một thiết kế xấu với một bộ thử nghiệm hoàn chỉnh vẫn là một thiết kế tồi.
Công việc

Câu trả lời:


28

Chính thức, những loại bảo hiểm có tên.

Đầu tiên, có phạm vi bảo hiểm vị ngữ : bạn muốn có một trường hợp thử nghiệm làm cho câu lệnh if đúng và một trường hợp làm cho nó sai. Có bảo hiểm này đáp ứng có lẽ là một yêu cầu cơ bản cho một bộ thử nghiệm tốt.

Sau đó, có Điều kiện bảo hiểm : Ở đây bạn muốn kiểm tra rằng mỗi điều kiện phụ trong if có giá trị đúng và sai. Điều này rõ ràng tạo ra nhiều thử nghiệm hơn, nhưng nó thường bắt được nhiều lỗi hơn, vì vậy thường nên đưa vào bộ thử nghiệm của bạn nếu bạn có thời gian.

Các tiêu chí bảo hiểm tiên tiến nhất thường được gọi là Bảo hiểm điều kiện kết hợp : Ở đây mục tiêu là có một trường hợp thử nghiệm đi qua tất cả các kết hợp có thể có của các giá trị boolean trong thử nghiệm của bạn.

Đây có phải là tốt hơn so với vị ngữ đơn giản hoặc điều kiện bảo hiểm? Về mặt bảo hiểm, tất nhiên. Nhưng nó không miễn phí. Nó đi kèm với chi phí rất cao trong bảo trì thử nghiệm. Vì lý do này, hầu hết mọi người không bận tâm với bảo hiểm tổ hợp đầy đủ. Thông thường kiểm tra tất cả các chi nhánh (hoặc tất cả các điều kiện), sẽ đủ tốt để bắt lỗi. Việc thêm các bài kiểm tra bổ sung cho kiểm tra kết hợp thường sẽ không gặp nhiều lỗi hơn, nhưng đòi hỏi rất nhiều nỗ lực để tạo và duy trì. Nỗ lực thêm thường làm cho việc này không xứng đáng với số tiền rất nhỏ, vì vậy tôi không khuyến nghị điều này.

Một phần của quyết định này nên dựa trên mức độ rủi ro mà bạn nghĩ rằng mã đó sẽ có rủi ro. Nếu nó có nhiều chỗ để thất bại, nó đáng để thử nghiệm. Nếu nó hơi ổn định và sẽ không thay đổi nhiều, bạn nên xem xét việc tập trung nỗ lực thử nghiệm của mình vào nơi khác.


2
Nếu các giá trị boolean được truyền từ các nguồn bên ngoài (có nghĩa là chúng không luôn được xác nhận), thì bảo hiểm điều kiện tổ hợp thường là cần thiết. Đầu tiên tạo một bảng kết hợp. Sau đó, đối với mỗi mục, hãy quyết định xem mục đó đại diện cho trường hợp sử dụng có ý nghĩa hay không. Nếu không, cần có mã ở đâu đó (hoặc xác nhận phần mềm hoặc mệnh đề xác nhận) để ngăn sự kết hợp đó được thực thi. Điều quan trọng là không gộp tất cả các tham số trong một thử nghiệm kết hợp duy nhất: cố gắng phân vùng các tham số thành các nhóm tương tác với nhau, tức là chia sẻ cùng một biểu thức boolean.
rwong

Làm thế nào chắc chắn là bạn của các điều khoản in đậm? Câu trả lời của bạn dường như là sự xuất hiện duy nhất của "Phạm vi điều kiện kết hợp" và một số tài nguyên nói rằng "phạm vi vị ngữ" và "phạm vi điều kiện" là như nhau.
Stijn

8

Cuối cùng, nó phụ thuộc vào bạn (nhóm r), mã và môi trường dự án cụ thể. Không có quy tắc phổ quát. Bạn (nhóm r) nên viết nhiều bài kiểm tra như bạn cần để cảm thấy thoải mái rằng mã thực sự chính xác . Vì vậy, nếu đồng đội của bạn không bị thuyết phục bởi 4 bài kiểm tra, có thể bạn cần nhiều hơn nữa.

Thời gian OTOH để viết bài kiểm tra đơn vị thường là một nguồn tài nguyên khan hiếm. Vì vậy, phấn đấu để tìm ra cách tốt nhất để dành thời gian giới hạn bạn có . Ví dụ: nếu bạn có một phương pháp quan trọng khác với độ bao phủ 0%, có thể tốt hơn là viết một vài bài kiểm tra đơn vị để bao quát phương pháp đó, thay vì thêm các bài kiểm tra bổ sung cho phương pháp này. Tất nhiên, nó cũng phụ thuộc vào mức độ mong manh của việc thực hiện từng cái. Lập kế hoạch rất nhiều thay đổi cho phương pháp cụ thể này trong tương lai gần có thể biện minh cho phạm vi kiểm tra đơn vị bổ sung. Vì vậy, có thể đang trên một con đường quan trọng trong chương trình. Đây là tất cả các yếu tố mà chỉ bạn (nhóm r) có thể đánh giá.

Cá nhân tôi thường rất vui với 4 bài kiểm tra mà bạn vạch ra, đó là:

  • đúng sai sai
  • sai đúng sai
  • sai sai đúng
  • đúng thật đúng

cộng có thể một:

  • đúng đúng sai

để đảm bảo rằng cách duy nhất để có được giá trị hoàn trả truelà đáp ứng cả 3 quy tắc kinh doanh. Nhưng cuối cùng, nếu đồng đội của bạn khăng khăng có các đường tổ hợp được bảo hiểm, có thể rẻ hơn khi thêm các bài kiểm tra bổ sung đó hơn là tiếp tục cuộc tranh luận lâu hơn nhiều :-)


3

Nếu bạn muốn an toàn, bạn sẽ cần tám bài kiểm tra đơn vị bằng cách sử dụng các điều kiện được biểu thị bằng bảng chân thực ba biến ( http://teach.valdosta.edu/plmoch/MATH4161/Spring%202004/and_or_if_files/image006.gif ).

Bạn không bao giờ có thể chắc chắn rằng logic nghiệp vụ sẽ luôn quy định rằng các kiểm tra được thực hiện theo thứ tự đó và bạn muốn kiểm tra biết càng ít về việc triển khai thực tế càng tốt.


2
Kiểm thử đơn vị kiểm thử hộp trắng.
Péter Török

Thứ tự cũng không thành vấn đề, && mang tính cộng đồng, hoặc ít nhất nên là
Zachary K

2

Vâng, nên có sự kết hợp đầy đủ trong một thế giới lý tưởng.

Khi làm bài kiểm tra đơn vị, bạn thực sự nên cố gắng bỏ qua cách phương thức thực hiện. Chỉ cần cung cấp 3 đầu vào và xác minh rằng đầu ra là chính xác.


1
Kiểm thử đơn vị kiểm thử hộp trắng. Và chúng ta không sống trong một thế giới lý tưởng.
Péter Török

@ PéterTörök - Chúng tôi không sống trong một thế giới lý tưởng, nhưng stackexchange không đồng ý với bạn ở điểm khác. Đặc biệt đối với TDD, các bài kiểm tra được viết theo thông số kỹ thuật, không phải việc thực hiện. Cá nhân tôi lấy 'đặc tả' để bao gồm tất cả các đầu vào (bao gồm cả các biến thành viên) và tất cả các đầu ra (bao gồm cả các tác dụng phụ).
Telastyn

1
Đây chỉ là một luồng cụ thể trên StackOverflow, về một trường hợp cụ thể, không nên quá mức. Đặc biệt là bài viết hiện tại rõ ràng là về mã thử nghiệm đã được viết.
Péter Török

1

Nhà nước là ác. Các chức năng sau đây không cần kiểm tra đơn vị vì nó không có tác dụng phụ và nó được hiểu rõ những gì nó làm và những gì nó không làm. Tại sao phải kiểm tra nó? Bạn không tin tưởng bộ não của chính mình ??? Hàm tĩnh rất tuyệt!

static function bool Foo(bool a, bool b, bool c)
{
    return a && b && c;
}

2
Không, tôi không tin vào bộ não của chính mình - Tôi đã học được cách khó khăn để luôn kiểm tra kỹ những gì tôi làm :-) Vì vậy, tôi vẫn sẽ cần các bài kiểm tra đơn vị để đảm bảo rằng tôi đã không nhầm lẫn bất cứ điều gì, và sẽ không có ai đi để phá mã trong tương lai. Và nhiều bài kiểm tra đơn vị hơn để xác minh phương thức người gọi tính toán trạng thái được biểu thị bởi a, bc. Bạn có thể di chuyển logic kinh doanh xung quanh bất kỳ cách nào bạn muốn, cuối cùng bạn vẫn cần kiểm tra nó ở đâu đó.
Péter Török

@ Péter Török, bạn cũng có thể mắc lỗi chính tả trong các bài kiểm tra của mình và do đó kết thúc với kết quả dương tính giả, vậy bạn sẽ dừng ở đâu? Bạn có viết bài kiểm tra đơn vị cho bài kiểm tra đơn vị của bạn? Tôi cũng không tin tưởng bộ não của mình 100%, nhưng vào cuối ngày viết mã là những gì tôi làm để kiếm sống. Có thể có một lỗi bên trong chức năng này nhưng điều quan trọng là viết mã theo cách mà một lỗi sẽ dễ dàng theo dõi nguồn và do đó, khi bạn tách biệt vấn đề và đã khắc phục, bạn nên khắc phục . Mã được viết tốt có thể dựa vào các bài kiểm tra tích hợp chủ yếu là infoq.com/presentations/Simple-Made- Easy
Công việc

2
Quả thực các bài kiểm tra cũng có thể bị lỗi. (TDD nhấn mạnh điều này bằng cách làm cho các bài kiểm tra thất bại trước tiên.) Tuy nhiên, việc thực hiện cùng một loại lỗi hai lần (và nhìn ra nó) có xác suất thấp hơn nhiều. Nói chung, không có số lượng và loại thử nghiệm nào có thể chứng minh rằng phần mềm không có lỗi, chỉ cần giảm xác suất lỗi xuống mức chấp nhận được. Và về tốc độ truy tìm lỗi đến nguồn, IMO không gì có thể vượt qua các bài kiểm tra đơn vị - quy tắc phản hồi nhanh :-)
Péter Török

"Hàm sau không cần kiểm tra đơn vị" Tôi nghĩ rằng bạn đang mỉa mai ở đây, nhưng không rõ ràng. Tôi có tin tưởng bộ não của mình không? KHÔNG! Tôi có tin tưởng bộ não của người tiếp theo chạm vào mã không? NGAY LẬP TỨC KHÔNG! Tôi có tin tưởng rằng tất cả các giả định đằng sau mã sẽ là sự thật một năm kể từ bây giờ không? ... bạn có được sự trôi dạt của tôi. Ngoài ra, các hàm tĩnh sẽ giết OO ... nếu bạn muốn thực hiện FP, sau đó sử dụng ngôn ngữ FP.
Cướp

1

Tôi biết câu hỏi này khá cũ. Nhưng tôi muốn đưa ra một quan điểm khác cho vấn đề.

Đầu tiên, bài kiểm tra đơn vị của bạn nên có hai mục đích:

  1. Tạo tài liệu cho bạn và đồng đội của bạn, vì vậy sau một khoảng thời gian nhất định, bạn có thể đọc bài kiểm tra đơn vị và đảm bảo rằng bạn hiểu what's the class' intentionhow the class is doing its work
  2. Trong khi phát triển, kiểm tra đơn vị đảm bảo mã chúng tôi đang viết đang thực hiện công việc của nó như dự định trong tâm trí của chúng tôi.

Vì vậy, tóm tắt lại vấn đề, chúng tôi muốn kiểm tra a complex if statement, ví dụ đã cho, có 2 ^ 3 khả năng, đó là một lượng thử nghiệm quan trọng chúng tôi có thể viết.

  • Bạn có thể thích nghi với thực tế này và viết ra 8 bài kiểm tra hoặc sử dụng các bài kiểm tra tham số
  • Bạn cũng có thể làm theo các câu trả lời khác và nhớ rằng các bài kiểm tra nên rõ ràng với ý định, theo cách này chúng ta sẽ không gây rối với quá nhiều chi tiết mà trong tương lai gần có thể khó hiểu hơn what is doing the code

Mặt khác, nếu bạn ở vị trí mà các bài kiểm tra của bạn thậm chí còn phức tạp hơn so với việc thực hiện, thì đó là do việc triển khai nên được thiết kế lại (nhiều hay ít tùy theo trường hợp) chứ không phải bản thân bài kiểm tra.

Ví dụ, đối với các câu lệnh if phức tạp, bạn có thể nghĩ về mẫu phản hồi chuỗi , triển khai từng trình xử lý theo cách này:

If some simple business rule apply, derive to the next handler

Làm thế nào đơn giản để kiểm tra một số quy tắc đơn giản, thay vì một quy tắc phức tạp?

Hy vọng nó giúp,


0

Đây là một trong những trường hợp trong đó Một cái gì đó như quickcheck ( http://en.wikipedia.org/wiki/QuickCheck ) sẽ là bạn của bạn. Thay vì viết ra tất cả các trường hợp N bằng tay, máy tính sẽ tạo ra tất cả (hoặc ít nhất một số lượng lớn) các trường hợp kiểm tra có thể và xác nhận rằng tất cả đều trả về một kết quả hợp lý.

Chúng tôi lập trình máy tính để kiếm sống ở đây, tại sao không lập trình máy tính để tạo ra các trường hợp thử nghiệm cho bạn?


0

Bạn có thể cấu trúc lại các điều kiện thành các điều kiện bảo vệ:

if (! PassesBusinessRule1) {
    return false;
}

if (! PassesBusinessRule2) {
    return false;
}

if (! PassesBusinessRule3) {
    return false;
}

Tôi không nghĩ rằng làm giảm số lượng các trường hợp, nhưng kinh nghiệm của tôi là dễ dàng phá vỡ chúng theo cách này.

(Lưu ý rằng tôi là một người hâm mộ "một điểm thoát" lớn, nhưng tôi có một ngoại lệ cho các điều kiện bảo vệ. Nhưng có nhiều cách khác để cấu trúc mã để bạn không có lợi nhuận riêng.)

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.