3

I'm learning threads in Python and thought unit testing would fit my needs.

Using this http://www.tutorialspoint.com/python/python_multithreading.htm as my point of origin. However when i'm using time.sleep() in my function, the test seems to return from that code block.

import unittest
import thread
import time


class Test(unittest.TestCase):

    def test_threads(self):
        thread.start_new_thread(self.print_time,  ("Thread 1", 1))

    def print_time(self, threadName, delay):
        count = 0
        while count < 5:
            time.sleep(delay)
            count += 1
            print "%s: %s" % (threadName, time.ctime(time.time()))

if __name__ == "__main__":
    unittest.main()

Using this code outputs nothing. Getting rid of time.sleep(delay) outputs:

Thread 1: Mon Aug 03 11:36:56 2015
Thread 1: Mon Aug 03 11:36:56 2015
Thread 1: Mon Aug 03 11:36:56 2015
Thread 1: Mon Aug 03 11:36:56 2015
Thread 1: Mon Aug 03 11:36:56 2015

How can I use time.sleep() when i'm using unit test in Python?

Bridgekeeper
  • 354
  • 2
  • 12
  • not sure where the problem is, running this on my machine (as is but with the references to self removed) it returns from the `test_threads` function as expected, then prints the output of the thread itself, could you provide more information as to how you are calling this? – James Kent Aug 03 '15 at 10:24
  • Full code from unit test added. The problem is @JamesKent that when i run the code with time.sleep(delay), I don't get any output whatsoever. – Bridgekeeper Aug 03 '15 at 10:32

2 Answers2

2

The behaviour you see is because your script has ended before the thread has had a chance to print its output. According to the docs, under 'Caveats':

When the main thread exits, it is system defined whether the other threads survive

So it might well be your thread is killed during its first sleep(). Even if the thread would survive I doubt if you would see ouput, in the same doc:

When the main thread exits [..] the standard I/O files are not flushed

Without your time.sleep(delay) apparently the print's are ready before the script has finished.

A naive way to fix this is to have your test method sleep() for the amount of time it takes for the subthread to finish, so to replace your test method by

def test_threads(self):
    Thread(target = self.print_time, args = ("Thread 1", 1)).start()
    time.sleep(6)

Normally though you would use the Threading module for this type of work. When you use it to start threads in non-daemon mode (the default) the calling thread only stops after all threads it started have finished.

jaapvee
  • 141
  • 1
  • 5
  • Oh, I did not realize i should use threading instead, [link](http://stackoverflow.com/questions/5568555/thread-vs-threading) – Bridgekeeper Aug 04 '15 at 08:33
1

Hmm. I get the same as you.

You could try using threading.Thread() instead?

Code:

import unittest
from threading import Thread
import time


class Test(unittest.TestCase):

    def test_threads(self):
        Thread(target = self.print_time, args = ("Thread 1", 1)).start()

    def print_time(self, threadName, delay):
        count = 0
        while count < 5:
            time.sleep(delay)
            count += 1
            print "%s: %s" % (threadName, time.ctime(time.time()))

if __name__ == "__main__":
    unittest.main()

Output:

----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Thread 1: Mon Aug 03 13:07:46 2015
Thread 1: Mon Aug 03 13:07:47 2015
Thread 1: Mon Aug 03 13:07:48 2015
Thread 1: Mon Aug 03 13:07:49 2015
Thread 1: Mon Aug 03 13:07:50 2015

Although, note that the test completes before the thread finishes.

SiHa
  • 7,830
  • 13
  • 34
  • 43