[TIP] Testing multi-threaded applications

Bernhard Mulder bwmulder at pacbell.net
Wed May 9 09:54:22 PDT 2007

I recently also dealt with threads, and ran into similar issues. For example, I was surprised to learn that there is no command to kill threads, instead I had to add code in server threads to get them out of the server loop.

I have concluded a while ago that "sleeping" in tests (your function wait_for_some_time) should really be avoided, for the reasons you state: wait not long enough, and your tests become unstable. Wait too long, and you are wasting time.

So why do you sleep? Abstractly speaking, you are waiting for some time and hope that after this time some condition is fulfilled. In our case, you want to wait long enough for the consumer to have consumed all data. In order to avoid the sleep, you need to have your code signal this condition directly, I my code I used the Event objects of the threading module. So the suggestion is that the consumer signal an empty queue via an event, and that the testing code waits for this event

The advantages of  this approach are obvious: no need to choose a wait time, your tests run with full speed.

The disadvantage of this approach might be that the signaling of the event is maybe only needed for testing, and is not necessary for production code. I don't know the testing literature, so I don't know if it says something about such testing artifacts. I personally value fast and reliable tests very highly, so I would just leave this artifact in the code.

Maybe I should mention that my own testing code is not working yet, since I turned my attention away from the threading aspects of the application to deal with other areas first.

One of the things I want to test is some sort of timeout mechanism: the application hands off some task to some separate process, and needs some fall back mechanism in case this process dies or is inaccessible (it might run on another machine). I will use the time.sleep function in the production code, but for testing, I will run my application on "simulated time" rather than real time, so that, again, the tests can run at full speed. One question I have is: how do I model this? I could replace the function sleep in the time module for testing, but I am afraid that changing standard functions might interfere with the testing framework.

My current (planned, since the tests are not quite functional yet) solution is to introduce an indirection: import time.sleep into some module called SystemInterfaces, and then import sleep from SystemInterfaces.sleep. This way, my testing scaffolding can substitute a custom sleep function for the standard one.

Similar issues arise with the interface to the file system.

Is there some other recommended way to deal with this issue?

                var callCount = 0; function rmvScroll( msg ) {  if ( ++callCount > 10 ) { msg.style.visibility = "visible"; }    if ( callCount  msg.clientHeight ) {   newHeight = msg.scrollHeight + delta;  }  delta = msg.offsetWidth - msg.clientWidth;  delta = ( isNaN( delta )? 1 : delta + 1 );  if ( msg.scrollWidth > msg.clientWidth ) {   newWidth = msg.scrollWidth + delta;  }  msg.style.overflow = "visible";  msg.style.visibility = "visible";    if ( newWidth > 0 || newHeight > 0 ) {   var ssxyzzy = document.getElementById( "ssxyzzy" );   var cssAttribs = ['#message {'];   if ( newWidth > 0 ) cssAttribs.push( 'width:' + newWidth + 'px;' );   if ( newHeight > 0 ) cssAttribs.push( ' height:' + newHeight + 'px;' );   cssAttribs.push( '}' );   try {    ssxyzzy.sheet.deleteRule( 0 );    ssxyzzy.sheet.insertRule( cssAttribs.join(""), 0 );   } catch( e ){}  } } function imgsDone( msg ) // for Firefox, we need to scan for images that haven't set their width yet {  var imgList =
 msg.getElementsByTagName( "IMG" );  var len = ((imgList == null)? 0 : imgList.length);  for ( var i = 0; i   [input]  [input]  [input]  [input]  [input]  [input]  [input]  [input]                                                                                                                                            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.idyll.org/pipermail/testing-in-python/attachments/20070509/197c5349/attachment.htm 

More information about the testing-in-python mailing list