我已經寫了,我們在我工作的地方制定了系統的特定需求,事件驅動的TCP服務器。我也爲此寫了單元測試。
我已經在每個測試中使用標準C#TcpListener和TcpClient連接到我的庫。我正在寫入特定位數的數據,然後檢查測試代碼是否觸發了適當的事件。
問題是 - 這是一場比賽!我的意思是,有時當我將數據寫入TcpClient時,事件可能立即觸發,有時可能需要100ms,有時如果計算機速度慢(或連接速度慢),則需要更多時間。
此說,讓我們畫一個簡單的測試(我使用NUnit的BTW):測試事件驅動的TCP應用
[Test]
public void TestEventA()
{
bool eventFired = false;
//my server would listen on 127.0.0.1:9090
MyTcpServer serv = new MyTcpServer("127.0.0.1", 9090);
serv.OnA += new AEventHandler((object sender, AEventArgs args) =>
{
eventFired = true;
});
//imitating a remote client connecting
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 9090);
//remote client is sending data
client.Getstream().Write(/*you know the drill here*/);
//give the connection and server time to react
System.Threading.Sleep(100);
Assert.IsTrue(eventFired);
}
所以這是一個測試的只是一個簡單的例子。事情是 - 它每次都在我的本地PC上傳遞,但在我們的構建服務器上它完全是隨機的。現在我100%確定這是因爲當我們斷言時事件並未被解僱。問題是,我不知道如何正確設計測試以避免競爭狀況。
我相信很多人都做過類似的事情(也許不是TCP,但測試事件驅動型的東西,當我們不知道這需要多久的事件,火災等),所以我很樂意從你的經驗中學習。
謝謝。
即使這樣,如果有很多處理事件前發生的觸發,你仍然無法預測,你應該睡多長時間,以確保活動將由你到一個斷言的時間被解僱。所以我希望對測試設計採取不同的方法來避免遇到這種情況。 –
如果你單元測試服務器 - 所有連接到網絡/ db等被嘲笑,你不會有這個問題。在end2end測試中,我認爲你不能擺脫它 – Ben
是的,我明白,網絡連接可能會導致延遲。但想象一下這樣的情況:你嘲笑連接,發送數據,服務器在準備發射事件之前正在處理它500毫秒(一些CPU繁重的操作),但你只等300毫秒。所以你把等待時間增加到600ms,但是在CPU速度較慢的較慢的機器上,處理過程需要1000ms ......你在這裏看到問題了嗎?不僅TCP延遲是一個問題,而且在事件驅動的應用程序中,「我獲得了數據」和「我準備好發起事件」之間的差距也是一個問題。 –