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,因为您最初没有运行任何请求。

请注意,信号量可能有助于测试发送的请求不超过三个,但如果测试同时运行,它不会帮助服务器,但您可能已经意识到这一点。

于 2012-09-21T08:06:58.977 回答
1

我的理解是单元测试应该测试小单元的功能。您不需要创建多个线程来让您的测试正常工作。如果你的外部依赖很慢(比如网络连接或数据库);您可以定义接口以将其抽象出来。

您应该能够在没有线程的情况下测试您想要的行为。我们可以假设线程工作 - 我们担心您拥有的代码。据推测,在您的代码中的某处,您有一个计数器,指示活动连接或请求的数量;或其他确定您是否可以接受另一个连接的方法。

您想测试当请求进入时会发生什么,当您已经达到最大值时。

所以写一个测试来做到这一点。将该计数器设置为最大值,调用打开的连接代码,并验证它是否失败并出现您预期的错误。

于 2012-09-21T08:15:43.013 回答