[英]How to unit test a thread safe queue
我需要一個具有以下要求的簡單數據結構:
我對多線程的經驗非常有限,但這就是我的目標:
public class Tickets
{
private ConcurrentQueue<uint> _tickets;
public Tickets(uint from, uint to)
{
Initialize(from, to);
}
private readonly object _lock = new object();
public void Initialize(uint from, uint to)
{
lock(_lock)
{
_tickets = new ConcurrentQueue<uint>();
for (uint i = from; i <= to; i++)
{
_tickets.Enqueue(i);
}
}
}
public uint Dequeue()
{
uint number;
if (_tickets.TryDequeue(out number))
{
return number;
}
throw new ArgumentException("Ticket queue empty!");
}
}
第一個問題:這段代碼好嗎?
Secod問題:我怎樣才能對這個類進行單元測試(例如,兩個線程在隊列中定期執行出隊操作,元素為(1,2,3,4,5,6),第一個線程只能得到奇數和第二個線程只有偶數)? 我試過這個,但斷言沒有執行:
[Test]
public void Test()
{
var tickets = new Tickets(1, 4);
var t1 = new Thread(() =>
{
Assert.AreEqual(1, tickets.Dequeue());
Thread.Sleep(100);
Assert.AreEqual(3, tickets.Dequeue());
});
var t2 = new Thread(() =>
{
Assert.AreEqual(2, tickets.Dequeue());
Thread.Sleep(100);
Assert.AreEqual(4, tickets.Dequeue());
});
t1.Start();
t2.Start();
}
我會用國際象棋: http : //research.microsoft.com/en-us/projects/chess
CHESS是一種在並行程序中查找和復制Heisenbugs的工具。 CHESS重復運行並發測試,確保每次運行都采用不同的交錯。 如果交錯導致錯誤,CHESS可以重現交錯以改進調試。 CHESS適用於托管和本機程序。
多線程和單元測試的問題是時間問題。 當您嘗試將多個線程引入單元測試時,您將面臨不可重現的測試結果的風險,測試有時會通過,但有時則不會通過。
但只是為了解釋為什么你的斷言可能沒有執行,單元測試在線程之前完成。 它需要等待線程完成而不是僅僅將它們踢掉並繼續前進。 單元測試框架本身不是線程安全的或者能夠從其他線程調用Asserts也是可行的。
對不起,這不是一個解決方案,但我不知道任何多線程代碼的自動化測試解決方案。
另請參閱: 我應該如何對線程代碼進行單元測試?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.