Multi Threaded Unit Tests with Osherove.ThreadTester

The title says "unit tests" but they are really integration tests, since we rely on the cpu and the context switching mechanisms of the OS to do the work for us, but still ,this tries to solve a scenario many people have been asking me about.

The ThreadTester library helps create tests that use multiple threads. It’s main use is to synchronize and “block” the running test until all the threads have finished their job, or a timeout has occurred. It is designed to make the test developer's life easier with a simple API that is readable and quick to use. It's part of the code I'm developing for my upcoming book.

 

Download:

Binaries in zip file

Source code in zip file

Source code from svn repository(one of several test libraries there I created):

http://tools.assembla.com/svn/NTestEx

 

Here is the basic usage of this class:

1) add a reference to Osherove.threadtester into your test project.

2) Write a test that looks like this:

[Test]
        public void TwoThreads()
        {
            Counter c = new Counter();
            ThreadTester tt = new ThreadTester();
            tt.AddThreadAction(
                delegate
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            c.Increment();
                            Thread.Sleep(15);
                        }
                    });

            
            tt.AddThreadAction(
                delegate
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            c.Increment();
                            Thread.Sleep(100);
                        }
                    });

            tt.StartAllThreads(22500);
        }

the test above starts two threads and will block until both of them finish their job. The Counter class is a simple class that we'd like to test that only has a count property and an increment method. We want to make sure it is thread safe.

Here's a test that starts up 100 threads against counter:

        [Test]
        public void HundredThreads()
        {
            Counter c = new Counter();
            ThreadTester tt = new ThreadTester();
            for (int i = 0; i < 100; i++)
            {
                tt.AddThreadAction(delegate
                                       {
                                           for (int j = 0; j < 10; j++)
                                           {
                                               c.Increment();
                                               Thread.Sleep(new Random(j+1).Next(100,300));
                                           }
                                       });
            }
          
            //this test will run for 22.5 seconds
            tt.RunBehavior=ThreadRunBehavior.RunForSpecificTime;
            tt.StartAllThreads(22500);
        }
 

ThreadTester works by getting a delegate from the developer which will be run in a separate thread. You can add as many separate delegates as you’d like. Each one will be run in a separate thread when you call ThreadTester.StartAllThreads().

AddThreadAction:

Takes a delegate with a void return value and no parameters. In the delegate you write code that would do something that a separate thread would do to your object (like call a method.

RunBehavior:

There are two run behaviors:

RunUntilAllThreadsFinish: For each delegate passed in, a thread will be created that will execute that delegate exactly once. When all threads have finished or if a timeout occurs, the ThreadTester will stop blocking it’s “StartAllThreads()” method.

This behavior is good if you'd like to test your object for a known amount of times.

RunForSpecificTime: For each delegate passed in, a thread will be created that will execute that delegate exactly once. When that thread is finished, a new thread will be created which will execute that delegate again. This behavior will continue until the timeout specified in the StartAllThreads() method has been reached. Then ThreadTester will stop blocking.

This behavior is good if you'd like to stress test your object for a known amount of elapsed time. Even if all threads finish, they will re-run until the time has elapsed.

Published Friday, June 22, 2007 12:28 PM by RoyOsherove

Comments

Friday, June 22, 2007 12:45 PM by Tom Opgenorth

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

A thousand thanks for this!  I'm soon to be needing this on my current project.

Saturday, June 23, 2007 6:05 PM by ISerializable - Roy Osherove's Blog

# Roy's Open Source Projects

Open Source Projects I am Involved in (Let me know if you' re interested in contributing to one of these

Sunday, June 24, 2007 2:53 AM by Gil Zilberfeld

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

Roy,

I wish I had this a year ago. I then wrote something a lot more primitive than this for checking timeouts and race conditions.

Well done.

Gil

Sunday, June 24, 2007 4:59 AM by Hermann Klinke

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

I've created something similar some time ago where  your TestFixture derives from a class and then you can just apply attributes (in addition to the TestAttribute) to specify the "RunBehaviour". There is no need to learn a new model. Tested it with NUnit and MbUnit. It uses your interception framework.

Sunday, June 24, 2007 5:07 AM by RoyOsherove

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

Hermann: I'd love to see it.

I thought about going that route, but it seemed too.. non intuitive, but I'd love to get my hands on that.

Roy

Sunday, June 24, 2007 8:51 AM by Hermann Klinke

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

Roy, I'll send it to you if you send me your e-mail-address (my e-mail is in the url). I can't attach files in your contact page.

Sunday, June 24, 2007 11:32 AM by RoyOsherove

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

Hermann: I'm always reachable at :

Roy at osherove.com

Sunday, June 24, 2007 4:39 PM by ISerializable - Roy Osherove's Blog

# Looking for open source contributors to my projects

I've been thinking a lot about doing some active open source development, mainly sharing and getting

Monday, June 25, 2007 8:42 AM by Console.Write(this.Opinion)

# Resumo da semana - 25/06/07

Resumo da semana - 25/06/07

Monday, June 25, 2007 2:34 PM by ISerializable - Roy Osherove's Blog

# ThreadTester with new Ability: StopWhenTrue() and thread polling

I've updated The ThreadTester Library with a new ability: StopWhenTrue(). It allows you to periodically

Monday, June 25, 2007 3:01 PM by Tom Opgenorth

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

I notice the reference to Mono.Cecil in your Tests folder.  Is this necessary?  When I removed the reference (and the UsingCecil tests), everything still seemed to compile okay.

Monday, June 25, 2007 6:24 PM by RoyOsherove

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

Tom: The Cecil is just something I've been playing with. There is no dependency on Cecil at the moment (and I don't see anhy for the near future)

Friday, June 29, 2007 1:15 PM by Sam Gentile

# New and Notable 176

TGIF!! I am super busy right now designing a multi-CPU/multi-threaded Parallel Calculation Engine and

Monday, July 16, 2007 1:07 PM by Greg

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

I've done this a couple of times, but much less general. I've been going to put something reusable together but you've beat me to it and done it well. Thanks Roy!

Thursday, August 02, 2007 11:40 AM by Ben

# re: Multi Threaded Unit Tests with Osherove.ThreadTester

Great little abstraction. Perfect for my needs.

Just a note FYI:

Some of the source classes have a "using NUnit.Framework" statement which isn't being used and as such if not installed on the clients machine throws an exception at runtime.

Also, the "public void StartAllThreads(int runningTimeout)" method has a dependency on NUnit which it doesn't need to... Just throw an exception instead of doing an NUnit.AssertFail().

Once again, great work.

Wednesday, November 07, 2007 7:33 AM by Azra [Florent Santin]

# [Teched 2007] Unit Testing Tips and Techniques with Visual Studio 2008 and the .NET Framework

Roy Osherove - SELA Group www.ISerializable.com (blog) Retour a une activit&#x0;E9; plus s&#x0;E9;rieuse.

Friday, November 09, 2007 12:29 PM by Nelson Correia

# TechEd Developers 2007 @ Barcelona

Friday, November 09, 2007 12:37 PM by Nelson Correia

# TechEd Developers 2007 @ Barcelona

Friday, November 09, 2007 12:42 PM by Nelson Correia

# TechEd Developers 2007 @ Barcelona

Nesta última semana estive em Barcelona, numa conferência da Microsoft, o TechEd Developers . Em primeiro

Friday, November 23, 2007 9:33 AM by DotNetKicks.com

# Multi Threaded Unit Tests with Osherove.ThreadTester

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Tuesday, December 02, 2008 8:43 PM by Sam Gentile's Blog

# New and Notable 176

TGIF!! I am super busy right now designing a multi-CPU/multi-threaded Parallel Calculation Engine and diving into the science of Parallel Computing. I'll have some links when I get a chance. Windows Workflow Tomas talks about Silver , the integration