Là tuân thủ một khẳng định cho mỗi thử nghiệm nhất quán ngu ngốc trong trường hợp này?


10

Tôi có một lớp mà tôi đang kiểm tra. Lớp này có chức năng:apply(List<IRule> rules, List<ITarget> targets);

Trong một thử nghiệm, tôi muốn đảm bảo rằng mỗi mục tiêu đã được chuyển đến một quy tắc, a la:

rule1.AssertWasCalled(fnord => fnord.Test(target1));
rule1.AssertWasCalled(fnord => fnord.Test(target2));
rule1.AssertWasCalled(fnord => fnord.Test(target3));

Dường như với tôi rằng việc giới hạn bản thân trong một tuyên bố khẳng định duy nhất sẽ khá là hobgoblin . Tôi có đúng trong giả định này không, hay có một cách nào khác mà tôi có thể khẳng định rằng trên thực tế, từng mục tiêu đã được thử nghiệm?


Tôi có thể nhìn thấy các fnords!
Ross Patterson

Câu trả lời:


15

Ba khẳng định về bản chất là một bài kiểm tra. Bạn đang kiểm tra hành vi của một phương thức trên một bộ sưu tập, để đảm bảo rằng mỗi mục đã là một tham số cho một cuộc gọi cụ thể (nghĩa là mỗi mục đã được xử lý đúng cách).

Thiết lập dữ liệu lên ba lần và theo ba phương pháp khác nhau là lãng phí và ít đọc hơn so với việc thay thế bằng một vài khẳng định.

"Quy tắc" khẳng định duy nhất là về việc đưa ra các xác nhận thuộc các loại khác nhau trong cùng một phương thức (về cơ bản là thử nghiệm những thứ khác nhau), không thực sự áp dụng trong trường hợp này, trong đó bạn đang thử nghiệm cho một hành vi.


3
Thật vậy: quy tắc là nhiều hơn một khẳng định hợp lý cho mỗi bài kiểm tra đơn vị. Bạn có thể nhóm chúng thành một cấp độ cao hơn khẳng định rằng bạn có thể sử dụng lại trong các thử nghiệm khác nhau.
Laurent Bourgault-Roy

5

Tôi tin rằng điều này khẳng định cho mỗi quy tắc kiểm tra tồn tại để giữ cho các bài kiểm tra của bạn tập trung vào một vấn đề. Nếu bạn kiểm tra 20 điều trong một bài kiểm tra, thật khó để biết phạm vi bảo hiểm của bạn là gì. Bạn biết nó gây ra vấn đề khi bạn không thể đặt tên cho phương thức kiểm tra mà không có từ trong đó. Ví dụ: nếu phương pháp thử nghiệm của bạn sẽ được đặt tên chính xác hơn testFooIsTrueAndDbExistsAndBarIsNullAndAnExceptionDoesntOccur(), thì có lẽ bạn đang thử nghiệm quá nhiều trong một thử nghiệm.

Trong trường hợp của bạn, tôi nghĩ có lẽ sẽ ổn khi khẳng định ba lần. Nếu bạn muốn làm cho mã của mình dễ đọc hơn, bạn có thể trích xuất ba xác nhận đó thành một phương thức có tên assertWasCalledOnTargets(...).


3

Đối với ví dụ cụ thể của bạn, bạn có thể thoát khỏi câu lệnh khẳng định "một" nếu bạn làm một cái gì đó như:

foreach target in targets
{
     rule1.AssertWasCalled(fnord => fnord.Test(target))
}

Đó là những gì tôi làm để tránh cảm thấy tội lỗi khi có nhiều khẳng định trong một bài kiểm tra.


Tôi đã làm điều này trước đây. Một cách không tồi để đi. Thật dễ đọc và bạn có thể hiểu bản chất của việc đang làm.
CokoBWare

1

Tôi đã đấu tranh với cái này, quá.

Người theo chủ nghĩa thuần túy (trong tôi) khăng khăng đòi một lần khẳng định cho mỗi bài kiểm tra để tôi biết * chính xác * nơi mọi thứ nổ tung.

Và sau đó tôi thấy mình cắt / dán rất nhiều mã cài đặt thử nghiệm dự phòng giống nhau. Sau lớp thứ ba hoặc thứ tư này, bạn bắt đầu nói "Oy! Đủ rồi!"

Sự thỏa hiệp của tôi là tìm ra những khía cạnh "không bao giờ" phá vỡ. Và tôi sẽ ghép các mảnh đó lại với nhau và sau đó thêm vào một yếu tố mới có thể phá vỡ. Rõ ràng, việc phân lớp nhiều khu vực dễ bay hơi trong một thử nghiệm sẽ là vi phạm thỏa hiệp này.


1
Bạn nên kiểm tra Assume. Tôi mới học về nó hôm nay.
Wayne Werner

1

Nếu mã thiết lập target1khác với mã thiết lập cho target2, loại cắt góc này cuối cùng có xu hướng dẫn đến mã khởi tạo thử nghiệm quá dài. Đến lượt nó là một mớ hỗn độn hoặc cuối cùng được tái cấu trúc và tái sử dụng. Nếu các bài kiểm tra của bạn đủ phức tạp để biện minh cho việc tái cấu trúc chúng, thì bài kiểm tra của bạn có thể đang kiểm tra nhiều hơn một điều.

Nếu mã thiết lập cho từng mục tiêu về cơ bản là giống nhau, việc chia thử nghiệm của bạn thành nhiều thử nghiệm riêng lẻ có thể là quá mức cần thiết.

Nếu target1target2là các triển khai khác nhau của cùng một giao diện, thay vào đó, bạn nên thêm một thử nghiệm đơn vị vào giao diện (và cho phép khung thử nghiệm của bạn tạo thử nghiệm cho mỗi lần thực hiện giao diệ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.