16

I'm pretty new to unit testing and currently experimenting a bit with Visual Studio's testing tools.

My question is how to define assertions about concurrent behaviour in these tests. E.g. given a class BoundedChan<T> implementing a bounded channel, how can I specify tests like

  1. "channel.Send will not block" or
  2. "If the channel's capacity is exceeded, channel.Send will block until a value is read"

Is there an elegant solution to write these assertions?

2
  • 1
    I'm not sure there are any precise duplicates (though this one is close: stackoverflow.com/questions/314580/…), but there's quite a bit of good SO material on this. I've listed some of the better discussions in my response here: stackoverflow.com/questions/1520539/…. Commented Jan 8, 2010 at 18:06
  • @Jeff: Why don't you post this as an answer - Looks quite useful to me. Commented Jan 8, 2010 at 18:28

3 Answers 3

7

Unfortunately, concurrency is still an area of unit testing that is challenging to structure easily. It's not a simple problem, and still requires that you implement some of your own synchronization and concurrency logic in the test.

For the example you provide, it may be impossible to write a test that conclusively demonstrates that a method will or won't block under certain conditions. You may be able to achieve some level of confidence by first creating worst-case circumstances where you would expect the blocking behavior - and then write tests to determine if that occurs or not.

Here's a blog article that discusses the topic; it focuses on NUnit.

Sign up to request clarification or add additional context in comments.

1 Comment

Link is dead, but Wayback Machine has your back. Original Dan Barvitsky article: web.archive.org/web/20140822013404/http://www.atalasoft.com/cs/… . His follow up post: web.archive.org/web/20100526080326/http://www.atalasoft.com/cs/… .
6

This question could lead to enough content to fill a book.

In general, I would not recommend adding unit tests to your classes for concurrent scenarios. With practice I think you'll learn that automated unit tests have one or several "sweet spots" -- and that focusing your efforts in these areas (and using other practices in other areas) yields better ROI.

But your class seems to be about concurrency (can't tell for certain based on info provided), and therefore this could be a case where you really want a concurrency-simulating test.

You can (as far as I know) start up multiple threads in a unit test if you wish. But there may be a simpler way. Consider leveraging the Compose Method pattern. While we're on the subject -- this pattern is pretty critical to effective unit tests over all, not just with concurrency.

Comments

1

I have created a helper that can start a bunch of threads to execute concurrent actions. The helper provides synchronization primitives and logging mechanisms. It can be used in conjunction with any unit test framework. Here is a code fragment from a unit test:

[Test] public void TwoCodeBlocksInParallelTest() { // This static method runs the provided Action delegates in parallel using threads CTestHelper.Run( c => { Thread.Sleep(1000); // Here should be the code to provide something CTestHelper.AddSequenceStep("Provide"); // We record a sequence step for the expectations after the test CTestHelper.SetEvent(); }, c => { CTestHelper.WaitEvent(); // We wait until we can consume what is provided CTestHelper.AddSequenceStep("Consume"); // We record a sequence step for the expectations after the test }, TimeSpan.FromSeconds(10)); // This is a timeout parameter, if the threads are deadlocked or take too long, the threads are terminated and a timeout exception is thrown // After Run() completes we can analyze if the recorded sequence steps are in the correct order Expect(CTestHelper.GetSequence(), Is.EqualTo(new[] { "Provide", "Consume" })); } 

It can be used to test client/server or synchronization in components or simply run a thread with a timeout. I'll continue to improve this in the next weeks. Here is the project page: Concurrency Testing Helper

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.