2010-03-12 22 views
38

Có gì không ổn với việc kiểm tra rất nhiều điều trong bài kiểm tra đơn vị này ?:Có nhiều xác nhận xấu trong thử nghiệm đơn vị không? Ngay cả khi xích?

ActualModel = ActualResult.AssertViewRendered()  // check 1 
          .ForView("Index")   // check 2 
          .WithViewData<List<Page>>(); // check 3 

CollectionAssert.AreEqual(Expected, ActualModel);  // check 4 

Các mục tiêu chính của thử nghiệm này là để kiểm tra xem đúng được trả lại (kiểm tra 2) và nó chứa các dữ liệu bên phải (kiểm tra 4).

Tôi có thể đạt được điều gì bằng cách chia nhỏ thành nhiều bài kiểm tra không? Tôi là tất cả về việc làm đúng, nhưng tôi sẽ không chia nhỏ mọi thứ nếu nó không có giá trị thực tế.

Tôi khá mới để thử nghiệm đơn vị, vì vậy hãy nhẹ nhàng.

+0

Một số thảo luận thêm về vấn đề này: http: // stackoverflow. com/questions/831390/multiple-asserts-in-single-test và http://stackoverflow.com/questions/762512/unit-testing-question – Alconja

+0

Tất cả câu trả lời hay (tất cả đều được bình chọn), cảm ơn! –

+0

Xem thêm http://programmers.stackexchange.com/questions/7823/is-it-ok-to-have-multiple-asserts-in-a-single-unit-test# –

Trả lời

29

Như những người khác đã chỉ ra, tốt nhất nên gắn bó với một khẳng định trong mỗi bài kiểm tra để tránh mất thông tin - nếu khẳng định đầu tiên không thành công, bạn không biết liệu những câu sau có thất bại hay không. Bạn phải khắc phục vấn đề với ít thông tin hơn - có thể (có thể sẽ) khó hơn.

Một tham chiếu rất tốt là của Roy Osherove Art of Unit Testing - nếu bạn muốn bắt đầu ngay với Bài kiểm tra đơn vị, bạn có thể làm tồi tệ hơn nhiều so với bắt đầu ở đây.

+2

Tôi thấy cuốn sách đó rất hay. Nó cải thiện chất lượng của các bài kiểm tra đơn vị của tôi rất nhiều. Và trong khi hầu hết các cuốn sách về phát triển phần mềm đều rất dày, cuốn sách này chứa khoảng 270 trang. Điều này làm cho nó tuyệt vời để đưa vào danh sách phải đọc của nhóm của bạn. Và nếu bạn vội vàng, Roy khuyên bạn nên chỉ đọc chương 7. – Steven

2

Tốt nhất là chỉ nên gắn một khẳng định trong mỗi thử nghiệm để tránh Assertion Roulette.

Nếu bạn cần thiết lập cùng một kịch bản để kiểm tra nhiều điều kiện dựa trên cơ sở giống nhau, tốt hơn là trích xuất mã thiết lập thành phương thức trợ giúp được chia sẻ và sau đó viết một số thử nghiệm gọi phương thức trợ giúp này.

Điều này đảm bảo rằng mỗi trường hợp kiểm tra chỉ kiểm tra một điều.

Như mọi khi, có những ngoại lệ cho quy tắc này, nhưng kể từ khi bạn là người mới để kiểm tra đơn vị, tôi sẽ khuyên bạn nên gắn bó với một sự khẳng định trên một đơn vị kiểm tra quy tắc cho đến khi bạn đã học được khi nó okay để đi chệch .

+0

Điều đó có ý nghĩa. cảm ơn! –

8

Miễn là mỗi xác nhận có một thông báo lỗi duy nhất và xác định bạn nên là tốt và sẽ bỏ qua bất kỳ vấn đề Assertion Roulette vì sẽ không khó để biết thử nghiệm nào không thành công. Sử dụng suy nghĩ thông thường.

+5

Vấn đề với việc có nhiều xác nhận không phải là khi nói với cái nào thất bại - trong hầu hết các trường hợp, bạn nhận được số dòng, nếu không có gì khác. Vấn đề là bạn không nhận được để xem nếu các xét nghiệm sau này cũng sẽ thất bại, vì vậy bạn kết thúc với ít thông tin về lỗi. Trong một số trường hợp, điều này không đáng kể - nhưng trong một số trường hợp (phần lớn, theo kinh nghiệm của tôi, trước khi tôi học được bài học này). – Bevan

+1

* là bạn không thể xem thử nghiệm sau này có bị lỗi hay không * nhưng điều đó không liên quan. Bạn sửa một Assert tại một thời điểm.Nó cũng an toàn để giả định rằng nếu Assert đầu tiên thất bại, tiếp theo sẽ thất bại là tốt vì điều kiện trước đó không được đáp ứng. Trong các thử nghiệm của tôi, tôi thay thế hầu hết các câu lệnh if nếu có Assert. Bên cạnh khi một chi nhánh là hợp lệ (mà hầu như không bao giờ là trường hợp). –

+0

Tôi không đồng ý. Nếu bạn có ba bài kiểm tra khác nhau và chạy tất cả, bạn sẽ có thể xem những gì đã được thông qua và những gì không. Bạn càng có nhiều thông tin hơn khi cố gắng khắc phục điều gì đó, bạn càng có nhiều khả năng. Bạn có thể thực hiện các thay đổi chính xác hơn để khắc phục sự cố. –

11

Lưu ý đối với người đọc trong tương lai rằng câu hỏi này và bản sao của nó là Is it bad practice to have more than one assertion in a unit test? đối diện với đa số ý kiến, vì vậy hãy đọc cả hai và tự quyết định. Kinh nghiệm của tôi là xác định lượng tử hữu ích nhất không phải là xác nhận, nhưng kịch bản - nghĩa là phải có một đơn vị kiểm tra cho một tập hợp các điều kiện ban đầu và cuộc gọi phương thức, với nhiều xác nhận như cần thiết để khẳng định điều kiện cuối cùng dự kiến. Có một thử nghiệm đơn vị cho mỗi xác nhận dẫn đến thiết lập trùng lặp hoặc cách giải quyết quanh co để tránh trùng lặp (chẳng hạn như bối cảnh rspec lồng nhau sâu sắc mà tôi thấy ngày càng nhiều trong thời gian gần đây). Nó cũng nhân các bài kiểm tra, làm chậm đáng kể bộ phần mềm của bạn.

6

Tôi đã tìm thấy một cuộc tranh luận khác nhau cho câu hỏi này (ít nhất là cho bản thân mình):

Sử dụng nhiều khẳng định là OK nếu họ đang thử nghiệm điều tương tự.

Ví dụ, đó là OK để làm:

Assert.IsNotNull(value); 
Assert.AreEqual(0, value.Count); 

Tại sao? - bởi vì hai xác nhận này không che giấu ý định của thử nghiệm. Nếu khẳng định đầu tiên không thành công, điều đó có nghĩa là lệnh thứ hai sẽ thất bại. Và thực sự, nếu chúng ta loại bỏ xác nhận đầu tiên, xác nhận thứ hai thất bại (với ngoại lệ tham chiếu null - !!!) thì khi value là null. Nếu đây không phải là trường hợp, thì chúng ta không nên đặt hai xác nhận này lại với nhau.

Vì vậy, đây là sai:

Assert.IsNotNull(value1); 
Assert.IsNotNull(value2); 

Như tôi đã đề cập ở trên, nếu khẳng định đầu tiên thất bại, không có dấu hiệu rõ ràng về sự khẳng định thứ hai - chúng tôi vẫn sẽ muốn biết những gì xảy ra với số thứ hai (ngay cả khi số đầu tiên không thành công). Vì vậy, vì lý do này, hai xác nhận này thuộc về hai bài kiểm tra đơn vị khác nhau.

Kết luận: đặt một hoặc nhiều xác nhận, khi thực hiện đúng cách, trở thành vấn đề ưu tiên - cho dù chúng tôi muốn xem ngoại lệ xác nhận trong kết quả kiểm tra hay chúng tôi muốn xem một số ngoại lệ khác. các trường hợp.

0

Tôi biết rằng đây là một câu hỏi cũ nhưng tôi nghĩ tôi sẽ thêm chút của mình.

Nói chung tôi có thể có ít xác nhận nhất có thể trong mỗi trường hợp thử nghiệm. Các xét nghiệm thường có thể được viết để tiết kiệm có nhiều xác nhận khác nhau.

Giả sử tôi có các xét nghiệm đơn vị cho một phương pháp tạo ra lời chào (ví dụ: Mr Smith) từ các thành phần của tên. Tôi muốn kiểm tra điều này với một số lượng lớn các kịch bản khác nhau, không nhất thiết phải có một bài kiểm tra riêng cho từng trường hợp.

Với mã sau, có nhiều xác nhận khác nhau. Khi chúng thất bại, bạn có thể sửa chúng từng cái một cho đến khi các xác nhận dừng lại.

Assert.AreEqual("Mr Smith", GetSalutation("Mr", "J", "Smith")); 
Assert.AreEqual("Mr Smith", GetSalutation("Mr", "John", "Smith")); 
Assert.AreEqual("Sir/Madam", GetSalutation("", "John", "Smith")); 
Assert.AreEqual("Sir/Madam", GetSalutation("", "J", "Smith")); 

Một giải pháp thay thế là giữ một số vấn đề và khẳng định điều này ở cuối.

int errorCount = 0; 
string result; 

result = GetSalutation("Mr", "J", "Smith"); 
if (result == "Mr Smith") 
    errorCount++; 

result = GetSalutation("Mr", "John", "Smith"); 
if (result == "Mr Smith") 
    errorCount++; 

Assert.AreEqual(0, errorCount); 

Trong một tình huống thế giới thực tôi có lẽ muốn thêm một số vết lệnh để viết các chi tiết của các bài kiểm tra cá nhân mà không cửa sổ đầu ra

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