C#压力测试 – 模拟对给定共享资源的多次访问

如何在ac#unit test中模拟/压力测试大约100个访问给定共享资源(例如数据库)的用户?

假设您正在访问真正的数据库,那么您正处于集成测试的范围内。 最简单的方法是从多个线程访问资源。 例如:

[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() (例如)的逻辑设置为虚拟并针对在CloseConnection()等待的inheritance类编写测试,可以实现相同的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(); } } 

您无法通过unit testing对任何事情进行有用的负载测试。 负载测试是一项具有完全不同目标的独立活动。 您的unit testing应该certificate代码符合规范。 负载测试是关于找到瓶颈,以便您可以解决它们。

我已经使用名为WCAT的免费工具http://www.iis.net/downloads/community/2007/05/wcat-63-(x86)完成了性能和负载测试。 它现在有点过时,但它很容易上手,有很多关于它的在线文章,它似乎很灵活。