How can I make Python's UnitTest Framework fail if an exception is raised by any thread?

0 votes

Hi. I've been using the unit test framework to automate integration tests of the following:-

  • multi-threaded python code
  • external hardware 
  • embedded C
I need the tests to fail if even one exception is raised by ay of the threads. Is this possible? 

A simple but non-workable solution would be to either 

  • refactor the code to avoid multi-threading 
  • test each thread separately

I can't perform either of these because the code interacts asynchronously with the hardware. I've also given a thought to passing messages to forward the exception the main unittest thread but that would require significant testing related changes to the code, and I want to avoid that at this moment.

For example, can I modify the test script below to fail on the exception raised in my_thread without modifying the x.ExceptionRaiser class?

import unittest
import x

class Test(unittest.TestCase):
    def test_x(self):
        my_thread = x.ExceptionRaiser()
        # Test case should fail when thread is started and raises
        # an exception.
        my_thread.start()
        my_thread.join()

if __name__ == '__main__':
    unittest.main()
Dec 5, 2018 in Python by charlie_brown
• 7,720 points
994 views

2 answers to this question.

0 votes

I've come across this problem myself, and the only solution I've been able to come up with is subclassing Thread to include an attribute for whether or not it terminates without an uncaught exception:

from threading import Thread

class ErrThread(Thread):
    """                                                                                                                                                                                               
    A subclass of Thread that will log store exceptions if the thread does                                                                                                                            
    not exit normally                                                                                                                                                                                 
    """
    def run(self):
        try:
            Thread.run(self)
        except Exception as self.err:
            pass
        else:
            self.err = None


class TaskQueue(object):
    """                                                                                                                                                                                               
    A utility class to run ErrThread objects in parallel and raises and exception                                                                                                                     
    in the event that *any* of them fail.                                                                                                                                                             
    """

    def __init__(self, *tasks):

        self.threads = []

        for t in tasks:
            try:
                self.threads.append(ErrThread(**t)) ## passing in a dict of target and args
            except TypeError:
                self.threads.append(ErrThread(target=t))

    def run(self):

        for t in self.threads:
            t.start()
for t in self.threads:
            t.join()
            if t.err:
                raise Exception('Thread %s failed with error: %s' % (t.name, t.err))
answered Dec 5, 2018 by ariaholic
• 7,340 points
0 votes
http://www.drdobbs.com/testing/testing-for-failures-with-python/240169387

Try reading the above document. I assume what you are looking for is post-failure testing?
answered Mar 9 by anonymous

Related Questions In Python

0 votes
1 answer
0 votes
1 answer

How can I make an EXE file from a Python program?

Auto PY to EXE - A .py ...READ MORE

answered Aug 6 in Python by SDeb
• 13,190 points
35 views
+4 votes
8 answers

How can I use Python's range function?

The range function is mostly used in for-loop.  Ex: for ...READ MORE

answered Aug 21, 2018 in Python by Omkar
• 67,660 points
80 views
+2 votes
3 answers

How can I play an audio file in the background using Python?

down voteacceptedFor windows: you could use  winsound.SND_ASYNC to play them ...READ MORE

answered Apr 3, 2018 in Python by charlie_brown
• 7,720 points
2,275 views
+1 vote
2 answers

how can i count the items in a list?

Syntax :            list. count(value) Code: colors = ['red', 'green', ...READ MORE

answered Jul 6 in Python by Neha
• 330 points

edited Jul 8 by Kalgi 350 views
0 votes
1 answer

How can I print an Error in Python?

For Python 2.6 and later and Python ...READ MORE

answered Oct 12, 2018 in Python by ariaholic
• 7,340 points
55 views
0 votes
1 answer

How can I turn an input date into a readable string in Python?

The datetime class has a method strftime. strftime() ...READ MORE

answered Dec 11, 2018 in Python by ariaholic
• 7,340 points
42 views