0

アプリケーションをテストしています。メソッドには、リクエストをサーバーに送信する別の[TearDown]メソッドが含まれています。これはかなり遅いです。一方、サーバーは同時に 3 つを超えるリクエストを処理できません。

そこで、セマフォを使用することにしました。

   [TestFixture]
    public class TestBase
    {
        private const int MaxThreadsCount = 3;
        private readonly Semaphore _semaphore = new Semaphore(MaxThreadsCount, MaxThreadsCount);

        [SetUp]
        public virtual void Setup()
        {
        }

        [TearDown]
        public void CleanUp()
        {
            //...some code
            new Thread(_ => SendRequestAsync("url/of/a/server", parameters)).Start();
        }

        private void SendRequestAsync(string url, NameValueCollection parameters)
        {
            _semaphore.WaitOne();
            string result = MyServerHelper.SendRequest(url, parameters); 
            Assert.That(string.IsNullOrEmpty(result), Is.False, "SendRequest returned false");
        }

        [Test]
        public void Test01()
        {
            Assert.AreEqual(1, 1);
        }

        [Test]
        public void Test02()
        {
            Assert.AreEqual(1, 1);
        }

        [Test]
        public void Test03()
        {
            Assert.AreEqual(1, 1);
        }
        //...........................
        [Test]
        public void TestN()
        {
            Assert.AreEqual(1, 1);
        }
    } 

ただし、正しく動作しないようです。現在、サーバーのログ ファイルにはレコードがありません。これは、サーバーが要求を受信して​​いないことを意味します。

1) 私は何を間違えましたか?

2) セマフォを初期化する方法:

private readonly Semaphore _semaphore = new Semaphore(MaxThreadsCount, MaxThreadsCount);

また

private readonly Semaphore _semaphore = new Semaphore(0, MaxThreadsCount);
4

2 に答える 2

3

1) 私は何を間違えましたか?

テスト ランナーは、スレッドが終了する前 (または開始する前) にテスト プロセスを終了している可能性があります。Fiddlerなどを使用して、テストとサーバーの間に通信がないことを確認できます。

別のスレッドで実行する必要がある理由はありますか? スレッド化されたコードを特にテストする場合を除き、複雑さを生み出すだけなので避けてください。通常どおり呼び出します。また、スローされた例外またはエラーがテスト ランナーによってキャッチされ、テスト結果で報告されることも意味します。

テストに時間がかかりすぎる (サーバー速度などの根本原因を修正できない) 場合は、AutoFac などの IoC コンテナーや参照カウントを使用して、必要なテスト間でこれを共有することを検討してください。また、テストを並行して実行することも検討してください。

2) セマフォを初期化する方法:

Semaphore クラス コンストラクターの最初の引数は、要求の初期数です。この場合、最初はリクエストを実行していないため、おそらく 0 に初期化する必要があります。

セマフォは、テストが 3 つを超えるリクエストを送信しないようにするのに役立つ場合がありますが、テストが同時に実行されている場合はサーバーには役に立たないことに注意してください。

于 2012-09-21T08:06:58.977 に答える
1

私の理解では、単体テストは機能の小さな単位をテストする必要があります。テストを機能させるために複数のスレッドを作成する必要はありません。外部依存関係が遅い場合 (ネットワーク接続やデータベースなど); それを抽象化するインターフェースを定義できます。

スレッドなしで必要な動作をテストできるはずです。スレッドが機能すると仮定できます - 私たちはあなたが持っているコードについて心配しています. おそらく、コードのどこかに、アクティブな接続または要求の数を示すカウンターがあります。または、別の接続を受け入れることができるかどうかを判断する他の方法。

すでに最大になっているときに、リクエストが入ったときに何が起こるかをテストしたいと考えています。

だから、それを行うテストを書いてください。そのカウンターを最大に設定し、開いている接続コードを呼び出して、予期したエラーで失敗することを確認します。

于 2012-09-21T08:15:43.013 に答える