C # Stress Test - имитация множественного доступа к данному общему ресурсу - PullRequest
6 голосов
/ 20 апреля 2010

Как вы можете имитировать / стресс-тестировать около 100 пользователей, обращающихся к определенному общему ресурсу (например, базе данных) в модульном тесте c #?

Ответы [ 3 ]

11 голосов
/ 20 апреля 2010

Предполагая, что вы получаете доступ к реальной БД, вы попадаете в область интеграционных тестов. Самый простой способ - получить доступ к ресурсу из нескольких потоков. Например:

[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() (например) 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();
    }
}
4 голосов
/ 20 апреля 2010

Вы просто не можете сделать полезное нагрузочное тестирование чего-либо через модульное тестирование. Нагрузочное тестирование - это отдельное занятие с совершенно разными целями. Ваши модульные тесты должны доказать, что код работает по спецификации. Нагрузочное тестирование - это поиск узких мест, чтобы вы могли их устранить.

0 голосов
/ 20 апреля 2010

Я провел тестирование производительности и нагрузки с помощью бесплатной утилиты под названием WCAT http://www.iis.net/downloads/community/2007/05/wcat-63-(x86). Сейчас оно немного устарело, но его было легко начать, есть много статей об этом, и оно показалось гибким. .

...