C# NUnit和不同线程中的测试

C# NUnit和不同线程中的测试,c#,.net,multithreading,nunit,semaphore,C#,.net,Multithreading,Nunit,Semaphore,我正在测试一个应用程序。[TearDown]方法包含另一个向服务器发送请求的方法。这个相当慢。同时,服务器无法同时处理3个以上的请求 所以我决定使用信号灯 [TestFixture] public class TestBase { private const int MaxThreadsCount = 3; private readonly Semaphore _semaphore = new Semaphore(MaxThreadsCoun

我正在测试一个应用程序。
[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);

1) 我做错了什么

测试运行程序可能在线程完成(甚至开始)之前结束测试过程。您可以使用类似的方法来验证测试和服务器之间是否没有通信

您需要在单独的线程中运行它有什么原因吗?除非您专门测试线程代码,否则请避免使用它,因为它只会造成复杂性。像平常一样称呼它。它还意味着任何抛出的异常或错误都将被测试运行程序捕获并在测试结果中报告

如果测试花费太长时间(并且不能像服务器速度一样修复根本原因),请考虑一个IoC容器,如AutoFac或引用计数,以便在需要它的测试之间共享。也要考虑运行测试。

2) 如何初始化信号量:

private readonly Semaphore _semaphore = new Semaphore(MaxThreadsCount, MaxThreadsCount);
的第一个参数是请求的初始数量。在这种情况下,您可能希望将其初始化为0,因为您最初没有运行任何请求

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

1) 我做错了什么

测试运行程序可能在线程完成(甚至开始)之前结束测试过程。您可以使用类似的方法来验证测试和服务器之间是否没有通信

您需要在单独的线程中运行它有什么原因吗?除非您专门测试线程代码,否则请避免使用它,因为它只会造成复杂性。像平常一样称呼它。它还意味着任何抛出的异常或错误都将被测试运行程序捕获并在测试结果中报告

如果测试花费太长时间(并且不能像服务器速度一样修复根本原因),请考虑一个IoC容器,如AutoFac或引用计数,以便在需要它的测试之间共享。也要考虑运行测试。

2) 如何初始化信号量:

private readonly Semaphore _semaphore = new Semaphore(MaxThreadsCount, MaxThreadsCount);
的第一个参数是请求的初始数量。在这种情况下,您可能希望将其初始化为0,因为您最初没有运行任何请求


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

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

您应该能够在没有线程的情况下测试所需的行为。我们可以假设线程可以工作——我们担心您的代码。大概在代码的某个地方有一个计数器,指示活动连接或请求的数量;或者以其他方式确定是否可以接受其他连接

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


因此,编写一个测试来实现这一点。将该计数器设置为最大值,调用打开的连接代码,并验证它是否因预期的错误而失败。

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

您应该能够在没有线程的情况下测试所需的行为。我们可以假设线程可以工作——我们担心您的代码。大概在代码的某个地方有一个计数器,指示活动连接或请求的数量;或者以其他方式确定是否可以接受其他连接

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


因此,编写一个测试来实现这一点。将计数器设置为最大值,调用打开的连接代码,并验证它是否会以预期的错误失败。

因为
MyServerHelper.SendRequest
速度慢,会阻止所有其他测试,直到完成为止。@AlexMaslakov可能会使用诸如AutoFac或引用计数之类的IoC容器来管理它,以便在需要它的测试之间共享它。也可以考虑并行运行测试(参见)。有没有办法让测试运行程序等待最后一个线程完成?@AlexMaslakov这取决于测试运行程序。如果我没有记错的话,默认的NUnit不等待,并且我不知道如何告诉他们等待(除了按照上面的答案将代码移动到主线程中)。因为
MyServerHelper.SendRequest
很慢,会阻止所有其他测试,直到它完成为止。@AlexMaslakov可能会使用诸如AutoFac或引用计数之类的IoC容器来管理它,所以您可以在需要它的测试之间共享它。也可以考虑并行运行测试(参见)。有没有办法让测试运行程序等待最后一个线程完成?@AlexMaslakov这取决于测试运行程序。如果我没有记错的话,默认的NUnit不等待,并且我不知道如何告诉他们等待(除了按照上面的答案将代码移动到主线程中)。