2012-09-21 87 views
0

我正在測試一個應用程序。 A [TearDown]方法包含另一種發送請求服務器的方法。這個很慢。同時一臺服務器不能同時處理3個以上的請求。NUnit和測試在不同的線程

所以我決定使用信號量。

[TestFixture] 
    public class TestBase 
    { 
     private const int MaxThreadsCount = 3; 
     private readonly Semaphore _semaphore = new Semaphore(MaxThreadsCount, MaxThreadsCount); 

     [SetUp] 
     public virtual void Setup() 
     { 
     } 

     [TearDown] 
     public void CleanUp() 
     { 
      //...some code 
      new Thread(_ => SendRequestAsync("url/of/a/server", parameters)).Start(); 
     } 

     private void SendRequestAsync(string url, NameValueCollection parameters) 
     { 
      _semaphore.WaitOne(); 
      string result = MyServerHelper.SendRequest(url, parameters); 
      Assert.That(string.IsNullOrEmpty(result), Is.False, "SendRequest returned false"); 
     } 

     [Test] 
     public void Test01() 
     { 
      Assert.AreEqual(1, 1); 
     } 

     [Test] 
     public void Test02() 
     { 
      Assert.AreEqual(1, 1); 
     } 

     [Test] 
     public void Test03() 
     { 
      Assert.AreEqual(1, 1); 
     } 
     //........................... 
     [Test] 
     public void TestN() 
     { 
      Assert.AreEqual(1, 1); 
     } 
    } 

但是,它似乎不能正常工作。現在在服務器上的日誌文件中沒有記錄,這意味着服務器不會收到任何請求。

1)我做錯了什麼?

2)如何初始化一個信號:

private readonly Semaphore _semaphore = new Semaphore(MaxThreadsCount, MaxThreadsCount); 

private readonly Semaphore _semaphore = new Semaphore(0, MaxThreadsCount); 

回答

2

1)我做了什麼錯?

測試運行程序可能會在線程結束(甚至啓動)之前結束測試過程。您可以使用類似Fiddler的驗證它來驗證測試和服務器之間沒有通信。

是否有一個原因,你需要在一個單獨的線程運行它?除非您專門測試線程代碼,否則應避免它,因爲它只會造成複雜性。像通常那樣調用它。這也意味着所有拋出的異常或錯誤都會被測試運行者捕獲並在測試結果中報告。

如果測試花費的時間太長(你不能修復的根本原因,如服務器的速度)考慮像AutoFac或引用計數IoC容器到需要它的測試之間分享。同樣考慮運行測試in parallel

2)如何初始化一個信號:

的第一個參數是Semaphore class constructor請求的初始數量。在這種情況下,您可能想將其初始化爲0,因爲您最初沒有運行任何請求。

注意,信號量可以幫助測試不發送超過三個請求,但它不會幫助服務器,如果測試同時運行,但你可能會意識到。

+0

<<是否有一個原因,你需要在一個單獨的線程運行它? >>因爲'MyServerHelper.SendRequest'很慢,並阻止所有其他測試,直到它完成。 – Alexandre

+0

@AlexMaslakov可能使用像AutoFac或引用計數這樣的IoC容器來管理此內容,以便在需要它的測試之間共享此內容。也許可以考慮同時運行測試(見http://www.nunit.org/index.php?p=pnunit&r=2.5)。 – akton

+0

<<測試運行程序可能在線程結束(甚至啓動)之前結束測試過程>>是否有任何方法讓測試運行程序等待直到最後一個線程結束? – Alexandre

2

我的理解是單元測試應該測試小功能單元。你不需要創建多個線程來讓你的測試工作。如果您的外部依賴性較慢(如網絡連接或數據庫);你可以定義接口來抽象。

你應該能夠測試你想要的行爲,而不需要線程。我們可以假設線程正常工作 - 我們擔心您的代碼。據推測,在你的代碼的某個地方,你有一個指示活動連接或請求數目的計數器;或者確定您是否可以接受其他連接的其他方式。

要測試,當請求中會發生什麼,當你已經在最大。

所以寫一個測試,做到這一點。將該計數器設置爲最大值,調用打開的連接代碼,並驗證它是否因您期望的錯誤而失敗。