ac#ユニットテストで特定の共有リソース(データベースなど)にアクセスする約100人のユーザーをシミュレート/ストレステストするにはどうすればよいですか?
3 に答える
実際の DB にアクセスしていると仮定すると、統合テストの範囲内になります。最も簡単な方法は、複数のスレッドからリソースにアクセスすることです。例えば:
[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;
}
すべてのスレッドを開始した後、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();
}
}
単体テストを介して何かの有用な負荷テストを行うことはできません。負荷テストは、まったく異なる目標を持つ別個のアクティビティです。単体テストは、コードが仕様どおりに機能することを証明する必要があります。負荷テストとは、ボトルネックを見つけて対処できるようにすることです。
WCAT http://www.iis.net/downloads/community/2007/05/wcat-63-(x86)と呼ばれる無料のユーティリティを使用してパフォーマンスと負荷テストを実行しました。今は少し古いですが、始めるのは簡単で、それに関するオンライン記事がたくさんあり、柔軟性があるように見えました。