2010-01-08 44 views
14

Tôi khá mới để thử nghiệm đơn vị và hiện đang thử nghiệm một chút với các công cụ kiểm tra của Visual Studio.Làm thế nào để mô hình đồng thời trong các bài kiểm tra đơn vị?

Câu hỏi của tôi là cách xác định các xác nhận về hành vi đồng thời trong các thử nghiệm này. Ví dụ. cung cấp một lớp BoundedChan<T> thực hiện một kênh bị chặn, làm thế nào tôi có thể chỉ định các xét nghiệm như

  1. "channel.Send sẽ không chặn" hoặc
  2. "Nếu công suất của kênh bị vượt quá, channel.Send sẽ chặn cho đến khi một giá trị được đọc"

Có giải pháp thanh lịch để viết các xác nhận này không?

+1

Tôi không chắc chắn có bất kỳ bản sao chính xác nào (mặc dù URL này gần đúng: http: // stackoverflow.com/questions/314580/how-do-i-perform-a-unit-kiểm tra-sử dụng-chủ đề), nhưng có khá nhiều tài liệu SO tốt về điều này. Tôi đã liệt kê một số cuộc thảo luận tốt hơn trong phản hồi của tôi ở đây: http://stackoverflow.com/questions/1520539/how-to-prove-that-multithreading-is-working/1520619#1520619. –

+0

@Jeff: Tại sao bạn không đăng câu trả lời này - Có vẻ khá hữu ích đối với tôi. – Dario

Trả lời

6

Đây là một số blog article thảo luận về chủ đề; nó tập trung vào NUnit.

Thật không may, đồng thời vẫn là một khu vực thử nghiệm đơn vị đó là thách thức để cấu trúc dễ dàng. Nó không phải là một vấn đề đơn giản, và vẫn yêu cầu bạn thực hiện một số đồng bộ hóa của riêng bạn và logic đồng thời trong thử nghiệm.

Ví dụ bạn cung cấp, không thể viết kiểm tra độc quyền chứng minh rằng một phương pháp sẽ hoặc sẽ không chặn trong các điều kiện nhất định. Bạn có thể đạt được mức độ tin cậy nào đó bằng cách đầu tiên tạo ra các trường hợp xấu nhất, nơi bạn mong đợi hành vi chặn - và sau đó viết các bài kiểm tra để xác định xem điều đó có xảy ra hay không.

+0

Liên kết đã chết, nhưng Wayback Machine có lưng của bạn. Bài viết gốc Dan Barvitsky: https://web.archive.org/web/20140822013404/http://www.atalasoft.com/cs/blogs/danbarvitsky/archive/2009/06/12/techniques-for-testing-concurrent -code-in-nunit.aspx. Bài đăng tiếp theo của anh ấy: https://web.archive.org/web/20100526080326/http://www.atalasoft.com/cs/blogs/danbarvitsky/archive/2009/06/15/my-solution-for-unit -testing-concurrent-code-in-nunit.aspx. –

+0

@ SørenBoisen các liên kết của bạn cũng đã chết: (nó nói Trang không thể được hiển thị do robots.txt. –

+0

@BogdanMart Ouch, do đó, robots.txt mới được tạo sẽ khiến Máy Wayback chặn truy cập (hoặc xóa) các trang web cũ. Tin xấu cho lưu trữ Internet Tôi đoán các bài đăng trên blog thực sự bị mất ngay bây giờ. –

4

Câu hỏi này có thể dẫn đến đủ nội dung để lấp đầy sách.

Nói chung, tôi sẽ không khuyên bạn nên thêm các bài kiểm tra đơn vị vào các lớp của bạn cho các tình huống đồng thời. Với thực tế, tôi nghĩ bạn sẽ biết rằng các bài kiểm tra đơn vị tự động có một hoặc nhiều "điểm ngọt" - và tập trung nỗ lực của bạn vào các khu vực này (và sử dụng các thực hành khác ở các khu vực khác) mang lại ROI tốt hơn.

Nhưng lớp học của bạn có vẻ là về đồng thời (không thể biết chắc chắn dựa trên thông tin được cung cấp), và do đó đây có thể là trường hợp bạn thực sự muốn thử nghiệm mô phỏng đồng thời.

Bạn có thể (theo như tôi biết) khởi động nhiều chủ đề trong một bài kiểm tra đơn vị nếu bạn muốn. Nhưng có thể có một cách đơn giản hơn. Xem xét tận dụng mẫu Compose Method. Trong khi chúng tôi đang ở trên chủ đề - mô hình này là khá quan trọng để kiểm tra đơn vị hiệu quả trên tất cả, không chỉ với đồng thời.

1

tôi đã tạo ra một helper có thể bắt đầu một loạt các chủ đề để thực hiện các hành động đồng thời. Trình trợ giúp cung cấp các nguyên tắc đồng bộ hóa và cơ chế ghi nhật ký. Nó có thể được sử dụng kết hợp với bất kỳ khung kiểm tra đơn vị nào. Đây là một đoạn mã từ thử nghiệm đơn vị:

[Test] 
public void TwoCodeBlocksInParallelTest() 
{ 
    // This static method runs the provided Action delegates in parallel using threads 
    CTestHelper.Run(
     c => 
      { 
       Thread.Sleep(1000); // Here should be the code to provide something 
       CTestHelper.AddSequenceStep("Provide"); // We record a sequence step for the expectations after the test 
       CTestHelper.SetEvent(); 
      }, 
     c => 
      { 
       CTestHelper.WaitEvent(); // We wait until we can consume what is provided 
       CTestHelper.AddSequenceStep("Consume"); // We record a sequence step for the expectations after the test 
      }, 
     TimeSpan.FromSeconds(10)); // This is a timeout parameter, if the threads are deadlocked or take too long, the threads are terminated and a timeout exception is thrown 

    // After Run() completes we can analyze if the recorded sequence steps are in the correct order 
    Expect(CTestHelper.GetSequence(), Is.EqualTo(new[] { "Provide", "Consume" })); 
} 

Nó có thể được sử dụng để kiểm tra máy khách/máy chủ hoặc đồng bộ hóa trong các thành phần hoặc chỉ chạy một luồng có thời gian chờ. Tôi sẽ tiếp tục cải thiện điều này trong những tuần tới. Đây là trang dự án: Concurrency Testing Helper

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