3

I'm using PyUnit for the first time. I want to require some tests to run within a specified amount of time. As far as I can see, there is no builtin way to do this.

I found this answer: PyUnit - How to unit test a method that runs into an infinite loop for some input?. However, this solution causes PyUnit to ignore other failed tests. Here is an example:

import multiprocessing
import unittest
from functools import wraps
import time

def timeout(seconds=5, error_message="Timeout"):
    def decorator(func):
        def wrapper(*args, **kwargs):
            process = multiprocessing.Process(None, func, None, args, kwargs)
            process.start()
            process.join(seconds)
            if process.is_alive():
                raise TimeoutError(error_message)

        return wraps(func)(wrapper)
    return decorator

class MyTestCase(unittest.TestCase):

    @timeout(1)
    def test_Sleepy(self):
        time.sleep(5)

    @timeout(1)
    def test_Falsy(self):
        self.assertTrue(False)

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

When I run this test, the exception for test_Falsy isn't caught by the PyUnit framework and the test output ends with FAILED (errors=1) (instead of FAILED (errors=2) as you'd expect).

What is the correct way to add timeouts to individual PyUnit tests?

Jesper
  • 2,781
  • 13
  • 14

1 Answers1

0

Suggested approach: 1. Keep the test in the main thread 2. Implement the timeout using a new thread, not a process. The new thread waits for 1 second (or whatever your timeout is) and then calls thread.interrupt_main

For thread documentation, see https://docs.python.org/2/library/thread.html

ygramoel
  • 669
  • 1
  • 6
  • 18