如何在c#单元测试中模拟/压力测试约100名访问给定共享资源(例如数据库)的用户?
答案 0 :(得分:11)
假设您正在访问真正的数据库,那么您正处于集成测试的范围内。最简单的方法是从多个线程访问资源。例如:
[Test]
public void SimpleStressTest()
{
bool wasExceptionThrown = false;
var threads = new Thread[100];
for(int i = 0; i < 100; i++)
{
threads[i] =
new Thread(new ThreadStart((Action)(() =>
{
try
{
AccessDB();
}
catch(Exception)
{
wasExceptionThrown = true;
}
})));
}
for(int i = 0; i < 100; i++)
{
threads[i].Start();
}
for(int i = 0; i < 100; i++)
{
threads[i].Join();
}
Assert.That(wasExceptionThrown, Is.False);
}
此测试不确定,因为您无法控制线程流。例如,如果要确保可以同时打开100个连接,可以在AccessDB()
的逻辑中放置一个钩子,这将强制它在关闭与DB的连接之前等待。
例如,代替上一个线程操作:
try
{
AccessDB(sychObject);
}
catch(Exception)
{
wasExceptionThrown = true;
}
启动所有线程后,确保在sychObject
上等待100个线程,然后释放它并加入线程。通过制作CloseConnection()
(例如) virtual 的逻辑并针对在CloseConnection()
中等待的继承类编写测试,可以实现相同的目的。例如:
public class DataBase
{
public void AccessDB()
{
// Do logic here before closing connection
CloseConnection();
}
protected virtual void CloseConnection()
{
// Real Logic to close connection
}
}
public class FakeDataBase : DataBase
{
ManualResetEvent sychObject;
public FakeDataBase(ManualResetEvent sychObject)
{
this.sychObject = sychObject;
}
override protected void CloseConnection()
{
sychObject.WaitOne();
base.CloseConnection();
}
}
答案 1 :(得分:4)
您无法通过单元测试对任何事情进行有用的负载测试。负载测试是一项具有完全不同目标的独立活动。您的单元测试应证明代码符合规范。负载测试是关于找到瓶颈,以便您可以解决它们。
答案 2 :(得分:0)
我使用名为WCAT http://www.iis.net/downloads/community/2007/05/wcat-63-(x86)的免费工具完成了性能和负载测试。它现在有点过时,但它很容易上手,有很多关于它的在线文章,它似乎很灵活。