2010-02-23 43 views
12

Dường như trong nhiều thử nghiệm đơn vị, các giá trị tham số hóa phép thử được tự nướng vào bản thân kiểm tra, hoặc được khai báo theo cách xác định trước.Nondeterminism trong thử nghiệm đơn vị

Ví dụ, đây là một thử nghiệm lấy từ các bài kiểm tra đơn vị nUnit của (EqualsFixture.cs):

[Test] 
public void Int() 
{ 
    int val = 1; 
    int expected = val; 
    int actual = val; 

    Assert.IsTrue(expected == actual); 
    Assert.AreEqual(expected, actual); 
} 

này có lợi thế là xác định; nếu bạn chạy thử nghiệm một lần, và nó không thành công, nó sẽ tiếp tục thất bại cho đến khi mã được cố định. Tuy nhiên, bạn chỉ kết thúc thử nghiệm một tập hợp các giá trị giới hạn.

Tôi không thể không cảm thấy như thế này là một sự lãng phí, mặc dù; các thử nghiệm tương tự chính xác có thể chạy với các thông số chính xác cùng hàng trăm nếu không phải hàng ngàn lần trong suốt vòng đời của một dự án.

Điều gì về việc ngẫu nhiên càng nhiều đầu vào cho tất cả các bài kiểm tra đơn vị càng tốt, để mỗi lần chạy có ảnh chụp tiết lộ nội dung mới?

Trong ví dụ trước, có lẽ:

[Test] 
public void Int() 
{ 
    Random rnd = new Random(); 
    int val = rnd.Next(); 
    int expected = val; 
    int actual = val; 
    Console.WriteLine("val is {0}", val); 
    Assert.IsTrue(expected == actual); 
    Assert.AreEqual(expected, actual); 
} 

(Nếu mã dự kiến ​​một chuỗi, có lẽ là một chuỗi ngẫu nhiên được biết đến là hợp lệ cho chức năng cụ thể được sử dụng mỗi lần)

Lợi ích sẽ là khi bạn chạy thử nghiệm nhiều lần, tập hợp các giá trị có thể lớn hơn bạn biết có thể xử lý chính xác.

Điều này có hữu ích không? Tà ác? Có nhược điểm đối với điều này không? Tôi hoàn toàn thiếu điểm kiểm tra đơn vị?

Cảm ơn bạn đã suy nghĩ.

+8

Một nhược điểm lớn là nếu bạn gặp lỗi kiểm tra, nó không tái sản xuất. Rõ ràng, bạn có thể đăng nhập mà các giá trị được sử dụng khi thất bại xảy ra, nhưng điều này tạo ra trên không và phạm vi bỏ lỡ một cái gì đó. Tuy nhiên, những gì bạn mô tả vẫn hữu ích: xem http://en.wikipedia.org/wiki/Fuzz_testing để biết thông tin về một số cách mà ý tưởng này được sử dụng và đã được mở rộng. – itowlson

+0

Cảm ơn bạn! Fuzz thử nghiệm âm thanh như chính xác những gì tôi đang nói về. Tôi sẽ xem xét điều này nhiều hơn. –

+0

"thử nghiệm chính xác có thể chạy với chính xác cùng một tham số hàng trăm nếu không phải hàng nghìn lần trong suốt dự án" - may mắn là chúng tôi đã phát minh ra máy tính chính xác để họ có thể chạy các công việc lặp đi lặp lại cả ngày và không chán! – Ken

Trả lời

7

Bạn muốn thử nghiệm đơn vị của mình có thể lặp lại để chúng luôn hoạt động theo cùng một cách trừ khi mã thay đổi. Sau đó, nếu mã thay đổi và làm cho đơn vị kiểm tra thất bại, bạn có thể sửa mã và kiểm tra đơn vị đã phục vụ mục đích của nó. Hơn nữa, bạn biết rằng mã này [có thể] được cố định khi kiểm tra đơn vị được truyền lại.

Việc kiểm tra đơn vị ngẫu nhiên có thể tìm thấy các lỗi bất thường, nhưng không cần thiết. Nếu bạn biết làm thế nào mã hoạt động (so sánh hộp màu trắng và hộp đen phương pháp tiếp cận để thử nghiệm), bằng cách sử dụng các giá trị ngẫu nhiên không bao giờ nên hiển thị bất cứ điều gì cũng nghĩ về các xét nghiệm đơn vị không ngẫu nhiên sẽ. Và tôi không muốn được nói "chạy thử nghiệm một vài lần và lỗi này sẽ xuất hiện".

+0

Điều này có ý nghĩa và tôi chắc chắn có thể hiểu được khả năng dự đoán là tài sản như thế nào. Tuy nhiên, một số công cụ này đi vào các công cụ được đề cập; nếu công cụ được thiết kế để theo dõi chính xác cách thử nghiệm được tham số hóa mỗi lần, kết quả của nó có thể được sao chép. Nếu một chương trình thử nghiệm hỗ trợ điều này, bạn nghĩ gì? –

+1

Đó là một ý tưởng thú vị, và như itowlson đã chỉ ra, nó đã tồn tại. Tôi nghĩ rằng tôi thích ý tưởng giữ thử nghiệm đơn vị không ngẫu nhiên, nhưng có một bộ kiểm tra ngẫu nhiên riêng biệt có thể hữu ích cho một số thứ. Bạn có thể sử dụng các bài kiểm tra ngẫu nhiên khác nhau là tốt, cho nó có ý nghĩa để chạy chúng nhiều lần cùng một lúc. Xây dựng các công cụ cho tất cả các ngôn ngữ khác nhau mà tồn tại các công cụ xUnit cũng sẽ là một thách thức. –

3

Các thử nghiệm phải bao gồm các trường hợp sử dụng của bạn, không còn nữa.

Hãy xem PEX.

+0

Cảm ơn bạn đã liên kết. Pex trông giống như một công cụ khá đáng kinh ngạc. Câu trả lời của nó dường như là: "Làm cho các thử nghiệm của bạn xác định, nhưng hãy để chúng tôi giúp bạn tìm các giá trị thú vị kích hoạt các đường dẫn thực thi khác nhau, thay vì chọn giá trị của bạn cho các hàm." Tôi nghĩ rằng điều này đi một chặng đường dài hướng tới một câu trả lời, nhưng thậm chí Pex không thể nhìn vào bên trong một hộp đen ... Khi bạn nói trường hợp sử dụng, làm thế nào để bạn xác định một trường hợp sử dụng? Nếu một hàm nên làm việc cho một tập hợp vô hạn các giá trị cho X, làm thế nào để bạn chọn cái nào? Cảm ơn bạn đã suy nghĩ. –

+0

Nếu bạn hoạt động nên làm việc với một vô hạn (những gì về giới hạn kích thước dữ liệu), bạn cần phải xác định độ mịn của vấn đề. Tôi sẽ nguy hiểm một đoán rằng có nhiều quyết định hơn bạn lần đầu tiên nhìn thấy. –

2

Vấn đề lớn mà tôi có với điều này là vì điều này là ngẫu nhiên, nó có thể không gây ra lỗi cho đến khi thử nghiệm được chạy 200, 2000, 3000 hoặc nhiều lần. Nếu nó thất bại trong thử 6007 tháng hoặc nhiều năm sau khi vụ việc đã được viết, về cơ bản nó có nghĩa là bạn đã có một lỗi trong nhiều tháng hoặc nhiều năm và không bao giờ biết.

Thay vào đó, tôi nghĩ hữu ích hơn khi biết các trường hợp góc của bạn và kiểm tra tất cả chúng một cách cụ thể. Nói cách khác, suy nghĩ về dữ liệu nào có thể phá vỡ mã của bạn và kiểm tra nó.

0

Bạn có đang thử nghiệm Nhà điều hành ngẫu nhiên hoặc bình đẳng không?

Dường như với tôi rằng bạn sẽ chọn các giá trị tiêu biểu cộng với điều kiện biên, hoặc lực lượng vũ phu toàn bộ tập hợp số nguyên. Đơn giản chỉ cần chọn số nguyên ngẫu nhiên không giúp với một trong hai cách tiếp cận.

Để trả lời câu hỏi cuối cùng của bạn, điểm thử nghiệm đơn vị là gì, cảm giác của tôi là thế này: giá trị chứng minh kết quả lặp lại vượt quá chi phí ghi các bài kiểm tra.

4

Những gì bạn đang đề xuất có ý nghĩa rất nhiều, miễn là bạn làm điều đó một cách chính xác. Bạn không nhất thiết phải luôn luôn lắng nghe chỉ với sự khôn ngoan thông thường mà nói rằng bạn không bao giờ phải không có quyết định trong các bài kiểm tra của bạn.

Điều gì thực sự quan trọng là mỗi thử nghiệm phải luôn luôn thực hiện cùng một đường dẫn mã. Đó không phải là điều tương tự.

Bạn có thể áp dụng những gì tôi gọi là Constrained Non-Determinism trong thử nghiệm đơn vị. Điều này có thể giúp bạn hướng tới một cách kiểm tra viết hơn Specification-Oriented.

+0

Có mỗi bài tập thử nghiệm cùng một đường dẫn mã làm cho rất nhiều ý nghĩa. Tôi thích bài viết của bạn về sự hạn chế không xác định ... thực phẩm tốt cho suy nghĩ, cảm ơn! –

0

Nếu ứng dụng của bạn không xác định, bạn đang lãng phí thời gian của bạn với thử nghiệm, trừ khi nó là một ứng dụng rất nhỏ.