[Tutor] Unit testing infinite loops

James Chapman james at uplinkzero.com
Fri Jan 31 12:31:49 CET 2014


Hello tutors

I've constructed an example which shows a problem I'm having testing a real
world program and would like to run it past you.

tutor_question.py
--------------------------------------
# -*- coding: utf-8 -*-
import sys
import threading
import time


class Time_Printer(threading.Thread):

    def run(self):
        for i in range(60):
            print('%s - %s' % (self, time.ctime(time.time())))
            time.sleep(1)


class Infinite_Loop_Tutor_Question(object):

    def start_A(self):
        thread = Time_Printer()
        thread.daemon = True
        thread.start()
        print('Started %s' % (thread))

    def start_B(self):
        thread = Time_Printer()
        thread.daemon = True
        thread.start()
        print('Started %s' % (thread))

    def run_forever(self):
        self.start_A()
        time.sleep(0.5)
        self.start_B()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            print("Caught Keyboard Interrupt...")
            sys.exit(0)


if __name__ == '__main__':
    infinite_loop = Infinite_Loop_Tutor_Question()
    infinite_loop.run_forever()

--------------------------------------

In my example above, testing the everything but the run_forever method is
trivial.

So on to my question... The run_forever method essentially just fires up a
bunch of threads to serve various purposes and then waits for CTRL-C to
terminate the entire program. Testing this at the moment is very difficult
because the unit test ends up in the infinite loop. So, would a better idea
be to create an attribute, set it to True and then do

try:
    while self.attribute:
        time.sleep(1)
except KeyboardInterrupt:
    ...


My unit test could then set the attribute. However I'd still have the
problem of how I get from the unit test line that fires up the method to
the next line to change the attribute.

So how should the run_forever method be written so that it's testable, or
if it's testable as is, how would I test it?

And please, no comments about syntax, clean exits of threads, thread
communication, resources, or even the need for testing the run_forever
method. In my test I want to test that it makes the relevant calls and then
enters the infinite loop at which point I want to terminate it.

Thanks in advance, and hopefully there are no formatting issues this time.


--
James
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/5a454c37/attachment.html>


More information about the Tutor mailing list