7

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

4

3 回答 3

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()将强制它在关闭与数据库的连接之前等待。

例如,代替之前的线程操作:

try
{                        
    AccessDB(sychObject);
}
catch(Exception)
{
    wasExceptionThrown = true;
}

启动所有线程后,确保您有 100 个线程在等待,sychObject然后才释放它并加入线程。同样可以通过使CloseConnection()(例如)虚拟逻辑并针对等待的继承类编写测试来实现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();
    }
}
于 2010-04-20T16:05:22.470 回答
4

您根本无法通过单元测试对任何内容进行有用的负载测试。负载测试是一项具有完全不同目标的单独活动。您的单元测试应证明代码功能符合规范。负载测试是关于发现瓶颈,以便您可以解决它们。

于 2010-04-20T15:22:32.990 回答
0

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

于 2010-04-20T15:23:41.550 回答