简体   繁体   中英

NUnit and testing in different threads

I'm testing an application. A [TearDown] methods contains another method which sends a request a server. This one is pretty slow. Meanwhile a server is unable to handle more than 3 requests at the same time.

So I decided to use a semaphore.

   [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);
        }
    } 

However it seems like it does not work properly. Now in log file on a server there are no records, which means a server does not receive any requests.

1) What did I do wrong?

2) How do I initialize a semaphore:

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

or

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

1) What did I do wrong?

The test runner is probably ending the test process before the thread has finished (or even started). You can verify it using something like Fiddler to verify there is no communication between the test and the server.

Is there a reason why you need to run it in a separate thread? Unless you are specifically testing threaded code, avoid it because it just creates complexities. Call it as you would normally. It also means any exception or error thrown will be caught by the test runner and reported in the test results.

If a test is taking too long (and you cannot fix the root cause like the server speed) consider an IoC container like AutoFac or reference counting to share this between tests that need it. Also consider running the tests in parallel , too.

2) How do I initialize a semaphore:

The first argument to the Semaphore class constructor is the initial number of requests. In this case, you probably want to initialize it to 0 since you have no requests running initially.

Note that a semaphore may help the test not send more than three requests but it will not help the server if tests are running concurrently but you probably realise that.

My understanding is that unit tests should be testing small units of functionality. You shouldn't need to create multiple threads to get your tests working. If you have slow external dependencies (like a network connection or database); you can define interfaces to abstract that away.

You should be able to test the behaviour you want without the threads. We can just assume that threads work - we're worried about the code you have. Presumably, somewhere in your code you have a counter that indicates the number of active connections or requests; or some other way of determining if you can accept another connection.

You want to test what happens when a request comes in, when you are already at the max.

So write a test that does that. Set that counter to the max, call the open connection code, and verify that it fails with the error you expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM